summaryrefslogtreecommitdiff
path: root/svtools/source
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source')
-rw-r--r--svtools/source/brwbox/brwbox1.cxx2761
-rw-r--r--svtools/source/brwbox/brwbox2.cxx2184
-rw-r--r--svtools/source/brwbox/brwbox3.cxx568
-rw-r--r--svtools/source/brwbox/brwhead.cxx119
-rw-r--r--svtools/source/brwbox/brwimpl.hxx87
-rw-r--r--svtools/source/brwbox/datwin.cxx782
-rw-r--r--svtools/source/brwbox/datwin.hxx254
-rw-r--r--svtools/source/brwbox/ebbcontrols.cxx628
-rw-r--r--svtools/source/brwbox/editbrowsebox.cxx1437
-rw-r--r--svtools/source/brwbox/editbrowsebox.hrc42
-rw-r--r--svtools/source/brwbox/editbrowsebox.src66
-rw-r--r--svtools/source/brwbox/editbrowsebox2.cxx222
-rw-r--r--svtools/source/brwbox/editbrowseboximpl.hxx45
-rw-r--r--svtools/source/brwbox/makefile.mk59
-rw-r--r--svtools/source/config/accessibilityoptions.cxx649
-rw-r--r--svtools/source/config/apearcfg.cxx321
-rw-r--r--svtools/source/config/colorcfg.cxx686
-rw-r--r--svtools/source/config/extcolorcfg.cxx827
-rw-r--r--svtools/source/config/fontsubstconfig.cxx229
-rw-r--r--svtools/source/config/helpopt.cxx764
-rw-r--r--svtools/source/config/htmlcfg.cxx523
-rw-r--r--svtools/source/config/itemholder2.cxx209
-rw-r--r--svtools/source/config/itemholder2.hxx89
-rw-r--r--svtools/source/config/makefile.mk58
-rw-r--r--svtools/source/config/menuoptions.cxx561
-rw-r--r--svtools/source/config/miscopt.cxx831
-rw-r--r--svtools/source/config/optionsdrawinglayer.cxx1713
-rw-r--r--svtools/source/config/printoptions.cxx870
-rw-r--r--svtools/source/config/test/makefile.mk62
-rw-r--r--svtools/source/config/test/test.cxx270
-rw-r--r--svtools/source/contnr/cont_pch.cxx41
-rw-r--r--svtools/source/contnr/contentenumeration.cxx464
-rw-r--r--svtools/source/contnr/contentenumeration.hxx287
-rw-r--r--svtools/source/contnr/ctrdll.cxx79
-rw-r--r--svtools/source/contnr/fileview.cxx2809
-rw-r--r--svtools/source/contnr/fileview.hrc40
-rw-r--r--svtools/source/contnr/fileview.src196
-rw-r--r--svtools/source/contnr/imivctl.hxx637
-rw-r--r--svtools/source/contnr/imivctl1.cxx4681
-rw-r--r--svtools/source/contnr/imivctl2.cxx848
-rw-r--r--svtools/source/contnr/ivctrl.cxx642
-rw-r--r--svtools/source/contnr/makefile.mk82
-rw-r--r--svtools/source/contnr/svcontnr.src103
-rw-r--r--svtools/source/contnr/svicnvw.cxx833
-rw-r--r--svtools/source/contnr/svimpbox.cxx3650
-rw-r--r--svtools/source/contnr/svimpicn.cxx4167
-rw-r--r--svtools/source/contnr/svlbitm.cxx651
-rw-r--r--svtools/source/contnr/svlbox.cxx1923
-rw-r--r--svtools/source/contnr/svtabbx.cxx1304
-rw-r--r--svtools/source/contnr/svtreebx.cxx2670
-rw-r--r--svtools/source/contnr/templwin.cxx2025
-rw-r--r--svtools/source/contnr/templwin.hrc59
-rw-r--r--svtools/source/contnr/templwin.hxx309
-rw-r--r--svtools/source/contnr/templwin.src376
-rw-r--r--svtools/source/contnr/tooltiplbox.cxx120
-rw-r--r--svtools/source/contnr/treelist.cxx2126
-rw-r--r--svtools/source/control/asynclink.cxx139
-rwxr-xr-xsvtools/source/control/calendar.cxx3051
-rwxr-xr-xsvtools/source/control/calendar.src74
-rwxr-xr-xsvtools/source/control/collatorres.cxx128
-rwxr-xr-xsvtools/source/control/ctrlbox.cxx1509
-rwxr-xr-xsvtools/source/control/ctrlbox.src232
-rw-r--r--svtools/source/control/ctrldll.cxx78
-rwxr-xr-xsvtools/source/control/ctrltool.cxx1016
-rwxr-xr-xsvtools/source/control/ctrltool.src144
-rw-r--r--svtools/source/control/filectrl.cxx236
-rw-r--r--svtools/source/control/filectrl.src58
-rw-r--r--svtools/source/control/filectrl2.cxx94
-rw-r--r--svtools/source/control/fileurlbox.cxx124
-rw-r--r--svtools/source/control/fixedhyper.cxx233
-rw-r--r--svtools/source/control/fmtfield.cxx1398
-rw-r--r--svtools/source/control/headbar.cxx1653
-rw-r--r--svtools/source/control/hyperlabel.cxx270
-rwxr-xr-xsvtools/source/control/indexentryres.cxx133
-rw-r--r--svtools/source/control/inettbc.cxx1375
-rwxr-xr-xsvtools/source/control/makefile.mk87
-rw-r--r--svtools/source/control/prgsbar.cxx262
-rw-r--r--svtools/source/control/roadmap.cxx1025
-rw-r--r--svtools/source/control/ruler.cxx3181
-rw-r--r--svtools/source/control/scriptedtext.cxx395
-rw-r--r--svtools/source/control/scrwin.cxx572
-rw-r--r--svtools/source/control/stdctrl.cxx96
-rw-r--r--svtools/source/control/stdmenu.cxx515
-rw-r--r--svtools/source/control/svxbox.cxx617
-rwxr-xr-xsvtools/source/control/tabbar.cxx2735
-rw-r--r--svtools/source/control/taskbar.cxx594
-rw-r--r--svtools/source/control/taskbox.cxx352
-rw-r--r--svtools/source/control/taskmisc.cxx380
-rw-r--r--svtools/source/control/taskstat.cxx656
-rw-r--r--svtools/source/control/toolbarmenu.cxx1805
-rw-r--r--svtools/source/control/toolbarmenuacc.cxx1003
-rw-r--r--svtools/source/control/toolbarmenuimp.hxx314
-rw-r--r--svtools/source/control/urlcontrol.cxx95
-rw-r--r--svtools/source/control/valueacc.cxx1258
-rwxr-xr-xsvtools/source/control/valueimp.hxx330
-rw-r--r--svtools/source/control/valueset.cxx2758
-rw-r--r--svtools/source/dialogs/addresstemplate.cxx1340
-rw-r--r--svtools/source/dialogs/addresstemplate.hrc88
-rw-r--r--svtools/source/dialogs/addresstemplate.src358
-rw-r--r--svtools/source/dialogs/colctrl.cxx690
-rw-r--r--svtools/source/dialogs/colrdlg.cxx328
-rw-r--r--svtools/source/dialogs/colrdlg.hrc67
-rw-r--r--svtools/source/dialogs/colrdlg.src308
-rw-r--r--svtools/source/dialogs/filedlg.cxx148
-rw-r--r--svtools/source/dialogs/filedlg2.cxx1362
-rw-r--r--svtools/source/dialogs/filedlg2.hxx219
-rw-r--r--svtools/source/dialogs/filedlg2.src126
-rw-r--r--svtools/source/dialogs/formats.src294
-rw-r--r--svtools/source/dialogs/insdlg.cxx389
-rwxr-xr-xsvtools/source/dialogs/makefile.mk75
-rw-r--r--svtools/source/dialogs/mcvmath.cxx305
-rw-r--r--svtools/source/dialogs/mcvmath.hxx228
-rw-r--r--svtools/source/dialogs/printdlg.cxx798
-rw-r--r--svtools/source/dialogs/printdlg.hrc74
-rw-r--r--svtools/source/dialogs/printdlg.src333
-rw-r--r--svtools/source/dialogs/prnsetup.cxx403
-rw-r--r--svtools/source/dialogs/prnsetup.hrc48
-rw-r--r--svtools/source/dialogs/prnsetup.src278
-rw-r--r--svtools/source/dialogs/propctrl.cxx503
-rw-r--r--svtools/source/dialogs/propctrl.hxx115
-rw-r--r--svtools/source/dialogs/property.cxx1560
-rw-r--r--svtools/source/dialogs/roadmapwizard.cxx748
-rw-r--r--svtools/source/dialogs/so3res.src315
-rw-r--r--svtools/source/dialogs/wizardmachine.cxx750
-rw-r--r--svtools/source/dialogs/wizardmachine.src50
-rw-r--r--svtools/source/dialogs/wizdlg.cxx707
-rw-r--r--svtools/source/edit/editsyntaxhighlighter.cxx204
-rw-r--r--svtools/source/edit/makefile.mk63
-rw-r--r--svtools/source/edit/svmedit.cxx1656
-rw-r--r--svtools/source/edit/svmedit2.cxx81
-rw-r--r--svtools/source/edit/sychconv.cxx103
-rw-r--r--svtools/source/edit/syntaxhighlight.cxx909
-rw-r--r--svtools/source/edit/textdat2.hxx306
-rw-r--r--svtools/source/edit/textdata.cxx361
-rw-r--r--svtools/source/edit/textdoc.cxx1047
-rw-r--r--svtools/source/edit/textdoc.hxx148
-rw-r--r--svtools/source/edit/texteng.cxx3303
-rw-r--r--svtools/source/edit/textund2.hxx148
-rw-r--r--svtools/source/edit/textundo.cxx343
-rw-r--r--svtools/source/edit/textundo.hxx84
-rw-r--r--svtools/source/edit/textview.cxx2470
-rw-r--r--svtools/source/edit/textwindowpeer.cxx59
-rw-r--r--svtools/source/edit/txtattr.cxx197
-rw-r--r--svtools/source/edit/xtextedt.cxx421
-rw-r--r--svtools/source/filter.vcl/filter/FilterConfigCache.cxx596
-rw-r--r--svtools/source/filter.vcl/filter/FilterConfigCache.hxx145
-rw-r--r--svtools/source/filter.vcl/filter/FilterConfigItem.cxx623
-rw-r--r--svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx327
-rw-r--r--svtools/source/filter.vcl/filter/SvFilterOptionsDialog.hxx101
-rw-r--r--svtools/source/filter.vcl/filter/dlgejpg.cxx96
-rw-r--r--svtools/source/filter.vcl/filter/dlgejpg.hrc39
-rw-r--r--svtools/source/filter.vcl/filter/dlgejpg.hxx72
-rw-r--r--svtools/source/filter.vcl/filter/dlgejpg.src136
-rw-r--r--svtools/source/filter.vcl/filter/dlgepng.cxx90
-rw-r--r--svtools/source/filter.vcl/filter/dlgepng.hrc35
-rw-r--r--svtools/source/filter.vcl/filter/dlgepng.hxx71
-rw-r--r--svtools/source/filter.vcl/filter/dlgepng.src119
-rw-r--r--svtools/source/filter.vcl/filter/dlgexpor.cxx442
-rw-r--r--svtools/source/filter.vcl/filter/dlgexpor.hrc58
-rw-r--r--svtools/source/filter.vcl/filter/dlgexpor.hxx127
-rw-r--r--svtools/source/filter.vcl/filter/dlgexpor.src315
-rw-r--r--svtools/source/filter.vcl/filter/filter.cxx2171
-rw-r--r--svtools/source/filter.vcl/filter/filter2.cxx1419
-rw-r--r--svtools/source/filter.vcl/filter/fldll.cxx76
-rw-r--r--svtools/source/filter.vcl/filter/gradwrap.cxx570
-rw-r--r--svtools/source/filter.vcl/filter/makefile.mk88
-rw-r--r--svtools/source/filter.vcl/filter/sgf.ini118
-rw-r--r--svtools/source/filter.vcl/filter/sgfbram.cxx666
-rw-r--r--svtools/source/filter.vcl/filter/sgvmain.cxx1143
-rw-r--r--svtools/source/filter.vcl/filter/sgvspln.cxx895
-rw-r--r--svtools/source/filter.vcl/filter/sgvtext.cxx1338
-rw-r--r--svtools/source/filter.vcl/filter/strings.hrc27
-rw-r--r--svtools/source/filter.vcl/filter/strings.src85
-rw-r--r--svtools/source/filter.vcl/igif/decode.cxx215
-rw-r--r--svtools/source/filter.vcl/igif/decode.hxx68
-rw-r--r--svtools/source/filter.vcl/igif/gifread.cxx858
-rw-r--r--svtools/source/filter.vcl/igif/makefile.mk45
-rw-r--r--svtools/source/filter.vcl/ixbm/makefile.mk44
-rw-r--r--svtools/source/filter.vcl/ixbm/xbmread.cxx398
-rw-r--r--svtools/source/filter.vcl/ixpm/makefile.mk43
-rw-r--r--svtools/source/filter.vcl/ixpm/rgbtable.hxx695
-rw-r--r--svtools/source/filter.vcl/ixpm/xpmread.cxx702
-rw-r--r--svtools/source/filter.vcl/jpeg/jpeg.cxx779
-rw-r--r--svtools/source/filter.vcl/jpeg/jpeg.h75
-rw-r--r--svtools/source/filter.vcl/jpeg/jpegc.c284
-rw-r--r--svtools/source/filter.vcl/jpeg/makefile.mk45
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.cxx1415
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.hxx100
-rw-r--r--svtools/source/filter.vcl/wmf/enhwmf.cxx1343
-rw-r--r--svtools/source/filter.vcl/wmf/makefile.mk50
-rw-r--r--svtools/source/filter.vcl/wmf/winmtf.cxx2203
-rw-r--r--svtools/source/filter.vcl/wmf/winmtf.hxx777
-rw-r--r--svtools/source/filter.vcl/wmf/winwmf.cxx1426
-rw-r--r--svtools/source/filter.vcl/wmf/wmf.cxx114
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.cxx2096
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.hxx229
-rw-r--r--svtools/source/graphic/descriptor.cxx498
-rw-r--r--svtools/source/graphic/descriptor.hxx140
-rw-r--r--svtools/source/graphic/graphic.cxx300
-rw-r--r--svtools/source/graphic/graphic.hxx103
-rw-r--r--svtools/source/graphic/graphicunofactory.cxx103
-rw-r--r--svtools/source/graphic/grfattr.cxx118
-rw-r--r--svtools/source/graphic/grfcache.cxx1062
-rw-r--r--svtools/source/graphic/grfcache.hxx109
-rw-r--r--svtools/source/graphic/grfmgr.cxx1382
-rw-r--r--svtools/source/graphic/grfmgr2.cxx2382
-rw-r--r--svtools/source/graphic/makefile.mk66
-rw-r--r--svtools/source/graphic/provider.cxx861
-rw-r--r--svtools/source/graphic/renderer.cxx345
-rw-r--r--svtools/source/graphic/transformer.cxx156
-rw-r--r--svtools/source/graphic/transformer.hxx63
-rw-r--r--svtools/source/hatchwindow/documentcloser.cxx295
-rw-r--r--svtools/source/hatchwindow/documentcloser.hxx89
-rw-r--r--svtools/source/hatchwindow/hatchwindow.cxx235
-rw-r--r--svtools/source/hatchwindow/hatchwindow.hxx79
-rw-r--r--svtools/source/hatchwindow/hatchwindowfactory.cxx187
-rw-r--r--svtools/source/hatchwindow/hatchwindowfactory.hxx74
-rw-r--r--svtools/source/hatchwindow/ipwin.cxx644
-rw-r--r--svtools/source/hatchwindow/ipwin.hxx110
-rw-r--r--svtools/source/hatchwindow/makefile.mk65
-rw-r--r--svtools/source/inc/accessibletableimp.hxx62
-rw-r--r--svtools/source/inc/configitems/accessibilityoptions_const.hxx50
-rw-r--r--svtools/source/inc/filectrl.hrc34
-rw-r--r--svtools/source/inc/gifread.hxx144
-rw-r--r--svtools/source/inc/gradwrap.hxx77
-rw-r--r--svtools/source/inc/iodlg.hrc107
-rw-r--r--svtools/source/inc/jpeg.hxx131
-rw-r--r--svtools/source/inc/msgrd.hxx37
-rw-r--r--svtools/source/inc/msgwr.hxx38
-rw-r--r--svtools/source/inc/property.hxx585
-rw-r--r--svtools/source/inc/provider.hxx82
-rw-r--r--svtools/source/inc/renderer.hxx100
-rw-r--r--svtools/source/inc/sgfbram.hxx157
-rw-r--r--svtools/source/inc/sgffilt.hxx46
-rw-r--r--svtools/source/inc/sgvmain.hxx353
-rw-r--r--svtools/source/inc/sgvspln.hxx73
-rw-r--r--svtools/source/inc/svimpbox.hxx474
-rw-r--r--svtools/source/inc/svimpicn.hxx321
-rw-r--r--svtools/source/inc/svtaccessiblefactory.hxx73
-rw-r--r--svtools/source/inc/unoiface.hxx441
-rw-r--r--svtools/source/inc/xbmread.hxx97
-rw-r--r--svtools/source/inc/xpmread.hxx131
-rw-r--r--svtools/source/java/javacontext.cxx106
-rw-r--r--svtools/source/java/javaerror.src93
-rw-r--r--svtools/source/java/javainteractionhandler.cxx340
-rw-r--r--svtools/source/java/makefile.mk54
-rw-r--r--svtools/source/java/patchjavaerror.src93
-rw-r--r--svtools/source/misc/acceleratorexecute.cxx578
-rw-r--r--svtools/source/misc/chartprettypainter.cxx140
-rw-r--r--svtools/source/misc/cliplistener.cxx98
-rw-r--r--svtools/source/misc/dialogclosedlistener.cxx75
-rw-r--r--svtools/source/misc/dialogcontrolling.cxx314
-rw-r--r--svtools/source/misc/ehdl.cxx489
-rw-r--r--svtools/source/misc/ehdl.src40
-rw-r--r--svtools/source/misc/embedhlp.cxx955
-rw-r--r--svtools/source/misc/embedtransfer.cxx256
-rw-r--r--svtools/source/misc/errtxt.src514
-rw-r--r--svtools/source/misc/helpagent.src41
-rw-r--r--svtools/source/misc/helpagentwindow.cxx192
-rw-r--r--svtools/source/misc/imagemgr.cxx881
-rw-r--r--svtools/source/misc/imagemgr.src452
-rw-r--r--svtools/source/misc/imageresourceaccess.cxx211
-rw-r--r--svtools/source/misc/imap.cxx1232
-rw-r--r--svtools/source/misc/imap2.cxx757
-rw-r--r--svtools/source/misc/imap3.cxx97
-rw-r--r--svtools/source/misc/itemdel.cxx135
-rw-r--r--svtools/source/misc/langtab.cxx208
-rw-r--r--svtools/source/misc/langtab.src329
-rwxr-xr-xsvtools/source/misc/makefile.mk84
-rw-r--r--svtools/source/misc/stringtransfer.cxx112
-rwxr-xr-xsvtools/source/misc/svtaccessiblefactory.cxx355
-rw-r--r--svtools/source/misc/svtdata.cxx92
-rw-r--r--svtools/source/misc/templatefoldercache.cxx919
-rw-r--r--svtools/source/misc/transfer.cxx2422
-rw-r--r--svtools/source/misc/transfer2.cxx635
-rw-r--r--svtools/source/misc/unitconv.cxx763
-rw-r--r--svtools/source/misc/wallitem.cxx65
-rwxr-xr-xsvtools/source/misc/xwindowitem.cxx97
-rw-r--r--svtools/source/plugapp/commtest.cxx261
-rw-r--r--svtools/source/plugapp/commtest.hrc34
-rw-r--r--svtools/source/plugapp/commtest.src60
-rw-r--r--svtools/source/plugapp/makefile.mk61
-rw-r--r--svtools/source/plugapp/testtool.hrc55
-rw-r--r--svtools/source/plugapp/testtool.src194
-rw-r--r--svtools/source/plugapp/ttprops.cxx79
-rw-r--r--svtools/source/productregistration/makefile.mk78
-rw-r--r--svtools/source/productregistration/productregistration.cxx507
-rw-r--r--svtools/source/productregistration/productregistration.hxx100
-rw-r--r--svtools/source/productregistration/registrationdlg.cxx171
-rw-r--r--svtools/source/productregistration/registrationdlg.hrc43
-rw-r--r--svtools/source/productregistration/registrationdlg.hxx87
-rw-r--r--svtools/source/productregistration/registrationdlg.src129
-rw-r--r--svtools/source/svhtml/htmlkywd.cxx1081
-rw-r--r--svtools/source/svhtml/htmlout.cxx980
-rw-r--r--svtools/source/svhtml/htmlsupp.cxx173
-rw-r--r--svtools/source/svhtml/makefile.mk51
-rw-r--r--svtools/source/svhtml/parhtml.cxx2371
-rw-r--r--svtools/source/svrtf/makefile.mk49
-rw-r--r--svtools/source/svrtf/parrtf.cxx710
-rw-r--r--svtools/source/svrtf/rtfkey2.cxx1159
-rw-r--r--svtools/source/svrtf/rtfkeywd.cxx1248
-rw-r--r--svtools/source/svrtf/rtfout.cxx209
-rw-r--r--svtools/source/svrtf/svparser.cxx726
-rw-r--r--svtools/source/table/defaultinputhandler.cxx234
-rw-r--r--svtools/source/table/gridtablerenderer.cxx382
-rw-r--r--svtools/source/table/makefile.mk55
-rw-r--r--svtools/source/table/tablecontrol.cxx628
-rw-r--r--svtools/source/table/tablecontrol_impl.cxx2363
-rw-r--r--svtools/source/table/tablecontrol_impl.hxx358
-rw-r--r--svtools/source/table/tabledatawindow.cxx172
-rw-r--r--svtools/source/table/tablegeometry.cxx131
-rw-r--r--svtools/source/table/tablegeometry.hxx162
-rw-r--r--svtools/source/toolpanel/drawerlayouter.cxx305
-rw-r--r--svtools/source/toolpanel/dummypanel.cxx107
-rw-r--r--svtools/source/toolpanel/dummypanel.hxx70
-rwxr-xr-xsvtools/source/toolpanel/makefile.mk68
-rwxr-xr-xsvtools/source/toolpanel/paneldecklisteners.cxx137
-rwxr-xr-xsvtools/source/toolpanel/paneldecklisteners.hxx72
-rwxr-xr-xsvtools/source/toolpanel/paneltabbar.cxx1354
-rw-r--r--svtools/source/toolpanel/paneltabbarpeer.cxx101
-rw-r--r--svtools/source/toolpanel/paneltabbarpeer.hxx69
-rw-r--r--svtools/source/toolpanel/refbase.cxx56
-rw-r--r--svtools/source/toolpanel/tabbargeometry.cxx328
-rw-r--r--svtools/source/toolpanel/tabbargeometry.hxx137
-rw-r--r--svtools/source/toolpanel/tabitemdescriptor.hxx90
-rwxr-xr-xsvtools/source/toolpanel/tablayouter.cxx262
-rw-r--r--svtools/source/toolpanel/toolpanel.cxx54
-rw-r--r--svtools/source/toolpanel/toolpanel.src57
-rw-r--r--svtools/source/toolpanel/toolpanelcollection.cxx193
-rw-r--r--svtools/source/toolpanel/toolpanelcollection.hxx69
-rwxr-xr-xsvtools/source/toolpanel/toolpaneldeck.cxx560
-rwxr-xr-xsvtools/source/toolpanel/toolpaneldeckpeer.cxx99
-rwxr-xr-xsvtools/source/toolpanel/toolpaneldeckpeer.hxx69
-rw-r--r--svtools/source/toolpanel/toolpaneldrawer.cxx373
-rw-r--r--svtools/source/toolpanel/toolpaneldrawer.hxx113
-rw-r--r--svtools/source/toolpanel/toolpaneldrawerpeer.cxx142
-rw-r--r--svtools/source/toolpanel/toolpaneldrawerpeer.hxx56
-rw-r--r--svtools/source/uno/addrtempuno.cxx245
-rw-r--r--svtools/source/uno/contextmenuhelper.cxx687
-rw-r--r--svtools/source/uno/framestatuslistener.cxx444
-rw-r--r--svtools/source/uno/generictoolboxcontroller.cxx208
-rw-r--r--svtools/source/uno/genericunodialog.cxx373
-rw-r--r--svtools/source/uno/makefile.mk61
-rw-r--r--svtools/source/uno/miscservices.cxx219
-rw-r--r--svtools/source/uno/popupmenucontrollerbase.cxx420
-rw-r--r--svtools/source/uno/popupwindowcontroller.cxx258
-rw-r--r--svtools/source/uno/statusbarcontroller.cxx784
-rwxr-xr-xsvtools/source/uno/svtxgridcontrol.cxx899
-rwxr-xr-xsvtools/source/uno/svtxgridcontrol.hxx117
-rw-r--r--svtools/source/uno/toolboxcontroller.cxx886
-rw-r--r--svtools/source/uno/treecontrolpeer.cxx1747
-rw-r--r--svtools/source/uno/treecontrolpeer.hxx174
-rw-r--r--svtools/source/uno/unocontroltablemodel.cxx513
-rw-r--r--svtools/source/uno/unocontroltablemodel.hxx177
-rw-r--r--svtools/source/uno/unoevent.cxx610
-rw-r--r--svtools/source/uno/unoiface.cxx2367
-rw-r--r--svtools/source/uno/unoimap.cxx824
-rw-r--r--svtools/source/uno/unowizard.hxx117
-rw-r--r--svtools/source/uno/wizard/makefile.mk48
-rw-r--r--svtools/source/uno/wizard/unowizard.cxx452
-rw-r--r--svtools/source/uno/wizard/wizardpagecontroller.cxx190
-rw-r--r--svtools/source/uno/wizard/wizardpagecontroller.hxx75
-rw-r--r--svtools/source/uno/wizard/wizardshell.cxx279
-rw-r--r--svtools/source/uno/wizard/wizardshell.hxx147
-rw-r--r--svtools/source/urlobj/inetimg.cxx149
-rw-r--r--svtools/source/urlobj/makefile.mk46
366 files changed, 191776 insertions, 0 deletions
diff --git a/svtools/source/brwbox/brwbox1.cxx b/svtools/source/brwbox/brwbox1.cxx
new file mode 100644
index 000000000000..3a29c4ae63fa
--- /dev/null
+++ b/svtools/source/brwbox/brwbox1.cxx
@@ -0,0 +1,2761 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/brwbox.hxx>
+#include <svtools/brwhead.hxx>
+#include "datwin.hxx"
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+
+#include <functional>
+#include <algorithm>
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <tools/multisel.hxx>
+#include "brwimpl.hxx"
+
+DBG_NAME(BrowseBox)
+
+extern const char* BrowseBoxCheckInvariants( const void* pVoid );
+
+DECLARE_LIST( BrowserColumns, BrowserColumn* )
+
+#define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
+#define getDataWindow() ((BrowserDataWin*)pDataWin)
+
+using namespace com::sun::star::accessibility::AccessibleEventId;
+using namespace com::sun::star::accessibility::AccessibleTableModelChangeType;
+using com::sun::star::accessibility::AccessibleTableModelChange;
+using com::sun::star::lang::XComponent;
+using namespace ::com::sun::star::uno;
+using namespace svt;
+
+//-------------------------------------------------------------------
+
+#ifdef DBG_MI
+void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho )
+{
+ SvFileStream aLog( "d:\\cursor.log", STREAM_WRITE|STREAM_NOCREATE );
+ if ( aLog.IsOpen() )
+ {
+ aLog.Seek( STREAM_SEEK_TO_END );
+ String aEntry( (long) pThis );
+ aEntry += "(row=";
+ aEntry += pThis->GetCurRow();
+ aEntry += "): ";
+ aEntry += pWhat;
+ aEntry += " from ";
+ aEntry += pWho;
+ aEntry += " => ";
+ aEntry += pThis->GetCursorHideCount();
+ aLog.WriteLine( aEntry );
+ }
+}
+#endif
+
+namespace
+{
+ void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap& _rHeaderCell)
+ {
+ ::std::for_each(
+ _rHeaderCell.begin(),
+ _rHeaderCell.end(),
+ ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose()
+ );
+ _rHeaderCell.clear();
+ }
+}
+
+//===================================================================
+
+void BrowseBox::ConstructImpl( BrowserMode nMode )
+{
+ DBG_TRACE1( "BrowseBox: %p->ConstructImpl", this );
+ bMultiSelection = FALSE;
+ pColSel = 0;
+ pDataWin = 0;
+ pVScroll = 0;
+
+ pDataWin = new BrowserDataWin( this );
+ pCols = new BrowserColumns;
+ m_pImpl.reset( new ::svt::BrowseBoxImpl() );
+
+ aGridLineColor = Color( COL_LIGHTGRAY );
+ InitSettings_Impl( this );
+ InitSettings_Impl( pDataWin );
+
+ bBootstrapped = FALSE;
+ nDataRowHeight = 0;
+ nTitleLines = 1;
+ nFirstCol = 0;
+ nTopRow = 0;
+ nCurRow = BROWSER_ENDOFSELECTION;
+ nCurColId = 0;
+ bResizing = FALSE;
+ bSelect = FALSE;
+ bSelecting = FALSE;
+ bScrolling = FALSE;
+ bSelectionIsVisible = FALSE;
+ bNotToggleSel = FALSE;
+ bRowDividerDrag = FALSE;
+ bHit = FALSE;
+ mbInteractiveRowHeight = FALSE;
+ bHideSelect = FALSE;
+ bHideCursor = NO_CURSOR_HIDE;
+ nRowCount = 0;
+ m_bFocusOnlyCursor = TRUE;
+ m_aCursorColor = COL_TRANSPARENT;
+ m_nCurrentMode = 0;
+ nControlAreaWidth = USHRT_MAX;
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+
+ aHScroll.SetLineSize(1);
+ aHScroll.SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
+ aHScroll.SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
+ pDataWin->Show();
+
+ SetMode( nMode );
+ bSelectionIsVisible = bKeepHighlight;
+ bHasFocus = HasChildPathFocus();
+ getDataWindow()->nCursorHidden =
+ ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
+ LOG( this, "ConstructImpl", "*" );
+}
+
+//-------------------------------------------------------------------
+
+BrowseBox::BrowseBox( Window* pParent, WinBits nBits, BrowserMode nMode )
+ :Control( pParent, nBits | WB_3DLOOK )
+ ,DragSourceHelper( this )
+ ,DropTargetHelper( this )
+ ,aHScroll( this, WinBits( WB_HSCROLL ) )
+{
+ DBG_CTOR( BrowseBox, NULL );
+ ConstructImpl( nMode );
+}
+
+//-------------------------------------------------------------------
+
+BrowseBox::BrowseBox( Window* pParent, const ResId& rId, BrowserMode nMode )
+ :Control( pParent, rId )
+ ,DragSourceHelper( this )
+ ,DropTargetHelper( this )
+ ,aHScroll( this, WinBits(WB_HSCROLL) )
+{
+ DBG_CTOR( BrowseBox, NULL );
+ ConstructImpl(nMode);
+}
+//-------------------------------------------------------------------
+
+BrowseBox::~BrowseBox()
+{
+ DBG_DTOR(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_TRACE1( "BrowseBox: %p~", this );
+
+ if ( m_pImpl->m_pAccessible )
+ {
+ disposeAndClearHeaderCell(m_pImpl->m_aColHeaderCellMap);
+ disposeAndClearHeaderCell(m_pImpl->m_aRowHeaderCellMap);
+ m_pImpl->m_pAccessible->dispose();
+ }
+
+ Hide();
+ delete getDataWindow()->pHeaderBar;
+ delete getDataWindow()->pCornerWin;
+ delete pDataWin;
+ delete pVScroll;
+
+ // free columns-space
+ for ( USHORT n = 0; n < pCols->Count(); ++n )
+ delete pCols->GetObject(n);
+ delete pCols;
+ delete pColSel;
+ if ( bMultiSelection )
+ delete uRow.pSel;
+}
+
+//-------------------------------------------------------------------
+
+short BrowseBox::GetCursorHideCount() const
+{
+ return getDataWindow()->nCursorHidden;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::DoShowCursor( const char *
+#ifdef DBG_MI
+pWhoLogs
+#endif
+)
+{
+ short nHiddenCount = --getDataWindow()->nCursorHidden;
+ if (PaintCursorIfHiddenOnce())
+ {
+ if (1 == nHiddenCount)
+ DrawCursor();
+ }
+ else
+ {
+ if (0 == nHiddenCount)
+ DrawCursor();
+ }
+ LOG( this, "DoShowCursor", pWhoLogs );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::DoHideCursor( const char *
+#ifdef DBG_MI
+pWhoLogs
+#endif
+)
+{
+ short nHiddenCount = ++getDataWindow()->nCursorHidden;
+ if (PaintCursorIfHiddenOnce())
+ {
+ if (2 == nHiddenCount)
+ DrawCursor();
+ }
+ else
+ {
+ if (1 == nHiddenCount)
+ DrawCursor();
+ }
+ LOG( this, "DoHideCursor", pWhoLogs );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetRealRowCount( const String &rRealRowCount )
+{
+ getDataWindow()->aRealRowCount = rRealRowCount;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetFont( const Font& rNewFont )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ pDataWin->SetFont( rNewFont );
+ ImpGetDataRowHeight();
+}
+
+//-------------------------------------------------------------------
+
+ULONG BrowseBox::GetDefaultColumnWidth( const String& _rText ) const
+{
+ return GetDataWindow().GetTextWidth( _rText ) + GetDataWindow().GetTextWidth( '0' ) * 4;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertHandleColumn( ULONG nWidth )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( 0, Image(), String(), nWidth, GetZoom(), 0 ), (ULONG) 0 );
+ FreezeColumn( 0 );
+
+ // Headerbar anpassen
+ if ( getDataWindow()->pHeaderBar )
+ {
+ getDataWindow()->pHeaderBar->SetPosSizePixel(
+ Point(nWidth, 0),
+ Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() )
+ );
+ }
+
+ /*if ( getDataWindow()->pHeaderBar )
+ getDataWindow()->pHeaderBar->InsertItem( USHRT_MAX - 1,
+ "", nWidth, HIB_FIXEDPOS|HIB_FIXED, 0 );*/
+ ColumnInserted( 0 );
+}
+
+//-------------------------------------------------------------------
+void BrowseBox::InsertDataColumn( USHORT nItemId, const Image& rImage,
+ long nWidth, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, rImage, String(), nWidth, GetZoom(), nBits ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+ if ( getDataWindow()->pHeaderBar )
+ {
+ // Handlecolumn nicht in der Headerbar
+ USHORT nHeaderPos = nPos;
+ if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
+ nHeaderPos--;
+ getDataWindow()->pHeaderBar->InsertItem(
+ nItemId, rImage, nWidth, nBits, nHeaderPos );
+ }
+ ColumnInserted( nPos );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertDataColumn( USHORT nItemId, const XubString& rText,
+ long nWidth, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom(), nBits ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+
+ if ( getDataWindow()->pHeaderBar )
+ {
+ // Handlecolumn nicht in der Headerbar
+ USHORT nHeaderPos = nPos;
+ if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
+ nHeaderPos--;
+ getDataWindow()->pHeaderBar->InsertItem(
+ nItemId, rText, nWidth, nBits, nHeaderPos );
+ }
+ ColumnInserted( nPos );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertDataColumn( USHORT nItemId,
+ const Image& rImage, const XubString& rText,
+ long nWidth, HeaderBarItemBits nBits, USHORT nPos,
+ const String* pHelpText )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, rImage, rText, nWidth, GetZoom(), nBits ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+ if ( getDataWindow()->pHeaderBar )
+ {
+ // Handlecolumn nicht in der Headerbar
+ USHORT nHeaderPos = nPos;
+ if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
+ nHeaderPos--;
+
+ getDataWindow()->pHeaderBar->InsertItem(
+ nItemId, rImage, rText, nWidth, nBits, nHeaderPos );
+ if( pHelpText && !rText.Len() )
+ {
+ getDataWindow()->pHeaderBar->SetHelpText(
+ nItemId, *pHelpText );
+ }
+ }
+ ColumnInserted( nPos );
+}
+//-------------------------------------------------------------------
+USHORT BrowseBox::ToggleSelectedColumn()
+{
+ USHORT nSelectedColId = USHRT_MAX;
+ if ( pColSel && pColSel->GetSelectCount() )
+ {
+ DoHideCursor( "ToggleSelectedColumn" );
+ ToggleSelection();
+ nSelectedColId = pCols->GetObject(pColSel->FirstSelected())->GetId();
+ pColSel->SelectAll(FALSE);
+ }
+ return nSelectedColId;
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::SetToggledSelectedColumn(USHORT _nSelectedColumnId)
+{
+ if ( pColSel && _nSelectedColumnId != USHRT_MAX )
+ {
+ pColSel->Select( GetColumnPos( _nSelectedColumnId ) );
+ ToggleSelection();
+ DBG_TRACE1( "BrowseBox: %p->SetToggledSelectedColumn", this );
+ DoShowCursor( "SetToggledSelectedColumn" );
+ }
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::FreezeColumn( USHORT nItemId, BOOL bFreeze )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // never unfreeze the handle-column
+ if ( nItemId == 0 && !bFreeze )
+ return;
+
+ // get the position in the current array
+ USHORT nItemPos = GetColumnPos( nItemId );
+ if ( nItemPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // doesn't the state change?
+ if ( pCols->GetObject(nItemPos)->IsFrozen() == bFreeze )
+ return;
+
+ // remark the column selection
+ USHORT nSelectedColId = ToggleSelectedColumn();
+
+ // freeze or unfreeze?
+ if ( bFreeze )
+ {
+ // to be moved?
+ if ( nItemPos != 0 && !pCols->GetObject(nItemPos-1)->IsFrozen() )
+ {
+ // move to the right of the last frozen column
+ USHORT nFirstScrollable = FrozenColCount();
+ BrowserColumn *pColumn = pCols->GetObject(nItemPos);
+ pCols->Remove( (ULONG) nItemPos );
+ nItemPos = nFirstScrollable;
+ pCols->Insert( pColumn, (ULONG) nItemPos );
+ }
+
+ // adjust the number of the first scrollable and visible column
+ if ( nFirstCol <= nItemPos )
+ nFirstCol = nItemPos + 1;
+ }
+ else
+ {
+ // to be moved?
+ if ( nItemPos != FrozenColCount()-1 )
+ {
+ // move to the leftmost scrollable colum
+ USHORT nFirstScrollable = FrozenColCount();
+ BrowserColumn *pColumn = pCols->GetObject(nItemPos);
+ pCols->Remove( (ULONG) nItemPos );
+ nItemPos = nFirstScrollable;
+ pCols->Insert( pColumn, (ULONG) nItemPos );
+ }
+
+ // adjust the number of the first scrollable and visible column
+ nFirstCol = nItemPos;
+ }
+
+ // toggle the freeze-state of the column
+ pCols->GetObject(nItemPos)->Freeze( bFreeze );
+
+ // align the scrollbar-range
+ UpdateScrollbars();
+
+ // repaint
+ Control::Invalidate();
+ getDataWindow()->Invalidate();
+
+ // remember the column selection
+ SetToggledSelectedColumn(nSelectedColId);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnPos( USHORT nColumnId, USHORT nPos )
+{
+ // never set pos of the handle-column
+ if ( nColumnId == 0 )
+ return;
+
+ // do not move handle column
+ if (nPos == 0 && !pCols->GetObject(0)->GetId())
+ return;
+
+ // get the position in the current array
+ USHORT nOldPos = GetColumnPos( nColumnId );
+ if ( nOldPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // does the state change?
+ if (nOldPos != nPos)
+ {
+ // remark the column selection
+ USHORT nSelectedColId = ToggleSelectedColumn();
+
+ // determine old column area
+ Size aDataWinSize( pDataWin->GetSizePixel() );
+ if ( getDataWindow()->pHeaderBar )
+ aDataWinSize.Height() += getDataWindow()->pHeaderBar->GetSizePixel().Height();
+
+ Rectangle aFromRect( GetFieldRect( nColumnId) );
+ aFromRect.Right() += 2*MIN_COLUMNWIDTH;
+
+ USHORT nNextPos = nOldPos + 1;
+ if ( nOldPos > nPos )
+ nNextPos = nOldPos - 1;
+
+ BrowserColumn *pNextCol = pCols->GetObject(nNextPos);
+ Rectangle aNextRect(GetFieldRect( pNextCol->GetId() ));
+
+ // move column internally
+ pCols->Insert( pCols->Remove( nOldPos ), nPos );
+
+ // determine new column area
+ Rectangle aToRect( GetFieldRect( nColumnId ) );
+ aToRect.Right() += 2*MIN_COLUMNWIDTH;
+
+ // do scroll, let redraw
+ if( pDataWin->GetBackground().IsScrollable() )
+ {
+ long nScroll = -aFromRect.GetWidth();
+ Rectangle aScrollArea;
+ if ( nOldPos > nPos )
+ {
+ long nFrozenWidth = GetFrozenWidth();
+ if ( aToRect.Left() < nFrozenWidth )
+ aToRect.Left() = nFrozenWidth;
+ aScrollArea = Rectangle(Point(aToRect.Left(),0),
+ Point(aNextRect.Right(),aDataWinSize.Height()));
+ nScroll *= -1; // reverse direction
+ }
+ else
+ aScrollArea = Rectangle(Point(aNextRect.Left(),0),
+ Point(aToRect.Right(),aDataWinSize.Height()));
+
+ pDataWin->Scroll( nScroll, 0, aScrollArea );
+ aToRect.Top() = 0;
+ aToRect.Bottom() = aScrollArea.Bottom();
+ Invalidate( aToRect );
+ }
+ else
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+
+ // adjust header bar positions
+ if ( getDataWindow()->pHeaderBar )
+ {
+ USHORT nNewPos = nPos;
+ if ( !GetColumnId(0) )
+ --nNewPos;
+ getDataWindow()->pHeaderBar->MoveItem(nColumnId,nNewPos);
+ }
+ // remember the column selection
+ SetToggledSelectedColumn(nSelectedColId);
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(
+ DELETE,
+ 0,
+ GetRowCount(),
+ nOldPos,
+ nOldPos
+ )
+ ),
+ Any()
+ );
+
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(
+ INSERT,
+ 0,
+ GetRowCount(),
+ nPos,
+ nPos
+ )
+ ),
+ Any()
+ );
+ }
+ }
+
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnMode( USHORT nColumnId, BrowserColumnMode nFlags )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // never set mode of the handle-column
+ if ( nColumnId == 0 )
+ return;
+
+ // get the position in the current array
+ USHORT nColumnPos = GetColumnPos( nColumnId );
+ if ( nColumnPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // does the state change?
+ BrowserColumn *pCol = pCols->GetObject(nColumnPos);
+ if ( pCol->Flags() != nFlags )
+ {
+ pCol->Flags() = sal::static_int_cast< HeaderBarItemBits >(nFlags);
+
+ // redraw visible colums
+ if ( GetUpdateMode() && ( pCol->IsFrozen() || nColumnPos > nFirstCol ) )
+ Invalidate( Rectangle( Point(0,0),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnTitle( USHORT nItemId, const String& rTitle )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // never set title of the handle-column
+ if ( nItemId == 0 )
+ return;
+
+ // get the position in the current array
+ USHORT nItemPos = GetColumnPos( nItemId );
+ if ( nItemPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // does the state change?
+ BrowserColumn *pCol = pCols->GetObject(nItemPos);
+ if ( pCol->Title() != rTitle )
+ {
+ ::rtl::OUString sNew(rTitle);
+ ::rtl::OUString sOld(pCol->Title());
+
+ pCol->Title() = rTitle;
+
+ // Headerbar-Column anpassen
+ if ( getDataWindow()->pHeaderBar )
+ getDataWindow()->pHeaderBar->SetItemText(
+ nItemId ? nItemId : USHRT_MAX - 1, rTitle );
+ else
+ {
+ // redraw visible colums
+ if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) )
+ Invalidate( Rectangle( Point(0,0),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
+ }
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED,
+ makeAny( sNew ),
+ makeAny( sOld )
+ );
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnWidth( USHORT nItemId, ULONG nWidth )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // get the position in the current array
+ USHORT nItemPos = GetColumnPos( nItemId );
+ if ( nItemPos >= pCols->Count() )
+ return;
+
+ // does the state change?
+ nWidth = QueryColumnResize( nItemId, nWidth );
+ if ( nWidth >= LONG_MAX || pCols->GetObject(nItemPos)->Width() != nWidth )
+ {
+ long nOldWidth = pCols->GetObject(nItemPos)->Width();
+
+ // ggf. letzte Spalte anpassen
+ if ( IsVisible() && nItemPos == pCols->Count() - 1 )
+ {
+ long nMaxWidth = pDataWin->GetSizePixel().Width();
+ nMaxWidth -= getDataWindow()->bAutoSizeLastCol
+ ? GetFieldRect(nItemId).Left()
+ : GetFrozenWidth();
+ if ( ( (BrowserDataWin*)pDataWin )->bAutoSizeLastCol || nWidth > (ULONG)nMaxWidth )
+ {
+ nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth;
+ nWidth = QueryColumnResize( nItemId, nWidth );
+ }
+ }
+
+ // OV
+ // In AutoSizeLastColumn() wird SetColumnWidth mit nWidth==0xffff
+ // gerufen. Deshalb muss hier nochmal geprueft werden, ob sich die
+ // Breite tatsaechlich geaendert hat.
+ if( (ULONG)nOldWidth == nWidth )
+ return;
+
+ // soll die Aenderung sofort dargestellt werden?
+ BOOL bUpdate = GetUpdateMode() &&
+ ( pCols->GetObject(nItemPos)->IsFrozen() || nItemPos >= nFirstCol );
+
+ if ( bUpdate )
+ {
+ // Selection hiden
+ DoHideCursor( "SetColumnWidth" );
+ ToggleSelection();
+ //!getDataWindow()->Update();
+ //!Control::Update();
+ }
+
+ // Breite setzen
+ pCols->GetObject(nItemPos)->SetWidth(nWidth, GetZoom());
+#if 0
+ if ( nItemPos != pCols->Count() - 1 )
+ {
+ long nLastColMaxWidth = pDataWin->GetSizePixel().Width() -
+ GetFieldRect(GetColumnId(pCols->Count()-1)).Left();
+ pCols->GetObject(pCols->Count()-1)->Width() = nLastColMaxWidth;
+ }
+#endif
+
+ // scroll and invalidate
+ if ( bUpdate )
+ {
+ // X-Pos der veraenderten Spalte ermitteln
+ long nX = 0;
+ for ( USHORT nCol = 0; nCol < nItemPos; ++nCol )
+ {
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+ if ( pCol->IsFrozen() || nCol >= nFirstCol )
+ nX += pCol->Width();
+ }
+
+ // eigentliches scroll+invalidate
+ pDataWin->SetClipRegion();
+ BOOL bSelVis = bSelectionIsVisible;
+ bSelectionIsVisible = FALSE;
+ if( GetBackground().IsScrollable() )
+ {
+
+ Rectangle aScrRect( nX + std::min( (ULONG)nOldWidth, nWidth ), 0,
+ GetSizePixel().Width() , // the header is longer than the datawin
+ pDataWin->GetPosPixel().Y() - 1 );
+ Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
+ aScrRect.Bottom() = pDataWin->GetSizePixel().Height();
+ getDataWindow()->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
+ Rectangle aInvRect( nX, 0, nX + std::max( nWidth, (ULONG)nOldWidth ), USHRT_MAX );
+ Control::Invalidate( aInvRect, INVALIDATE_NOCHILDREN );
+ ( (BrowserDataWin*)pDataWin )->Invalidate( aInvRect );
+ }
+ else
+ {
+ Control::Invalidate( INVALIDATE_NOCHILDREN );
+ getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+
+
+ //!getDataWindow()->Update();
+ //!Control::Update();
+ bSelectionIsVisible = bSelVis;
+ ToggleSelection();
+ DoShowCursor( "SetColumnWidth" );
+ }
+ UpdateScrollbars();
+
+ // Headerbar-Column anpassen
+ if ( getDataWindow()->pHeaderBar )
+ getDataWindow()->pHeaderBar->SetItemSize(
+ nItemId ? nItemId : USHRT_MAX - 1, nWidth );
+
+ // adjust last column
+ if ( nItemPos != pCols->Count() - 1 )
+ AutoSizeLastColumn();
+
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::AutoSizeLastColumn()
+{
+ if ( getDataWindow()->bAutoSizeLastCol &&
+ getDataWindow()->GetUpdateMode() )
+ {
+ USHORT nId = GetColumnId( (USHORT)pCols->Count() - 1 );
+ SetColumnWidth( nId, LONG_MAX );
+ ColumnResized( nId );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RemoveColumn( USHORT nItemId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // Spaltenposition ermitteln
+ USHORT nPos = GetColumnPos(nItemId);
+ if ( nPos >= ColCount() )
+ // nicht vorhanden
+ return;
+
+ // Spaltenselektion korrigieren
+ if ( pColSel )
+ pColSel->Remove( nPos );
+
+ // Spaltencursor korrigieren
+ if ( nCurColId == nItemId )
+ nCurColId = 0;
+
+ // Spalte entfernen
+ delete( pCols->Remove( (ULONG) nPos ));
+ // OJ #93534#
+ if ( nFirstCol >= nPos && nFirstCol > FrozenColCount() )
+ {
+ OSL_ENSURE(nFirstCol > 0,"FirstCol must be greater zero!");
+ --nFirstCol;
+ }
+
+ // Handlecolumn nicht in der Headerbar
+ if (nItemId)
+ {
+ if ( getDataWindow()->pHeaderBar )
+ getDataWindow()->pHeaderBar->RemoveItem( nItemId );
+ }
+ else
+ {
+ // Headerbar anpassen
+ if ( getDataWindow()->pHeaderBar )
+ {
+ getDataWindow()->pHeaderBar->SetPosSizePixel(
+ Point(0, 0),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() )
+ );
+ }
+ }
+
+ // vertikalen Scrollbar korrigieren
+ UpdateScrollbars();
+
+ // ggf. Repaint ausl"osen
+ if ( GetUpdateMode() )
+ {
+ getDataWindow()->Invalidate();
+ Control::Invalidate();
+ if ( getDataWindow()->bAutoSizeLastCol && nPos ==ColCount() )
+ SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX );
+ }
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange( DELETE,
+ 0,
+ GetRowCount(),
+ nPos,
+ nPos
+ )
+ ),
+ Any()
+ );
+
+ commitHeaderBarEvent(
+ CHILD,
+ Any(),
+ makeAny( CreateAccessibleColumnHeader( nPos ) ),
+ sal_True
+ );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RemoveColumns()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ unsigned int nOldCount = pCols->Count();
+ // alle Spalten entfernen
+ while ( pCols->Count() )
+ delete ( pCols->Remove( (ULONG) 0 ));
+
+ // Spaltenselektion korrigieren
+ if ( pColSel )
+ {
+ pColSel->SelectAll(FALSE);
+ pColSel->SetTotalRange( Range( 0, 0 ) );
+ }
+
+ // Spaltencursor korrigieren
+ nCurColId = 0;
+ nFirstCol = 0;
+
+ if ( getDataWindow()->pHeaderBar )
+ getDataWindow()->pHeaderBar->Clear( );
+
+ // vertikalen Scrollbar korrigieren
+ UpdateScrollbars();
+
+ // ggf. Repaint ausl"osen
+ if ( GetUpdateMode() )
+ {
+ getDataWindow()->Invalidate();
+ Control::Invalidate();
+ }
+
+ if ( isAccessibleAlive() )
+ {
+ if ( pCols->Count() != nOldCount )
+ {
+ // all columns should be removed, so we remove the column header bar and append it again
+ // to avoid to notify every column remove
+ commitBrowseBoxEvent(
+ CHILD,
+ Any(),
+ makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR))
+ );
+
+ // and now append it again
+ commitBrowseBoxEvent(
+ CHILD,
+ makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)),
+ Any()
+ );
+
+ // notify a table model change
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny ( AccessibleTableModelChange( DELETE,
+ 0,
+ GetRowCount(),
+ 0,
+ nOldCount
+ )
+ ),
+ Any()
+ );
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
+String BrowseBox::GetColumnTitle( USHORT nId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ USHORT nItemPos = GetColumnPos( nId );
+ if ( nItemPos >= pCols->Count() )
+ return String();
+ return pCols->GetObject(nItemPos)->Title();
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetRowCount() const
+{
+ return nRowCount;
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::ColCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return (USHORT) pCols->Count();
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ImpGetDataRowHeight() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ BrowseBox *pThis = (BrowseBox*)this;
+ pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2);
+ pThis->Resize();
+ getDataWindow()->Invalidate();
+ return nDataRowHeight;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetDataRowHeight( long nPixel )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ nDataRowHeight = CalcReverseZoom(nPixel);
+ Resize();
+ getDataWindow()->Invalidate();
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetTitleLines( USHORT nLines )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ nTitleLines = nLines;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ScrollColumns( long nCols )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nFirstCol + nCols < 0 ||
+ nFirstCol + nCols >= (long)pCols->Count() )
+ //?MI: pCols->GetObject( nFirstCol + nCols )->IsFrozen() )
+ return 0;
+
+ // implicitly hides cursor while scrolling
+ StartScroll();
+ bScrolling = TRUE;
+ BOOL bScrollable = pDataWin->GetBackground().IsScrollable();
+ BOOL bInvalidateView = FALSE;
+
+ // scrolling one column to the right?
+ if ( nCols == 1 )
+ {
+ // update internal value and scrollbar
+ ++nFirstCol;
+ aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
+
+ if ( !bScrollable )
+ {
+ bInvalidateView = TRUE;
+ }
+ else
+ {
+ long nDelta = pCols->GetObject(nFirstCol-1)->Width();
+ long nFrozenWidth = GetFrozenWidth();
+
+ Rectangle aScrollRect( Point( nFrozenWidth + nDelta, 0 ),
+ Size ( GetOutputSizePixel().Width() - nFrozenWidth - nDelta,
+ GetTitleHeight() - 1
+ ) );
+
+ // scroll the header bar area (if there is no dedicated HeaderBar control)
+ if ( !getDataWindow()->pHeaderBar && nTitleLines )
+ {
+ // actually scroll
+ Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
+
+ // invalidate the area of the column which was scrolled out to the left hand side
+ Rectangle aInvalidateRect( aScrollRect );
+ aInvalidateRect.Left() = nFrozenWidth;
+ aInvalidateRect.Right() = nFrozenWidth + nDelta - 1;
+ Invalidate( aInvalidateRect );
+ }
+
+ // scroll the data-area
+ aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
+
+ // actually scroll
+ pDataWin->Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
+
+ // invalidate the area of the column which was scrolled out to the left hand side
+ aScrollRect.Left() = nFrozenWidth;
+ aScrollRect.Right() = nFrozenWidth + nDelta - 1;
+ getDataWindow()->Invalidate( aScrollRect );
+ }
+ }
+
+ // scrolling one column to the left?
+ else if ( nCols == -1 )
+ {
+ --nFirstCol;
+ aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
+
+ if ( !bScrollable )
+ {
+ bInvalidateView = TRUE;
+ }
+ else
+ {
+ long nDelta = pCols->GetObject(nFirstCol)->Width();
+ long nFrozenWidth = GetFrozenWidth();
+
+ Rectangle aScrollRect( Point( nFrozenWidth, 0 ),
+ Size ( GetOutputSizePixel().Width() - nFrozenWidth,
+ GetTitleHeight() - 1
+ ) );
+
+ // scroll the header bar area (if there is no dedicated HeaderBar control)
+ if ( !getDataWindow()->pHeaderBar && nTitleLines )
+ {
+ Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
+ }
+
+ // scroll the data-area
+ aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
+ pDataWin->Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
+ }
+ }
+ else
+ {
+ if ( GetUpdateMode() )
+ {
+ Invalidate( Rectangle(
+ Point( GetFrozenWidth(), 0 ),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
+ getDataWindow()->Invalidate( Rectangle(
+ Point( GetFrozenWidth(), 0 ),
+ pDataWin->GetSizePixel() ) );
+ }
+
+ nFirstCol = nFirstCol + (USHORT)nCols;
+ aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
+ }
+
+ // ggf. externe Headerbar anpassen
+ if ( getDataWindow()->pHeaderBar )
+ {
+ long nWidth = 0;
+ for ( USHORT nCol = 0;
+ nCol < pCols->Count() && nCol < nFirstCol;
+ ++nCol )
+ {
+ // HandleColumn nicht
+ if ( pCols->GetObject(nCol)->GetId() )
+ nWidth += pCols->GetObject(nCol)->Width();
+ }
+
+ getDataWindow()->pHeaderBar->SetOffset( nWidth );
+ }
+
+ if( bInvalidateView )
+ {
+ Control::Invalidate( INVALIDATE_NOCHILDREN );
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+
+ // implicitly show cursor after scrolling
+ if ( nCols )
+ {
+ getDataWindow()->Update();
+ Update();
+ }
+ bScrolling = FALSE;
+ EndScroll();
+
+ return nCols;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ScrollRows( long nRows )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // out of range?
+ if ( getDataWindow()->bNoScrollBack && nRows < 0 )
+ return 0;
+
+ // compute new top row
+ long nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
+
+ long nNewTopRow = Max( (long)nTmpMin, (long)0 );
+
+ if ( nNewTopRow == nTopRow )
+ return 0;
+
+ USHORT nVisibleRows =
+ (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
+
+ VisibleRowsChanged(nNewTopRow, nVisibleRows);
+
+ // compute new top row again (nTopRow might have changed!)
+ nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
+
+ nNewTopRow = Max( (long)nTmpMin, (long)0 );
+
+ StartScroll();
+
+ // scroll area on screen and/or repaint
+ long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow );
+ long nOldTopRow = nTopRow;
+ nTopRow = nNewTopRow;
+
+ if ( GetUpdateMode() )
+ {
+ pVScroll->SetRange( Range( 0L, nRowCount ) );
+ pVScroll->SetThumbPos( nTopRow );
+
+ if( pDataWin->GetBackground().IsScrollable() &&
+ Abs( nDeltaY ) > 0 &&
+ Abs( nDeltaY ) < pDataWin->GetSizePixel().Height() )
+ {
+ pDataWin->Scroll( 0, (short)-nDeltaY, SCROLL_FLAGS );
+ }
+ else
+ getDataWindow()->Invalidate();
+
+ if ( nTopRow - nOldTopRow )
+ getDataWindow()->Update();
+ }
+
+ EndScroll();
+
+ return nTopRow - nOldTopRow;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ScrollPages( long )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return ScrollRows( pDataWin->GetSizePixel().Height() / GetDataRowHeight() );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RowModified( long nRow, USHORT nColId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !GetUpdateMode() )
+ return;
+
+ Rectangle aRect;
+ if ( nColId == USHRT_MAX )
+ // invalidate the whole row
+ aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
+ else
+ {
+ // invalidate the specific field
+ aRect = GetFieldRectPixel( nRow, nColId, FALSE );
+ }
+ getDataWindow()->Invalidate( aRect );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::Clear()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // adjust the total number of rows
+ DoHideCursor( "Clear" );
+ long nOldRowCount = nRowCount;
+ nRowCount = 0;
+ nCurRow = BROWSER_ENDOFSELECTION;
+ nTopRow = 0;
+ nCurColId = 0;
+
+ // nFirstCol darf nicht zurueckgesetzt werden, da ansonsten das Scrollen
+ // total durcheinander kommt
+ // nFirstCol darf nur beim Hinzufuegen oder Loeschen von Spalten geaendert werden
+ // nFirstCol = 0; ->Falsch!!!!
+ aHScroll.SetThumbPos( 0 );
+ pVScroll->SetThumbPos( 0 );
+
+ Invalidate();
+ UpdateScrollbars();
+ SetNoSelection();
+ DoShowCursor( "Clear" );
+ CursorMoved();
+
+ if ( isAccessibleAlive() )
+ {
+ // all rows should be removed, so we remove the row header bar and append it again
+ // to avoid to notify every row remove
+ if ( nOldRowCount != nRowCount )
+ {
+ commitBrowseBoxEvent(
+ CHILD,
+ Any(),
+ makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
+ );
+
+ // and now append it again
+ commitBrowseBoxEvent(
+ CHILD,
+ makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ),
+ Any()
+ );
+
+ // notify a table model change
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange( DELETE,
+ 0,
+ nOldRowCount,
+ 0,
+ GetColumnCount())
+ ),
+ Any()
+ );
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::RowInserted( long nRow, long nNumRows, BOOL bDoPaint, BOOL bKeepSelection )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if (nRow < 0)
+ nRow = 0;
+ else if (nRow > nRowCount) // maximal = nRowCount
+ nRow = nRowCount;
+
+ if ( nNumRows <= 0 )
+ return;
+
+#if 0
+ // Zerlegung in einzelne RowInserted-Aufrufe:
+ if (nNumRows > 1)
+ {
+ for (long i = 0; i < nNumRows; i++)
+ RowInserted(nRow + i,1,bDoPaint);
+ return;
+ }
+#endif
+
+ // adjust total row count
+ BOOL bLastRow = nRow >= nRowCount;
+ nRowCount += nNumRows;
+
+ DoHideCursor( "RowInserted" );
+
+ // must we paint the new rows?
+ long nOldCurRow = nCurRow;
+ Size aSz = pDataWin->GetOutputSizePixel();
+ if ( bDoPaint && nRow >= nTopRow &&
+ nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
+ {
+ long nY = (nRow-nTopRow) * GetDataRowHeight();
+ if ( !bLastRow )
+ {
+ // scroll down the rows behind the new row
+ pDataWin->SetClipRegion();
+ if( pDataWin->GetBackground().IsScrollable() )
+ {
+ pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows,
+ Rectangle( Point( 0, nY ),
+ Size( aSz.Width(), aSz.Height() - nY ) ),
+ SCROLL_FLAGS );
+ }
+ else
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+ else
+ // scroll would cause a repaint, so we must explicitly invalidate
+ pDataWin->Invalidate( Rectangle( Point( 0, nY ),
+ Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) );
+ }
+
+ // ggf. Top-Row korrigieren
+ if ( nRow < nTopRow )
+ nTopRow += nNumRows;
+
+ // adjust the selection
+ if ( bMultiSelection )
+ uRow.pSel->Insert( nRow, nNumRows );
+ else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel )
+ uRow.nSel += nNumRows;
+
+ // adjust the cursor
+ if ( nCurRow == BROWSER_ENDOFSELECTION )
+ GoToRow( 0, FALSE, bKeepSelection );
+ else if ( nRow <= nCurRow )
+ GoToRow( nCurRow += nNumRows, FALSE, bKeepSelection );
+
+ // adjust the vertical scrollbar
+ if ( bDoPaint )
+ {
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ }
+
+ DoShowCursor( "RowInserted" );
+ // notify accessible that rows were inserted
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(
+ INSERT,
+ nRow,
+ nRow + nNumRows,
+ 0,
+ GetColumnCount()
+ )
+ ),
+ Any()
+ );
+
+ for (sal_Int32 i = nRow+1 ; i <= nRowCount ; ++i)
+ {
+ commitHeaderBarEvent(
+ CHILD,
+ makeAny( CreateAccessibleRowHeader( i ) ),
+ Any(),
+ sal_False
+ );
+ }
+ }
+
+ if ( nCurRow != nOldCurRow )
+ CursorMoved();
+
+ DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0");
+ DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0");
+ DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RowRemoved( long nRow, long nNumRows, BOOL bDoPaint )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nRow < 0 )
+ nRow = 0;
+ else if ( nRow >= nRowCount )
+ nRow = nRowCount - 1;
+
+ if ( nNumRows <= 0 )
+ return;
+
+ if ( nRowCount <= 0 )
+ return;
+
+ if ( bDoPaint )
+ {
+ // hide cursor and selection
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+ DoHideCursor( "RowRemoved" );
+ }
+
+ // adjust total row count
+ nRowCount -= nNumRows;
+ if (nRowCount < 0) nRowCount = 0;
+ long nOldCurRow = nCurRow;
+
+ // adjust the selection
+ if ( bMultiSelection )
+ // uRow.pSel->Remove( nRow, nNumRows );
+ for ( long i = 0; i < nNumRows; i++ )
+ uRow.pSel->Remove( nRow );
+ else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows )
+ uRow.nSel -= nNumRows;
+ else if ( nRow <= uRow.nSel )
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+
+ // adjust the cursor
+ if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
+ nCurRow = BROWSER_ENDOFSELECTION;
+ else if ( nRow < nCurRow )
+ {
+ nCurRow -= Min( nCurRow - nRow, nNumRows );
+ // with the above nCurRow points a) to the first row after the removed block or b) to the same line
+ // as before, but moved up nNumRows
+ // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
+ // removed block' is an invalid position then
+ // FS - 09/28/99 - 68429
+ if (nCurRow == nRowCount)
+ --nCurRow;
+ }
+ else if( nRow == nCurRow && nCurRow == nRowCount )
+ nCurRow = nRowCount-1;
+
+ // is the deleted row visible?
+ Size aSz = pDataWin->GetOutputSizePixel();
+ if ( nRow >= nTopRow &&
+ nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
+ {
+ if ( bDoPaint )
+ {
+ // scroll up the rows behind the deleted row
+ // if there are Rows behind
+ if (nRow < nRowCount)
+ {
+ long nY = (nRow-nTopRow) * GetDataRowHeight();
+ pDataWin->SetClipRegion();
+ if( pDataWin->GetBackground().IsScrollable() )
+ {
+ pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows,
+ Rectangle( Point( 0, nY ), Size( aSz.Width(),
+ aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ),
+ SCROLL_FLAGS );
+ }
+ else
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+ else
+ {
+ // Repaint the Rect of the deleted row
+ Rectangle aRect(
+ Point( 0, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(),
+ nNumRows * GetDataRowHeight() ) );
+ pDataWin->Invalidate( aRect );
+ }
+ }
+ }
+ // is the deleted row above of the visible area?
+ else if ( nRow < nTopRow )
+ nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0;
+
+ if ( bDoPaint )
+ {
+ // reshow cursor and selection
+ ToggleSelection();
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+ DoShowCursor( "RowRemoved" );
+
+ // adjust the vertical scrollbar
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ }
+
+ if ( isAccessibleAlive() )
+ {
+ if ( nRowCount == 0 )
+ {
+ // all columns should be removed, so we remove the column header bar and append it again
+ // to avoid to notify every column remove
+ commitBrowseBoxEvent(
+ CHILD,
+ Any(),
+ makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
+ );
+
+ // and now append it again
+ commitBrowseBoxEvent(
+ CHILD,
+ makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR)),
+ Any()
+ );
+ commitBrowseBoxEvent(
+ CHILD,
+ Any(),
+ makeAny( m_pImpl->getAccessibleTable() )
+ );
+
+ // and now append it again
+ commitBrowseBoxEvent(
+ CHILD,
+ makeAny( m_pImpl->getAccessibleTable() ),
+ Any()
+ );
+ }
+ else
+ {
+ commitTableEvent(
+ TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(
+ DELETE,
+ nRow,
+ nRow + nNumRows,
+ 0,
+ GetColumnCount()
+ )
+ ),
+ Any()
+ );
+
+ for (sal_Int32 i = nRow+1 ; i <= (nRow+nNumRows) ; ++i)
+ {
+ commitHeaderBarEvent(
+ CHILD,
+ Any(),
+ makeAny( CreateAccessibleRowHeader( i ) ),
+ sal_False
+ );
+ }
+ }
+ }
+
+ if ( nOldCurRow != nCurRow )
+ CursorMoved();
+
+ DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0");
+ DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
+ DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToRow( long nRow)
+{
+ return GoToRow(nRow, FALSE, FALSE);
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToRowAndDoNotModifySelection( long nRow )
+{
+ return GoToRow( nRow, FALSE, TRUE );
+}
+
+//-------------------------------------------------------------------
+BOOL BrowseBox::GoToRow( long nRow, BOOL bRowColMove, BOOL bKeepSelection )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ long nOldCurRow = nCurRow;
+
+ // nothing to do?
+ if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) )
+ return TRUE;
+
+ // out of range?
+ if ( nRow < 0 || nRow >= nRowCount )
+ return FALSE;
+
+ // nicht erlaubt?
+ if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) )
+ return FALSE;
+
+ if ( getDataWindow()->bNoScrollBack && nRow < nTopRow )
+ nRow = nTopRow;
+
+ // compute the last visible row
+ Size aSz( pDataWin->GetSizePixel() );
+ USHORT nVisibleRows = USHORT( aSz.Height() / GetDataRowHeight() - 1 );
+ long nLastRow = nTopRow + nVisibleRows;
+
+ // suspend Updates
+ getDataWindow()->EnterUpdateLock();
+
+ // ggf. altes Highlight weg
+ if ( !bMultiSelection && !bKeepSelection )
+ ToggleSelection();
+ DoHideCursor( "GoToRow" );
+
+ // must we scroll?
+ BOOL bWasVisible = bSelectionIsVisible;
+ if (! bMultiSelection)
+ {
+ if( !bKeepSelection )
+ bSelectionIsVisible = FALSE;
+ }
+ if ( nRow < nTopRow )
+ ScrollRows( nRow - nTopRow );
+ else if ( nRow > nLastRow )
+ ScrollRows( nRow - nLastRow );
+ bSelectionIsVisible = bWasVisible;
+
+ // adjust cursor (selection) and thumb
+ if ( GetUpdateMode() )
+ pVScroll->SetThumbPos( nTopRow );
+
+ // relative positioning (because nCurRow might have changed in the meantime)!
+ if (nCurRow != BROWSER_ENDOFSELECTION )
+ nCurRow = nCurRow + (nRow - nOldCurRow);
+
+ // make sure that the current position is valid
+ if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0)
+ nCurRow = 0;
+ else if ( nCurRow >= nRowCount )
+ nCurRow = nRowCount - 1;
+ aSelRange = Range( nCurRow, nCurRow );
+
+ // ggf. neues Highlight anzeigen
+ if ( !bMultiSelection && !bKeepSelection )
+ uRow.nSel = nRow;
+
+ // resume Updates
+ getDataWindow()->LeaveUpdateLock();
+
+ // Cursor+Highlight
+ if ( !bMultiSelection && !bKeepSelection)
+ ToggleSelection();
+ DoShowCursor( "GoToRow" );
+ if ( !bRowColMove && nOldCurRow != nCurRow )
+ CursorMoved();
+
+ if ( !bMultiSelection && !bKeepSelection )
+ {
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToColumnId( USHORT nColId)
+{
+ return GoToColumnId(nColId,TRUE,FALSE);
+}
+
+
+BOOL BrowseBox::GoToColumnId( USHORT nColId, BOOL bMakeVisible, BOOL bRowColMove)
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if (!bColumnCursor)
+ return FALSE;
+
+ // erlaubt?
+ if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) )
+ return FALSE;
+
+ if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, TRUE)))
+ {
+ USHORT nNewPos = GetColumnPos(nColId);
+ BrowserColumn* pColumn = pCols->GetObject( nNewPos );
+ DBG_ASSERT( pColumn, "no column object - invalid id?" );
+ if ( !pColumn )
+ return FALSE;
+
+ DoHideCursor( "GoToColumnId" );
+ nCurColId = nColId;
+
+ USHORT nFirstPos = nFirstCol;
+ USHORT nWidth = (USHORT)pColumn->Width();
+ USHORT nLastPos = GetColumnAtXPosPixel(
+ pDataWin->GetSizePixel().Width()-nWidth, FALSE );
+ USHORT nFrozen = FrozenColCount();
+ if ( bMakeVisible && nLastPos &&
+ nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) )
+ {
+ if ( nNewPos < nFirstPos )
+ ScrollColumns( nNewPos-nFirstPos );
+ else if ( nNewPos > nLastPos )
+ ScrollColumns( nNewPos-nLastPos );
+ }
+
+ DoShowCursor( "GoToColumnId" );
+ if (!bRowColMove)
+ CursorMoved();
+ return TRUE;
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToRowColumnId( long nRow, USHORT nColId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // out of range?
+ if ( nRow < 0 || nRow >= nRowCount )
+ return FALSE;
+
+ if (!bColumnCursor)
+ return FALSE;
+
+ // nothing to do ?
+ if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) &&
+ nColId == nCurColId && IsFieldVisible(nCurRow, nColId, TRUE))
+ return TRUE;
+
+ // erlaubt?
+ if (!IsCursorMoveAllowed(nRow, nColId))
+ return FALSE;
+
+ DoHideCursor( "GoToRowColumnId" );
+ BOOL bMoved = GoToRow(nRow, TRUE) && GoToColumnId(nColId, TRUE, TRUE);
+ DoShowCursor( "GoToRowColumnId" );
+
+ if (bMoved)
+ CursorMoved();
+
+ return bMoved;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetNoSelection()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // is there no selection
+ if ( ( !pColSel || !pColSel->GetSelectCount() ) &&
+ ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) ||
+ ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) )
+ // nothing to do
+ return;
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+
+ // unselect all
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any()
+ );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetSelection( const MultiSelection &rSel )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_ASSERT( bMultiSelection, "SetSelection only allowed with Multi-Selection-Mode" );
+
+ // prepare inverted areas
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+
+ // assign Selection
+ *uRow.pSel = rSel;
+
+ // only highlight painted areas
+ pDataWin->Update();
+
+ // notify derived class
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ ToggleSelection();
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any()
+ );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SelectAll()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bMultiSelection )
+ return;
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+
+ // select all rows
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ uRow.pSel->SelectAll(TRUE);
+
+ // Handle-Column nicht highlighten
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
+
+ // highlight the row selection
+ if ( !bHideSelect )
+ {
+ Rectangle aHighlightRect;
+ USHORT nVisibleRows =
+ (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
+ for ( long nRow = Max( nTopRow, uRow.pSel->FirstSelected() );
+ nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows;
+ nRow = uRow.pSel->NextSelected() )
+ aHighlightRect.Union( Rectangle(
+ Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) );
+ pDataWin->Invalidate( aHighlightRect );
+ }
+
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any()
+ );
+ commitHeaderBarEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any(),
+ sal_True
+ ); // column header event
+
+ commitHeaderBarEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any(),
+ sal_False
+ ); // row header event
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SelectRow( long nRow, BOOL _bSelect, BOOL bExpand )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bMultiSelection )
+ {
+ // deselecting is impossible, selecting via cursor
+ if ( _bSelect )
+ GoToRow(nRow, FALSE);
+ return;
+ }
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+
+ // remove old selection?
+ if ( !bExpand || !bMultiSelection )
+ {
+ ToggleSelection();
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ }
+
+ // set new selection
+ if ( !bHideSelect
+ && ( ( bMultiSelection
+ && uRow.pSel->GetTotalRange().Max() >= nRow
+ && uRow.pSel->Select( nRow, _bSelect )
+ )
+ || ( !bMultiSelection
+ && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION )
+ )
+ )
+ {
+ // Handle-Column nicht highlighten
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
+
+ // highlight only newly selected part
+ Rectangle aRect(
+ Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
+ pDataWin->Invalidate( aRect );
+ }
+
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any()
+ );
+ commitHeaderBarEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any(),
+ sal_False
+ ); // row header event
+ }
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetSelectRowCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->GetSelectCount() :
+ uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SelectColumnPos( USHORT nNewColPos, BOOL _bSelect, BOOL bMakeVisible )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bColumnCursor || nNewColPos == BROWSER_INVALIDID )
+ return;
+
+ if ( !bMultiSelection )
+ {
+ if ( _bSelect )
+ GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
+ return;
+ }
+ else
+ {
+ if ( !GoToColumnId( pCols->GetObject( nNewColPos )->GetId(), bMakeVisible ) )
+ return;
+ }
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ pColSel->SelectAll(FALSE);
+
+ if ( pColSel->Select( nNewColPos, _bSelect ) )
+ {
+ // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
+
+ // only highlight painted areas
+ pDataWin->Update();
+ Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, FALSE ) );
+ Rectangle aRect(
+ Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ),
+ Size( pCols->GetObject(nNewColPos)->Width(),
+ pDataWin->GetOutputSizePixel().Height() ) );
+ pDataWin->Invalidate( aRect );
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ if ( isAccessibleAlive() )
+ {
+ commitTableEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any()
+ );
+ commitHeaderBarEvent(
+ SELECTION_CHANGED,
+ Any(),
+ Any(),
+ sal_True
+ ); // column header event
+ }
+ }
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::GetSelectColumnCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
+ return pColSel ? (USHORT) pColSel->GetSelectCount() :
+ nCurRow >= 0 ? 1 : 0;
+}
+
+//-------------------------------------------------------------------
+long BrowseBox::FirstSelectedColumn( ) const
+{
+ return pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
+}
+
+//-------------------------------------------------------------------
+long BrowseBox::NextSelectedColumn( ) const
+{
+ return pColSel ? pColSel->NextSelected() : BROWSER_ENDOFSELECTION;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::FirstSelectedRow( BOOL bInverse )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::NextSelectedRow()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::PrevSelectedRow()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->PrevSelected() : BROWSER_ENDOFSELECTION;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::LastSelectedRow()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->LastSelected() : uRow.nSel;
+}
+
+//-------------------------------------------------------------------
+
+bool BrowseBox::IsRowSelected( long nRow ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel;
+}
+
+//-------------------------------------------------------------------
+
+bool BrowseBox::IsColumnSelected( USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) :
+ nCurColId == nColumnId;
+}
+
+//-------------------------------------------------------------------
+
+sal_Bool BrowseBox::IsAllSelected() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection && uRow.pSel->IsAllSelected();
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::MakeFieldVisible
+(
+ long nRow, // Zeilen-Nr des Feldes (beginnend mit 0)
+ USHORT nColId, // Spalten-Id des Feldes
+ BOOL bComplete // (== FALSE), TRUE => vollst"andig sichtbar machen
+)
+
+/* [Beschreibung]
+
+ Macht das durch 'nRow' und 'nColId' beschriebene Feld durch
+ entsprechendes scrollen sichtbar. Ist 'bComplete' gesetzt, dann wird
+ gefordert, da\s das Feld ganz sichtbar wird.
+
+ [R"uckgabewert]
+
+ BOOL TRUE
+ Das angegebene Feld wurde sichtbar gemacht, bzw. war
+ bereits sichtbar.
+
+ FALSE
+ Das angegebene Feld konnte nicht sichtbar bzw. bei
+ 'bComplete' nicht vollst"andig sichtbar gemacht werden.
+*/
+
+{
+ Size aTestSize = pDataWin->GetSizePixel();
+
+ if ( !bBootstrapped ||
+ ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) )
+ return FALSE;
+
+ // ist es schon sichtbar?
+ BOOL bVisible = IsFieldVisible( nRow, nColId, bComplete );
+ if ( bVisible )
+ return TRUE;
+
+ // Spaltenposition und Feld-Rechteck und Ausgabebereich berechnen
+ USHORT nColPos = GetColumnPos( nColId );
+ Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, FALSE );
+ Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() );
+
+ // links au\serhalb?
+ if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
+ // => nach rechts scrollen
+ ScrollColumns( nColPos - nFirstCol );
+
+ // solange rechts au\serhalb
+ while ( aDataRect.Right() < ( bComplete
+ ? aFieldRect.Right()
+ : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) )
+ {
+ // => nach links scrollen
+ if ( ScrollColumns( 1 ) != 1 )
+ // nichts mehr zu scrollen
+ break;
+ aFieldRect = GetFieldRectPixel( nRow, nColId, FALSE );
+ }
+
+ // oben au\serhalb?
+ if ( nRow < nTopRow )
+ // nach unten scrollen
+ ScrollRows( nRow - nTopRow );
+
+ // unten au\serhalb?
+ long nBottomRow = nTopRow + GetVisibleRows();
+ // OV: damit nBottomRow die Nummer der letzten sichtbaren Zeile ist
+ // (Zaehlung ab Null!), muss sie dekrementiert werden.
+ // Beispiel: BrowseBox enthaelt genau einen Eintrag. nBottomRow := 0 + 1 - 1
+ if( nBottomRow )
+ nBottomRow--;
+
+ if ( nRow > nBottomRow )
+ // nach oben scrollen
+ ScrollRows( nRow - nBottomRow );
+
+ // jetzt kann es immer noch nicht passen, z.B. weil Window zu klein
+ return IsFieldVisible( nRow, nColId, bComplete );
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsFieldVisible( long nRow, USHORT nColumnId,
+ BOOL bCompletely ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // durch frozen-Column verdeckt?
+ USHORT nColPos = GetColumnPos( nColumnId );
+ if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
+ return FALSE;
+
+ Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
+ if ( aRect.IsEmpty() )
+ return FALSE;
+
+ // get the visible area
+ Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() );
+
+ if ( bCompletely )
+ // test if the field is completely visible
+ return aOutRect.IsInside( aRect );
+ else
+ // test if the field is partly of completely visible
+ return !aOutRect.Intersection( aRect ).IsEmpty();
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetFieldRectPixel( long nRow, USHORT nColumnId,
+ BOOL bRelToBrowser) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // get the rectangle relative to DataWin
+ Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
+ if ( aRect.IsEmpty() )
+ return aRect;
+
+ // adjust relative to BrowseBox's output area
+ Point aTopLeft( aRect.TopLeft() );
+ if ( bRelToBrowser )
+ {
+ aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
+ aTopLeft = ScreenToOutputPixel( aTopLeft );
+ }
+
+ return Rectangle( aTopLeft, aRect.GetSize() );
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetRowRectPixel( long nRow, BOOL bRelToBrowser ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // get the rectangle relative to DataWin
+ Rectangle aRect;
+ if ( nTopRow > nRow )
+ // row is above visible area
+ return aRect;
+ aRect = Rectangle(
+ Point( 0, GetDataRowHeight() * (nRow-nTopRow) ),
+ Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
+ if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() )
+ // row is below visible area
+ return aRect;
+
+ // adjust relative to BrowseBox's output area
+ Point aTopLeft( aRect.TopLeft() );
+ if ( bRelToBrowser )
+ {
+ aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
+ aTopLeft = ScreenToOutputPixel( aTopLeft );
+ }
+
+ return Rectangle( aTopLeft, aRect.GetSize() );
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::ImplFieldRectPixel( long nRow, USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // compute the X-coordinte realtiv to DataWin by accumulation
+ long nColX = 0;
+ USHORT nFrozenCols = FrozenColCount();
+ USHORT nCol;
+ for ( nCol = 0;
+ nCol < pCols->Count() && pCols->GetObject(nCol)->GetId() != nColumnId;
+ ++nCol )
+ if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol )
+ nColX += pCols->GetObject(nCol)->Width();
+
+ if ( nCol >= pCols->Count() || ( nCol >= nFrozenCols && nCol < nFirstCol ) )
+ return Rectangle();
+
+ // compute the Y-coordinate relative to DataWin
+ long nRowY = GetDataRowHeight();
+ if ( nRow != BROWSER_ENDOFSELECTION ) // #105497# OJ
+ nRowY = ( nRow - nTopRow ) * GetDataRowHeight();
+
+ // assemble the Rectangle relative to DataWin
+ return Rectangle(
+ Point( nColX + MIN_COLUMNWIDTH, nRowY ),
+ Size( pCols->GetObject(nCol)->Width() - 2*MIN_COLUMNWIDTH,
+ GetDataRowHeight() - 1 ) );
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetRowAtYPosPixel( long nY, BOOL bRelToBrowser ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // compute the Y-coord
+ if ( bRelToBrowser )
+ {
+ Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) );
+ Point aTopLeft = OutputToScreenPixel( Point(0, 0) );
+ nY -= aDataTopLeft.Y() - aTopLeft.Y();
+ }
+
+ // no row there (e.g. in the header)
+ if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() )
+ return -1;
+
+ return nY / GetDataRowHeight() + nTopRow;
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetFieldRect( USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return GetFieldRectPixel( nCurRow, nColumnId );
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::GetColumnAtXPosPixel( long nX, BOOL ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // accumulate the withds of the visible columns
+ long nColX = 0;
+ USHORT nCol;
+ for ( nCol = 0; nCol < USHORT(pCols->Count()); ++nCol )
+ {
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+ if ( pCol->IsFrozen() || nCol >= nFirstCol )
+ nColX += pCol->Width();
+
+ if ( nColX > nX )
+ return nCol;
+ }
+
+ return BROWSER_INVALIDID;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ReserveControlArea( USHORT nWidth )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nWidth != nControlAreaWidth )
+ {
+ OSL_ENSURE(nWidth,"Control aera of 0 is not allowed, Use USHRT_MAX instead!");
+ nControlAreaWidth = nWidth;
+ UpdateScrollbars();
+ }
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetControlArea() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return Rectangle(
+ Point( 0, GetOutputSizePixel().Height() - aHScroll.GetSizePixel().Height() ),
+ Size( GetOutputSizePixel().Width() - aHScroll.GetSizePixel().Width(),
+ aHScroll.GetSizePixel().Height() ) );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetMode( BrowserMode nMode )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+#ifdef DBG_MIx
+ Sound::Beep();
+ nMode =
+// BROWSER_COLUMNSELECTION |
+// BROWSER_MULTISELECTION |
+ BROWSER_THUMBDRAGGING |
+ BROWSER_KEEPHIGHLIGHT |
+ BROWSER_HLINES |
+ BROWSER_VLINES |
+// BROWSER_HIDECURSOR |
+// BROWSER_NO_HSCROLL |
+// BROWSER_NO_SCROLLBACK |
+ BROWSER_AUTO_VSCROLL |
+ BROWSER_AUTO_HSCROLL |
+ BROWSER_TRACKING_TIPS |
+// BROWSER_HIGHLIGHT_NONE |
+ BROWSER_HEADERBAR_NEW |
+// BROWSER_AUTOSIZE_LASTCOL |
+ 0;
+#endif
+
+ getDataWindow()->bAutoHScroll = BROWSER_AUTO_HSCROLL == ( nMode & BROWSER_AUTO_HSCROLL );
+ getDataWindow()->bAutoVScroll = BROWSER_AUTO_VSCROLL == ( nMode & BROWSER_AUTO_VSCROLL );
+ getDataWindow()->bNoHScroll = BROWSER_NO_HSCROLL == ( nMode & BROWSER_NO_HSCROLL );
+ getDataWindow()->bNoVScroll = BROWSER_NO_VSCROLL == ( nMode & BROWSER_NO_VSCROLL );
+
+ DBG_ASSERT( !( getDataWindow()->bAutoHScroll && getDataWindow()->bNoHScroll ),
+ "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" );
+ DBG_ASSERT( !( getDataWindow()->bAutoVScroll && getDataWindow()->bNoVScroll ),
+ "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" );
+ if ( getDataWindow()->bAutoHScroll )
+ getDataWindow()->bNoHScroll = FALSE;
+ if ( getDataWindow()->bAutoVScroll )
+ getDataWindow()->bNoVScroll = FALSE;
+
+ if ( getDataWindow()->bNoHScroll )
+ aHScroll.Hide();
+
+ nControlAreaWidth = USHRT_MAX;
+
+ getDataWindow()->bNoScrollBack =
+ BROWSER_NO_SCROLLBACK == ( nMode & BROWSER_NO_SCROLLBACK);
+
+ long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
+ MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0;
+ MultiSelection *pOldColSel = pColSel;
+
+ delete pVScroll;
+
+ bThumbDragging = ( nMode & BROWSER_THUMBDRAGGING ) == BROWSER_THUMBDRAGGING;
+ bMultiSelection = ( nMode & BROWSER_MULTISELECTION ) == BROWSER_MULTISELECTION;
+ bColumnCursor = ( nMode & BROWSER_COLUMNSELECTION ) == BROWSER_COLUMNSELECTION;
+ bKeepHighlight = ( nMode & BROWSER_KEEPSELECTION ) == BROWSER_KEEPSELECTION;
+
+ bHideSelect = ((nMode & BROWSER_HIDESELECT) == BROWSER_HIDESELECT);
+ // default: do not hide the cursor at all (untaken scrolling and such)
+ bHideCursor = NO_CURSOR_HIDE;
+
+ if ( BROWSER_SMART_HIDECURSOR == ( nMode & BROWSER_SMART_HIDECURSOR ) )
+ { // smart cursor hide overrules hard cursor hide
+ bHideCursor = SMART_CURSOR_HIDE;
+ }
+ else if ( BROWSER_HIDECURSOR == ( nMode & BROWSER_HIDECURSOR ) )
+ {
+ bHideCursor = HARD_CURSOR_HIDE;
+ }
+
+ m_bFocusOnlyCursor = ((nMode & BROWSER_CURSOR_WO_FOCUS) == 0);
+
+ bHLines = ( nMode & BROWSER_HLINESFULL ) == BROWSER_HLINESFULL;
+ bVLines = ( nMode & BROWSER_VLINESFULL ) == BROWSER_VLINESFULL;
+ bHDots = ( nMode & BROWSER_HLINESDOTS ) == BROWSER_HLINESDOTS;
+ bVDots = ( nMode & BROWSER_VLINESDOTS ) == BROWSER_VLINESDOTS;
+
+ WinBits nVScrollWinBits =
+ WB_VSCROLL | ( ( nMode & BROWSER_THUMBDRAGGING ) ? WB_DRAG : 0 );
+ pVScroll = ( nMode & BROWSER_TRACKING_TIPS ) == BROWSER_TRACKING_TIPS
+ ? new BrowserScrollBar( this, nVScrollWinBits,
+ (BrowserDataWin*) pDataWin )
+ : new ScrollBar( this, nVScrollWinBits );
+ pVScroll->SetLineSize( 1 );
+ pVScroll->SetPageSize(1);
+ pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
+ pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
+
+ getDataWindow()->bAutoSizeLastCol =
+ BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL );
+ getDataWindow()->bOwnDataChangedHdl =
+ BROWSER_OWN_DATACHANGED == ( nMode & BROWSER_OWN_DATACHANGED );
+
+ // Headerbar erzeugen, was passiert, wenn eine erzeugt werden mu� und schon Spalten bestehen ?
+ if ( BROWSER_HEADERBAR_NEW == ( nMode & BROWSER_HEADERBAR_NEW ) )
+ {
+ if (!getDataWindow()->pHeaderBar)
+ getDataWindow()->pHeaderBar = CreateHeaderBar( this );
+ }
+ else
+ {
+ DELETEZ(getDataWindow()->pHeaderBar);
+ }
+
+
+
+ if ( bColumnCursor )
+ {
+ pColSel = pOldColSel ? pOldColSel : new MultiSelection;
+ pColSel->SetTotalRange( Range( 0, pCols->Count()-1 ) );
+ }
+ else
+ {
+ pColSel = 0;
+ delete pColSel;
+ }
+
+ if ( bMultiSelection )
+ {
+ if ( pOldRowSel )
+ uRow.pSel = pOldRowSel;
+ else
+ uRow.pSel = new MultiSelection;
+ }
+ else
+ {
+ uRow.nSel = nOldRowSel;
+ delete pOldRowSel;
+ }
+
+ if ( bBootstrapped )
+ {
+ StateChanged( STATE_CHANGE_INITSHOW );
+ if ( bMultiSelection && !pOldRowSel &&
+ nOldRowSel != BROWSER_ENDOFSELECTION )
+ uRow.pSel->Select( nOldRowSel );
+ }
+
+ if ( pDataWin )
+ pDataWin->Invalidate();
+
+ // kein Cursor auf Handle-Column
+ if ( nCurColId == 0 )
+ nCurColId = GetColumnId( 1 );
+
+ m_nCurrentMode = nMode;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::VisibleRowsChanged( long, USHORT )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // Das alte Verhalten: NumRows automatisch korrigieren:
+ if ( nRowCount < GetRowCount() )
+ {
+ RowInserted(nRowCount,GetRowCount() - nRowCount,FALSE);
+ }
+ else if ( nRowCount > GetRowCount() )
+ {
+ RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(),FALSE);
+ }
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsCursorMoveAllowed( long, USHORT ) const
+
+/* [Beschreibung]
+
+ Diese virtuelle Methode wird immer gerufen bevor der Cursor direkt
+ bewegt werden soll. Durch 'return FALSE' kann verhindert werden, da\s
+ dies geschieht, wenn z.B. ein Datensatz irgendwelchen Rules widerspricht.
+
+ Diese Methode wird nicht gerufen, wenn die Cursorbewegung durch
+ ein L"oschen oder Einf"ugen (einer Zeile/Spalte) ausgel"ost wird, also
+ genaugenommen nur eine Cursor-Korrektur vorliegt.
+
+ Die Basisimplementierung liefert derzeit immer TRUE.
+*/
+
+{
+ return TRUE;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetDataRowHeight() const
+{
+ return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight());
+}
+
+//-------------------------------------------------------------------
+
+Window& BrowseBox::GetEventWindow() const
+{
+ return *getDataWindow()->pEventWin;
+}
+
+//-------------------------------------------------------------------
+
+BrowserHeader* BrowseBox::CreateHeaderBar( BrowseBox* pParent )
+{
+ BrowserHeader* pNewBar = new BrowserHeader( pParent );
+ pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
+ return pNewBar;
+}
+
+void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar )
+{
+ delete ( (BrowserDataWin*)pDataWin )->pHeaderBar;
+ ( (BrowserDataWin*)pDataWin )->pHeaderBar = pHeaderBar;
+ ( (BrowserDataWin*)pDataWin )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
+}
+//-------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+const char* BrowseBoxCheckInvariants( const void * pVoid )
+{
+ const BrowseBox * p = (const BrowseBox *)pVoid;
+
+ if (p->nRowCount < 0) return "BrowseBox: nRowCount < 0";
+ if (p->nTopRow < 0) return "BrowseBox: nTopRow < 0";
+ if (p->nTopRow >= p->nRowCount && p->nRowCount != 0) return "BrowseBox: nTopRow >= nRowCount && nRowCount != 0";
+ if (p->nCurRow < -1) return "BrowseBox: nCurRow < -1";
+ if (p->nCurRow > p->nRowCount) return "BrowseBox: nCurRow > nRowCount";
+
+ // Leider waehrend der Bearbeitung nicht immer der Fall:
+ //if (p->nCurRow < 0 && p->nRowCount != 0) return "nCurRow < 0 && nRowCount != 0";
+ //if (p->nCurRow >= p->nRowCount && p->nRowCount != 0) return "nCurRow >= nRowCount && nRowCount != 0";
+
+ return NULL;
+}
+#endif
+
+//-------------------------------------------------------------------
+long BrowseBox::GetTitleHeight() const
+{
+ long nHeight;
+ // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
+ // our (and the header's) zoom factor
+ HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar;
+ if ( pHeaderBar )
+ nHeight = pHeaderBar->GetTextHeight();
+ else
+ nHeight = GetTextHeight();
+
+ return nTitleLines ? nTitleLines * nHeight + 4 : 0;
+}
+
+//-------------------------------------------------------------------
+long BrowseBox::CalcReverseZoom(long nVal)
+{
+ if (IsZoom())
+ {
+ const Fraction& rZoom = GetZoom();
+ double n = (double)nVal;
+ n *= (double)rZoom.GetDenominator();
+ n /= (double)rZoom.GetNumerator();
+ nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5);
+ }
+
+ return nVal;
+}
+
+//-------------------------------------------------------------------
+HeaderBar* BrowseBox::GetHeaderBar() const
+{
+ return getDataWindow()->pHeaderBar;
+}
+//-------------------------------------------------------------------
+
+void BrowseBox::CursorMoved()
+{
+ // before implementing more here, please adjust the EditBrowseBox
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( isAccessibleAlive() && HasFocus() )
+ commitTableEvent(
+ ACTIVE_DESCENDANT_CHANGED,
+ makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ),
+ Any()
+ );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::LoseFocus()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_TRACE1( "BrowseBox: %p->LoseFocus", this );
+
+ if ( bHasFocus )
+ {
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ DoHideCursor( "LoseFocus" );
+
+ if ( !bKeepHighlight )
+ {
+ ToggleSelection();
+ bSelectionIsVisible = FALSE;
+ }
+
+ bHasFocus = FALSE;
+ }
+ Control::LoseFocus();
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::GetFocus()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_TRACE1( "BrowseBox: %p->GetFocus", this );
+
+ if ( !bHasFocus )
+ {
+ if ( !bSelectionIsVisible )
+ {
+ bSelectionIsVisible = TRUE;
+ if ( bBootstrapped )
+ ToggleSelection();
+ }
+
+ bHasFocus = TRUE;
+ DoShowCursor( "GetFocus" );
+ }
+ Control::GetFocus();
+}
+
+
diff --git a/svtools/source/brwbox/brwbox2.cxx b/svtools/source/brwbox/brwbox2.cxx
new file mode 100644
index 000000000000..68cf316e813b
--- /dev/null
+++ b/svtools/source/brwbox/brwbox2.cxx
@@ -0,0 +1,2184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <tools/debug.hxx>
+#include <svtools/brwbox.hxx>
+#include "datwin.hxx"
+#include <svtools/colorcfg.hxx>
+#include <vcl/salgtype.hxx>
+
+#ifndef GCC
+#endif
+#include <tools/multisel.hxx>
+#include <algorithm>
+
+using namespace ::com::sun::star::datatransfer;
+
+#define getDataWindow() ((BrowserDataWin*)pDataWin)
+
+
+//===================================================================
+
+DBG_NAMEEX(BrowseBox)
+
+//===================================================================
+
+extern const char* BrowseBoxCheckInvariants( const void * pVoid );
+
+DECLARE_LIST( BrowserColumns, BrowserColumn* )
+
+//===================================================================
+
+void BrowseBox::StartDrag( sal_Int8 /* _nAction */, const Point& /* _rPosPixel */ )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ // not interested in this event
+}
+
+//===================================================================
+
+sal_Int8 BrowseBox::AcceptDrop( const AcceptDropEvent& _rEvt )
+{
+ BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
+ AcceptDropEvent aTransformed( _rEvt );
+ aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
+ return pDataWindow->AcceptDrop( aTransformed );
+}
+
+//===================================================================
+
+sal_Int8 BrowseBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
+{
+ BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
+ ExecuteDropEvent aTransformed( _rEvt );
+ aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
+ return pDataWindow->ExecuteDrop( aTransformed );
+}
+
+//===================================================================
+
+sal_Int8 BrowseBox::AcceptDrop( const BrowserAcceptDropEvent& )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ // not interested in this event
+ return DND_ACTION_NONE;
+}
+
+//===================================================================
+
+sal_Int8 BrowseBox::ExecuteDrop( const BrowserExecuteDropEvent& )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ // not interested in this event
+ return DND_ACTION_NONE;
+}
+
+//===================================================================
+
+void* BrowseBox::implGetDataFlavors() const
+{
+ if (static_cast<BrowserDataWin*>(pDataWin)->bCallingDropCallback)
+ return &static_cast<BrowserDataWin*>(pDataWin)->GetDataFlavorExVector();
+ return &GetDataFlavorExVector();
+}
+
+//===================================================================
+
+sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat )
+{
+ if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
+ return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _nFormat );
+
+ return DropTargetHelper::IsDropFormatSupported( _nFormat );
+}
+
+//===================================================================
+
+sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat ) const
+{
+ return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _nFormat );
+}
+
+//===================================================================
+
+sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor )
+{
+ if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
+ return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _rFlavor );
+
+ return DropTargetHelper::IsDropFormatSupported( _rFlavor );
+}
+
+//===================================================================
+
+sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor ) const
+{
+ return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _rFlavor );
+}
+
+//===================================================================
+
+void BrowseBox::Command( const CommandEvent& rEvt )
+{
+ if ( !getDataWindow()->bInCommand )
+ Control::Command( rEvt );
+}
+
+//===================================================================
+
+bool BrowseBox::IsInCommandEvent() const
+{
+ return getDataWindow()->bInCommand;
+}
+
+//===================================================================
+
+void BrowseBox::StateChanged( StateChangedType nStateChange )
+{
+ Control::StateChanged( nStateChange );
+
+ if ( STATE_CHANGE_MIRRORING == nStateChange )
+ {
+ getDataWindow()->EnableRTL( IsRTLEnabled() );
+
+ HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
+ if ( pHeaderBar )
+ pHeaderBar->EnableRTL( IsRTLEnabled() );
+ aHScroll.EnableRTL( IsRTLEnabled() );
+ if( pVScroll )
+ pVScroll->EnableRTL( IsRTLEnabled() );
+ Resize();
+ }
+ else if ( STATE_CHANGE_INITSHOW == nStateChange )
+ {
+ bBootstrapped = TRUE; // muss zuerst gesetzt werden!
+
+ Resize();
+ if ( bMultiSelection )
+ uRow.pSel->SetTotalRange( Range( 0, nRowCount - 1 ) );
+ if ( nRowCount == 0 )
+ nCurRow = BROWSER_ENDOFSELECTION;
+ else if ( nCurRow == BROWSER_ENDOFSELECTION )
+ nCurRow = 0;
+
+
+ if ( HasFocus() )
+ {
+ bSelectionIsVisible = TRUE;
+ bHasFocus = TRUE;
+ }
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ CursorMoved();
+ }
+ else if (STATE_CHANGE_ZOOM == nStateChange)
+ {
+ pDataWin->SetZoom(GetZoom());
+ HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
+ if (pHeaderBar)
+ pHeaderBar->SetZoom(GetZoom());
+
+ // let the cols calc their new widths and adjust the header bar
+ for ( USHORT nPos = 0; nPos < pCols->Count(); ++nPos )
+ {
+ pCols->GetObject(nPos)->ZoomChanged(GetZoom());
+ if ( pHeaderBar )
+ pHeaderBar->SetItemSize( pCols->GetObject(nPos)->GetId(), pCols->GetObject(nPos)->Width() );
+ }
+
+ // all our controls have to be repositioned
+ Resize();
+ }
+ else if (STATE_CHANGE_ENABLE == nStateChange)
+ {
+ // do we have a handle column?
+ sal_Bool bHandleCol = pCols->Count() && (0 == pCols->GetObject(0)->GetId());
+ // do we have a header bar
+ sal_Bool bHeaderBar = (NULL != static_cast<BrowserDataWin&>(GetDataWindow()).pHeaderBar);
+
+ if ( nTitleLines
+ && ( !bHeaderBar
+ || bHandleCol
+ )
+ )
+ // we draw the text in our header bar in a color dependent on the enabled state. So if this state changed
+ // -> redraw
+ Invalidate(Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetTitleHeight() - 1)));
+ }
+}
+
+//===================================================================
+
+void BrowseBox::Select()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::DoubleClick( const BrowserMouseEvent & )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::QueryMinimumRowHeight()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ return CalcZoom( 5 );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ImplStartTracking()
+{
+ DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ImplTracking()
+{
+ DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ImplEndTracking()
+{
+ DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RowHeightChanged()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::QueryColumnResize( USHORT, long nWidth )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ return nWidth;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ColumnResized( USHORT )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ColumnMoved( USHORT )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::StartScroll()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ //((Control*)pDataWin)->HideFocus();
+ DoHideCursor( "StartScroll" );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::EndScroll()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ DoShowCursor( "EndScroll" );
+}
+
+//-------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize( "", off )
+#endif
+
+void BrowseBox::ToggleSelection( BOOL bForce )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // selection highlight-toggling allowed?
+ if ( bHideSelect )
+ return;
+ if ( !bForce &&
+ ( bNotToggleSel || !IsUpdateMode() || !bSelectionIsVisible ) )
+ return;
+
+ // only highlight painted areas!
+ bNotToggleSel = TRUE;
+ if ( FALSE && !getDataWindow()->bInPaint )
+ pDataWin->Update();
+
+ // accumulate areas of rows to highlight
+ RectangleList aHighlightList;
+ long nLastRowInRect = 0; // fuer den CFront
+
+ // Handle-Column nicht highlighten
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ long nOfsX = (!pFirstCol || pFirstCol->GetId()) ? 0 : pFirstCol->Width();
+
+ // accumulate old row selection
+ long nBottomRow = nTopRow +
+ pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight();
+ if ( nBottomRow > GetRowCount() && GetRowCount() )
+ nBottomRow = GetRowCount();
+ for ( long nRow = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
+ nRow != BROWSER_ENDOFSELECTION && nRow <= nBottomRow;
+ nRow = bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION )
+ {
+ if ( nRow < nTopRow )
+ continue;
+
+ Rectangle aAddRect(
+ Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
+ if ( aHighlightList.Count() && nLastRowInRect == ( nRow - 1 ) )
+ aHighlightList.First()->Union( aAddRect );
+ else
+ aHighlightList.Insert( new Rectangle( aAddRect ), (ULONG) 0 );
+ nLastRowInRect = nRow;
+ }
+
+ // unhighlight the old selection (if any)
+ while ( aHighlightList.Count() )
+ {
+ Rectangle *pRect = aHighlightList.Remove( aHighlightList.Count() - 1 );
+ pDataWin->Invalidate( *pRect );
+ delete pRect;
+ }
+
+ // unhighlight old column selection (if any)
+ for ( long nColId = pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
+ nColId != BROWSER_ENDOFSELECTION;
+ nColId = pColSel->NextSelected() )
+ {
+ Rectangle aRect( GetFieldRectPixel(nCurRow,
+ pCols->GetObject(nColId)->GetId(),
+ FALSE ) );
+ aRect.Left() -= MIN_COLUMNWIDTH;
+ aRect.Right() += MIN_COLUMNWIDTH;
+ aRect.Top() = 0;
+ aRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
+ pDataWin->Invalidate( aRect );
+ }
+
+ bNotToggleSel = FALSE;
+}
+
+#ifdef _MSC_VER
+#pragma optimize( "", on )
+#endif
+
+//-------------------------------------------------------------------
+
+void BrowseBox::DrawCursor()
+{
+ BOOL bReallyHide = FALSE;
+ if ( SMART_CURSOR_HIDE == bHideCursor )
+ {
+ if ( !GetSelectRowCount() && !GetSelectColumnCount() )
+ bReallyHide = TRUE;
+ }
+ else if ( HARD_CURSOR_HIDE == bHideCursor )
+ {
+ bReallyHide = TRUE;
+ }
+
+ bReallyHide |= !bSelectionIsVisible || !IsUpdateMode() || bScrolling || nCurRow < 0;
+
+ if (PaintCursorIfHiddenOnce())
+ bReallyHide |= ( GetCursorHideCount() > 1 );
+ else
+ bReallyHide |= ( GetCursorHideCount() > 0 );
+
+ // keine Cursor auf Handle-Column
+ if ( nCurColId == 0 )
+ nCurColId = GetColumnId(1);
+
+ // Cursor-Rechteck berechnen
+ Rectangle aCursor;
+ if ( bColumnCursor )
+ {
+ aCursor = GetFieldRectPixel( nCurRow, nCurColId, FALSE );
+ //! --aCursor.Bottom();
+ aCursor.Left() -= MIN_COLUMNWIDTH;
+ aCursor.Right() += 1;
+ aCursor.Bottom() += 1;
+ }
+ else
+ aCursor = Rectangle(
+ Point( ( pCols->Count() && pCols->GetObject(0)->GetId() == 0 ) ?
+ pCols->GetObject(0)->Width() : 0,
+ (nCurRow - nTopRow) * GetDataRowHeight() + 1 ),
+ Size( pDataWin->GetOutputSizePixel().Width() + 1,
+ GetDataRowHeight() - 2 ) );
+ if ( bHLines )
+ {
+ if ( !bMultiSelection )
+ --aCursor.Top();
+ --aCursor.Bottom();
+ }
+
+ //!mi_mac pDataWin->Update();
+
+ if (m_aCursorColor == COL_TRANSPARENT)
+ {
+ // auf diesem Plattformen funktioniert der StarView-Focus richtig
+ if ( bReallyHide )
+ ((Control*)pDataWin)->HideFocus();
+ else
+ ((Control*)pDataWin)->ShowFocus( aCursor );
+ }
+ else
+ {
+ Color rCol = bReallyHide ? pDataWin->GetFillColor() : m_aCursorColor;
+ Color aOldFillColor = pDataWin->GetFillColor();
+ Color aOldLineColor = pDataWin->GetLineColor();
+ pDataWin->SetFillColor();
+ pDataWin->SetLineColor( rCol );
+ pDataWin->DrawRect( aCursor );
+ pDataWin->SetLineColor( aOldLineColor );
+ pDataWin->SetFillColor( aOldFillColor );
+ }
+}
+
+//-------------------------------------------------------------------
+
+ULONG BrowseBox::GetColumnWidth( USHORT nId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ USHORT nItemPos = GetColumnPos( nId );
+ if ( nItemPos >= pCols->Count() )
+ return 0;
+ return pCols->GetObject(nItemPos)->Width();
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::GetColumnId( USHORT nPos ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nPos >= pCols->Count() )
+ return 0;
+ return pCols->GetObject(nPos)->GetId();
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::GetColumnPos( USHORT nId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ for ( USHORT nPos = 0; nPos < pCols->Count(); ++nPos )
+ if ( pCols->GetObject(nPos)->GetId() == nId )
+ return nPos;
+ return BROWSER_INVALIDID;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsFrozen( USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ for ( USHORT nPos = 0; nPos < pCols->Count(); ++nPos )
+ if ( pCols->GetObject(nPos)->GetId() == nColumnId )
+ return pCols->GetObject(nPos)->IsFrozen();
+ return FALSE;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ExpandRowSelection( const BrowserMouseEvent& rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ DoHideCursor( "ExpandRowSelection" );
+
+ // expand the last selection
+ if ( bMultiSelection )
+ {
+ Range aJustifiedRange( aSelRange );
+ aJustifiedRange.Justify();
+
+ BOOL bSelectThis = ( bSelect != aJustifiedRange.IsInside( rEvt.GetRow() ) );
+
+ if ( aJustifiedRange.IsInside( rEvt.GetRow() ) )
+ {
+ // down and up
+ while ( rEvt.GetRow() < aSelRange.Max() )
+ { // ZTC/Mac bug - dont put these statemants together!
+ SelectRow( aSelRange.Max(), bSelectThis, TRUE );
+ --aSelRange.Max();
+ }
+ while ( rEvt.GetRow() > aSelRange.Max() )
+ { // ZTC/Mac bug - dont put these statemants together!
+ SelectRow( aSelRange.Max(), bSelectThis, TRUE );
+ ++aSelRange.Max();
+ }
+ }
+ else
+ {
+ // up and down
+ BOOL bOldSelecting = bSelecting;
+ bSelecting = TRUE;
+ while ( rEvt.GetRow() < aSelRange.Max() )
+ { // ZTC/Mac bug - dont put these statemants together!
+ --aSelRange.Max();
+ if ( !IsRowSelected( aSelRange.Max() ) )
+ {
+ SelectRow( aSelRange.Max(), bSelectThis, TRUE );
+ bSelect = TRUE;
+ }
+ }
+ while ( rEvt.GetRow() > aSelRange.Max() )
+ { // ZTC/Mac bug - dont put these statemants together!
+ ++aSelRange.Max();
+ if ( !IsRowSelected( aSelRange.Max() ) )
+ {
+ SelectRow( aSelRange.Max(), bSelectThis, TRUE );
+ bSelect = TRUE;
+ }
+ }
+ bSelecting = bOldSelecting;
+ if ( bSelect )
+ Select();
+ }
+ }
+ else
+ if ( !bMultiSelection || !IsRowSelected( rEvt.GetRow() ) )
+ SelectRow( rEvt.GetRow(), TRUE );
+
+ GoToRow( rEvt.GetRow(), FALSE );
+ DoShowCursor( "ExpandRowSelection" );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::Resize()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ if ( !bBootstrapped && IsReallyVisible() )
+ BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
+ if ( !pCols->Count() )
+ {
+ getDataWindow()->bResizeOnPaint = TRUE;
+ return;
+ }
+ getDataWindow()->bResizeOnPaint = FALSE;
+
+ // calc the size of the scrollbars
+ // (we can't ask the scrollbars for their widths cause if we're zoomed they still have to be
+ // resized - which is done in UpdateScrollbars)
+ ULONG nSBSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if (IsZoom())
+ nSBSize = (ULONG)(nSBSize * (double)GetZoom());
+
+ long nSize = pDataWin->GetPosPixel().Y();
+ if( !getDataWindow()->bNoHScroll )
+ nSize += aHScroll.GetSizePixel().Height();
+
+ if ( GetOutputSizePixel().Height() < nSize )
+ return;
+
+ DoHideCursor( "Resize" );
+ USHORT nOldVisibleRows =
+ (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
+
+ // did we need a horiz. scroll bar oder gibt es eine Control Area?
+ if ( !getDataWindow()->bNoHScroll &&
+ ( ( pCols->Count() - FrozenColCount() ) > 1 ) )
+ aHScroll.Show();
+ else
+ aHScroll.Hide();
+
+ // calculate the size of the data window
+ long nDataHeight = GetOutputSizePixel().Height() - GetTitleHeight();
+ if ( aHScroll.IsVisible() || ( nControlAreaWidth != USHRT_MAX ) )
+ nDataHeight -= nSBSize;
+
+ long nDataWidth = GetOutputSizePixel().Width();
+ if ( pVScroll->IsVisible() )
+ nDataWidth -= nSBSize;
+
+ // adjust position and size of data window
+ pDataWin->SetPosSizePixel(
+ Point( 0, GetTitleHeight() ),
+ Size( nDataWidth, nDataHeight ) );
+
+ USHORT nVisibleRows =
+ (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
+
+ // TopRow ist unveraendert, aber die Anzahl sichtbarer Zeilen hat sich
+ // geaendert
+ if ( nVisibleRows != nOldVisibleRows )
+ VisibleRowsChanged(nTopRow, nVisibleRows);
+
+ UpdateScrollbars();
+
+ // Control-Area
+ Rectangle aInvalidArea( GetControlArea() );
+ aInvalidArea.Right() = GetOutputSizePixel().Width();
+ aInvalidArea.Left() = 0;
+ Invalidate( aInvalidArea );
+
+ // external header-bar
+ HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
+ if ( pHeaderBar )
+ {
+ // Handle-Column beruecksichtigen
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
+ pHeaderBar->SetPosSizePixel( Point( nOfsX, 0 ), Size( GetOutputSizePixel().Width() - nOfsX, GetTitleHeight() ) );
+ }
+
+ AutoSizeLastColumn(); // adjust last column width
+ DoShowCursor( "Resize" );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::Paint( const Rectangle& rRect )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // initializations
+ if ( !bBootstrapped && IsReallyVisible() )
+ BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
+ if ( !pCols->Count() )
+ return;
+
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ BOOL bHandleCol = pFirstCol && pFirstCol->GetId() == 0;
+ BOOL bHeaderBar = getDataWindow()->pHeaderBar != NULL;
+
+ // draw delimitational lines
+ if ( !getDataWindow()->bNoHScroll )
+ DrawLine( Point( 0, aHScroll.GetPosPixel().Y() ),
+ Point( GetOutputSizePixel().Width(),
+ aHScroll.GetPosPixel().Y() ) );
+
+ if ( nTitleLines )
+ {
+ if ( !bHeaderBar )
+ DrawLine( Point( 0, GetTitleHeight() - 1 ),
+ Point( GetOutputSizePixel().Width(),
+ GetTitleHeight() - 1 ) );
+ else if ( bHandleCol )
+ DrawLine( Point( 0, GetTitleHeight() - 1 ),
+ Point( pFirstCol->Width(), GetTitleHeight() - 1 ) );
+ }
+
+ // Title Bar
+ // Wenn es eine Handle Column gibt und die Headerbar verfuegbar ist, dann nur
+ // die HandleColumn
+ // Handle-Column beruecksichtigen
+ if ( nTitleLines && (!bHeaderBar || bHandleCol) )
+ {
+ // iterate through columns to redraw
+ long nX = 0;
+ USHORT nCol;
+ for ( nCol = 0;
+ nCol < pCols->Count() && nX < rRect.Right();
+ ++nCol )
+ {
+ // skip invisible colums between frozen and scrollable area
+ if ( nCol < nFirstCol && !pCols->GetObject(nCol)->IsFrozen() )
+ nCol = nFirstCol;
+
+ // nur die HandleCol ?
+ if (bHeaderBar && bHandleCol && nCol > 0)
+ break;
+
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+
+ // draw the column and increment position
+ if ( pCol->Width() > 4 )
+ {
+ ButtonFrame aButtonFrame( Point( nX, 0 ),
+ Size( pCol->Width()-1, GetTitleHeight()-1 ),
+ pCol->Title(), FALSE, FALSE,
+ 0 != (BROWSER_COLUMN_TITLEABBREVATION&pCol->Flags()),
+ !IsEnabled());
+ aButtonFrame.Draw( *this );
+ DrawLine( Point( nX + pCol->Width() - 1, 0 ),
+ Point( nX + pCol->Width() - 1, GetTitleHeight()-1 ) );
+ }
+ else
+ {
+ Color aOldFillColor = GetFillColor();
+ SetFillColor( Color( COL_BLACK ) );
+ DrawRect( Rectangle( Point( nX, 0 ), Size( pCol->Width(), GetTitleHeight() - 1 ) ) );
+ SetFillColor( aOldFillColor );
+ }
+
+ // skip column
+ nX += pCol->Width();
+ }
+
+ // retouching
+ if ( !bHeaderBar && nCol == pCols->Count() )
+ {
+ const StyleSettings &rSettings = GetSettings().GetStyleSettings();
+ Color aColFace( rSettings.GetFaceColor() );
+ Color aOldFillColor = GetFillColor();
+ Color aOldLineColor = GetLineColor();
+ SetFillColor( aColFace );
+ SetLineColor( aColFace );
+ DrawRect( Rectangle(
+ Point( nX, 0 ),
+ Point( rRect.Right(), GetTitleHeight() - 2 ) ) );
+ SetFillColor( aOldFillColor); // aOldLineColor ); oj 09.02.00 seems to be a copy&paste bug
+ SetLineColor( aOldLineColor); // aOldFillColor );
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::PaintRow( OutputDevice&, const Rectangle& )
+{
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ BOOL bDrawSelection = (nFlags & WINDOW_DRAW_NOSELECTION) == 0;
+
+ // we need pixel coordinates
+ Size aRealSize = pDev->LogicToPixel(rSize);
+ Point aRealPos = pDev->LogicToPixel(rPos);
+
+ if ((rSize.Width() < 3) || (rSize.Height() < 3))
+ // we want to have two pixels frame ...
+ return;
+
+ Font aFont = GetDataWindow().GetDrawPixelFont( pDev );
+ // the 'normal' painting uses always the data window as device to output to, so we have to calc the new font
+ // relative to the data wins current settings
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+
+ // draw a frame
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ pDev->SetLineColor(rStyleSettings.GetDarkShadowColor());
+ pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
+ Point(aRealPos.X(), aRealPos.Y() + aRealSize.Height() - 1));
+ pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
+ Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y()));
+ pDev->SetLineColor(rStyleSettings.GetShadowColor());
+ pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + 1),
+ Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1));
+ pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1),
+ Point(aRealPos.X() + 1, aRealPos.Y() + aRealSize.Height() - 1));
+
+ HeaderBar* pBar = getDataWindow()->pHeaderBar;
+
+ // we're drawing onto a foreign device, so we have to fake the DataRowHeight for the subsequent ImplPaintData
+ // (as it is based on the settings of our data window, not the foreign device)
+ if (!nDataRowHeight)
+ ImpGetDataRowHeight();
+ long nHeightLogic = PixelToLogic(Size(0, nDataRowHeight), MAP_10TH_MM).Height();
+ long nForeignHeightPixel = pDev->LogicToPixel(Size(0, nHeightLogic), MAP_10TH_MM).Height();
+
+ long nOriginalHeight = nDataRowHeight;
+ nDataRowHeight = nForeignHeightPixel;
+
+ // this counts for the column widths, too
+ USHORT nPos;
+ for ( nPos = 0; nPos < pCols->Count(); ++nPos )
+ {
+ BrowserColumn* pCurrent = pCols->GetObject(nPos);
+
+ long nWidthLogic = PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
+ long nForeignWidthPixel = pDev->LogicToPixel(Size(nWidthLogic, 0), MAP_10TH_MM).Width();
+
+ pCurrent->SetWidth(nForeignWidthPixel, GetZoom());
+ if ( pBar )
+ pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
+ }
+
+ // a smaller area for the content
+ ++aRealPos.X();
+ ++aRealPos.Y();
+ aRealSize.Width() -= 2;
+ aRealSize.Height() -= 2;
+
+ // let the header bar draw itself
+ if ( pBar )
+ {
+ // the title height with respect to the font set for the given device
+ long nTitleHeight = PixelToLogic(Size(0, GetTitleHeight()), MAP_10TH_MM).Height();
+ nTitleHeight = pDev->LogicToPixel(Size(0, nTitleHeight), MAP_10TH_MM).Height();
+
+ BrowserColumn* pFirstCol = pCols->Count() ? pCols->GetObject(0) : NULL;
+
+ Point aHeaderPos(pFirstCol && (pFirstCol->GetId() == 0) ? pFirstCol->Width() : 0, 0);
+ Size aHeaderSize(aRealSize.Width() - aHeaderPos.X(), nTitleHeight);
+
+ aHeaderPos += aRealPos;
+ // do this before converting to logics !
+
+ // the header's draw expects logic coordinates, again
+ aHeaderPos = pDev->PixelToLogic(aHeaderPos);
+ aHeaderSize = pDev->PixelToLogic(aHeaderSize);
+
+ pBar->Draw(pDev, aHeaderPos, aHeaderSize, nFlags);
+
+ // draw the "upper left cell" (the intersection between the header bar and the handle column)
+ if (( pFirstCol->GetId() == 0 ) && ( pFirstCol->Width() > 4 ))
+ {
+ ButtonFrame aButtonFrame( aRealPos,
+ Size( pFirstCol->Width()-1, nTitleHeight-1 ),
+ pFirstCol->Title(), FALSE, FALSE, FALSE, !IsEnabled());
+ aButtonFrame.Draw( *pDev );
+
+ pDev->Push( PUSH_LINECOLOR );
+ pDev->SetLineColor( Color( COL_BLACK ) );
+
+ pDev->DrawLine( Point( aRealPos.X(), aRealPos.Y() + nTitleHeight-1 ),
+ Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
+ pDev->DrawLine( Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() ),
+ Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
+
+ pDev->Pop();
+ }
+
+ aRealPos.Y() += aHeaderSize.Height();
+ aRealSize.Height() -= aHeaderSize.Height();
+ }
+
+ // draw our own content (with clipping)
+ Region aRegion(Rectangle(aRealPos, aRealSize));
+ pDev->SetClipRegion( pDev->PixelToLogic( aRegion ) );
+
+ // do we have to paint the background
+ BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && GetDataWindow().IsControlBackground();
+ if ( bBackground )
+ {
+ Rectangle aRect( aRealPos, aRealSize );
+ pDev->SetFillColor( GetDataWindow().GetControlBackground() );
+ pDev->DrawRect( aRect );
+ }
+
+ ImplPaintData( *pDev, Rectangle( aRealPos, aRealSize ), TRUE, bDrawSelection );
+
+ // restore the column widths/data row height
+ nDataRowHeight = nOriginalHeight;
+ for ( nPos = 0; nPos < pCols->Count(); ++nPos )
+ {
+ BrowserColumn* pCurrent = pCols->GetObject(nPos);
+
+ long nForeignWidthLogic = pDev->PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
+ long nWidthPixel = LogicToPixel(Size(nForeignWidthLogic, 0), MAP_10TH_MM).Width();
+
+ pCurrent->SetWidth(nWidthPixel, GetZoom());
+ if ( pBar )
+ pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
+ }
+
+ pDev->Pop();
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, BOOL _bForeignDevice, BOOL _bDrawSelections)
+{
+ Point aOverallAreaPos = _bForeignDevice ? _rRect.TopLeft() : Point(0,0);
+ Size aOverallAreaSize = _bForeignDevice ? _rRect.GetSize() : GetDataWindow().GetOutputSizePixel();
+ Point aOverallAreaBRPos = _bForeignDevice ? _rRect.BottomRight() : Point( aOverallAreaSize.Width(), aOverallAreaSize.Height() );
+
+ long nDataRowHeigt = GetDataRowHeight();
+
+ // compute relative rows to redraw
+ ULONG nRelTopRow = _bForeignDevice ? 0 : ((ULONG)_rRect.Top() / nDataRowHeigt);
+ ULONG nRelBottomRow = (ULONG)(_bForeignDevice ? aOverallAreaSize.Height() : _rRect.Bottom()) / nDataRowHeigt;
+
+ // cache frequently used values
+ Point aPos( aOverallAreaPos.X(), nRelTopRow * nDataRowHeigt + aOverallAreaPos.Y() );
+ _rOut.SetLineColor( Color( COL_WHITE ) );
+ const AllSettings& rAllSets = _rOut.GetSettings();
+ const StyleSettings &rSettings = rAllSets.GetStyleSettings();
+ const Color &rHighlightTextColor = rSettings.GetHighlightTextColor();
+ const Color &rHighlightFillColor = rSettings.GetHighlightColor();
+ Color aOldTextColor = _rOut.GetTextColor();
+ Color aOldFillColor = _rOut.GetFillColor();
+ Color aOldLineColor = _rOut.GetLineColor();
+ long nHLineX = 0 == pCols->GetObject(0)->GetId()
+ ? pCols->GetObject(0)->Width()
+ : 0;
+ nHLineX += aOverallAreaPos.X();
+
+ Color aDelimiterLineColor( ::svtools::ColorConfig().GetColorValue( ::svtools::CALCGRID ).nColor );
+
+ // redraw the invalid fields
+ BOOL bRetouching = FALSE;
+ for ( ULONG nRelRow = nRelTopRow;
+ nRelRow <= nRelBottomRow && (ULONG)nTopRow+nRelRow < (ULONG)nRowCount;
+ ++nRelRow, aPos.Y() += nDataRowHeigt )
+ {
+ // get row
+ // Zur Sicherheit auf zul"assigen Bereich abfragen:
+ DBG_ASSERT( (USHORT)(nTopRow+nRelRow) < nRowCount, "BrowseBox::ImplPaintData: invalid seek" );
+ if ( (nTopRow+long(nRelRow)) < 0 || (USHORT)(nTopRow+nRelRow) >= nRowCount )
+ continue;
+
+ // prepare row
+ ULONG nRow = nTopRow+nRelRow;
+ if ( !SeekRow( nRow) ) {
+ DBG_ERROR("BrowseBox::ImplPaintData: SeekRow gescheitert");
+ }
+ _rOut.SetClipRegion();
+ aPos.X() = aOverallAreaPos.X();
+
+
+ // #73325# don't paint the row outside the painting rectangle (DG)
+ // prepare auto-highlight
+ Rectangle aRowRect( Point( _rRect.TopLeft().X(), aPos.Y() ),
+ Size( _rRect.GetSize().Width(), nDataRowHeigt ) );
+ PaintRow( _rOut, aRowRect );
+
+ BOOL bRowSelected = _bDrawSelections
+ && !bHideSelect
+ && IsRowSelected( nRow );
+ if ( bRowSelected )
+ {
+ _rOut.SetTextColor( rHighlightTextColor );
+ _rOut.SetFillColor( rHighlightFillColor );
+ _rOut.SetLineColor();
+ _rOut.DrawRect( aRowRect );
+ }
+
+ // iterate through columns to redraw
+ USHORT nCol;
+ for ( nCol = 0; nCol < pCols->Count(); ++nCol )
+ {
+ // get column
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+
+ // at end of invalid area
+ if ( aPos.X() >= _rRect.Right() )
+ break;
+
+ // skip invisible colums between frozen and scrollable area
+ if ( nCol < nFirstCol && !pCol->IsFrozen() )
+ {
+ nCol = nFirstCol;
+ pCol = pCols->GetObject(nCol);
+ if (!pCol)
+ { // FS - 21.05.99 - 66325
+ // ist zwar eigentlich woanders (an der richtigen Stelle) gefixt, aber sicher ist sicher ...
+ DBG_ERROR("BrowseBox::PaintData : nFirstCol is probably invalid !");
+ break;
+ }
+ }
+
+ // prepare Column-AutoHighlight
+ BOOL bColAutoHighlight = _bDrawSelections
+ && bColumnCursor
+ && IsColumnSelected( pCol->GetId() );
+ if ( bColAutoHighlight )
+ {
+ _rOut.SetClipRegion();
+ _rOut.SetTextColor( rHighlightTextColor );
+ _rOut.SetFillColor( rHighlightFillColor );
+ _rOut.SetLineColor();
+ Rectangle aFieldRect( aPos,
+ Size( pCol->Width(), nDataRowHeigt ) );
+ _rOut.DrawRect( aFieldRect );
+ }
+
+ if (!m_bFocusOnlyCursor && (pCol->GetId() == GetCurColumnId()) && (nRow == (ULONG)GetCurRow()))
+ DrawCursor();
+
+ // draw a single field
+ // #63864#, Sonst wird auch etwas gezeichnet, bsp Handle Column
+ if (pCol->Width())
+ {
+ // clip the column's output to the field area
+ if (_bForeignDevice)
+ { // (not neccessary if painting onto the data window)
+ Size aFieldSize(pCol->Width(), nDataRowHeigt);
+
+ if (aPos.X() + aFieldSize.Width() > aOverallAreaBRPos.X())
+ aFieldSize.Width() = aOverallAreaBRPos.X() - aPos.X();
+
+ if (aPos.Y() + aFieldSize.Height() > aOverallAreaBRPos.Y() + 1)
+ {
+ // for non-handle cols we don't clip vertically : we just don't draw the cell if the line isn't completely visible
+ if (pCol->GetId() != 0)
+ continue;
+ aFieldSize.Height() = aOverallAreaBRPos.Y() + 1 - aPos.Y();
+ }
+
+ Region aClipToField(Rectangle(aPos, aFieldSize));
+ _rOut.SetClipRegion(aClipToField);
+ }
+ pCol->Draw( *this, _rOut, aPos, FALSE );
+ if (_bForeignDevice)
+ _rOut.SetClipRegion();
+ }
+
+ // reset Column-auto-highlight
+ if ( bColAutoHighlight )
+ {
+ _rOut.SetTextColor( aOldTextColor );
+ _rOut.SetFillColor( aOldFillColor );
+ _rOut.SetLineColor( aOldLineColor );
+ }
+
+ // skip column
+ aPos.X() += pCol->Width();
+ }
+
+ if ( nCol == pCols->Count() )
+ bRetouching = TRUE;
+
+ // reset auto-highlight
+ if ( bRowSelected )
+ {
+ _rOut.SetTextColor( aOldTextColor );
+ _rOut.SetFillColor( aOldFillColor );
+ _rOut.SetLineColor( aOldLineColor );
+ }
+
+ if ( bHLines )
+ {
+ // draw horizontal delimitation lines
+ _rOut.SetClipRegion();
+ _rOut.Push( PUSH_LINECOLOR );
+ _rOut.SetLineColor( aDelimiterLineColor );
+ long nY = aPos.Y() + nDataRowHeigt - 1;
+ if (nY <= aOverallAreaBRPos.Y())
+ _rOut.DrawLine( Point( nHLineX, nY ),
+ Point( bVLines
+ ? std::min(long(long(aPos.X()) - 1), aOverallAreaBRPos.X())
+ : aOverallAreaBRPos.X(),
+ nY ) );
+ _rOut.Pop();
+ }
+ }
+
+ if (aPos.Y() > aOverallAreaBRPos.Y() + 1)
+ aPos.Y() = aOverallAreaBRPos.Y() + 1;
+ // needed for some of the following drawing
+
+ // retouching
+ _rOut.SetClipRegion();
+ aOldLineColor = _rOut.GetLineColor();
+ aOldFillColor = _rOut.GetFillColor();
+ _rOut.SetFillColor( rSettings.GetFaceColor() );
+ if ( pCols->Count() && ( pCols->GetObject(0)->GetId() == 0 ) && ( aPos.Y() <= _rRect.Bottom() ) )
+ {
+ // fill rectangle gray below handle column
+ // DG: fill it only until the end of the drawing rect and not to the end, as this may overpaint handle columns
+ _rOut.SetLineColor( Color( COL_BLACK ) );
+ _rOut.DrawRect( Rectangle(
+ Point( aOverallAreaPos.X() - 1, aPos.Y() - 1 ),
+ Point( aOverallAreaPos.X() + pCols->GetObject(0)->Width() - 1,
+ _rRect.Bottom() + 1) ) );
+ }
+ _rOut.SetFillColor( aOldFillColor );
+
+ // draw vertical delimitational line between frozen and scrollable cols
+ _rOut.SetLineColor( COL_BLACK );
+ long nFrozenWidth = GetFrozenWidth()-1;
+ _rOut.DrawLine( Point( aOverallAreaPos.X() + nFrozenWidth, aPos.Y() ),
+ Point( aOverallAreaPos.X() + nFrozenWidth, bHLines
+ ? aPos.Y() - 1
+ : aOverallAreaBRPos.Y() ) );
+
+ // draw vertical delimitational lines?
+ if ( bVLines )
+ {
+ _rOut.SetLineColor( aDelimiterLineColor );
+ Point aVertPos( aOverallAreaPos.X() - 1, aOverallAreaPos.Y() );
+ long nDeltaY = aOverallAreaBRPos.Y();
+ for ( USHORT nCol = 0; nCol < pCols->Count(); ++nCol )
+ {
+ // get column
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+
+ // skip invisible colums between frozen and scrollable area
+ if ( nCol < nFirstCol && !pCol->IsFrozen() )
+ {
+ nCol = nFirstCol;
+ pCol = pCols->GetObject(nCol);
+ }
+
+ // skip column
+ aVertPos.X() += pCol->Width();
+
+ // at end of invalid area
+ // invalid area is first reached when X > Right
+ // and not >=
+ if ( aVertPos.X() > _rRect.Right() )
+ break;
+
+ // draw a single line
+ if ( pCol->GetId() != 0 )
+ _rOut.DrawLine( aVertPos, Point( aVertPos.X(),
+ bHLines
+ ? aPos.Y() - 1
+ : aPos.Y() + nDeltaY ) );
+ }
+ }
+
+ _rOut.SetLineColor( aOldLineColor );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::PaintData( Window& rWin, const Rectangle& rRect )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ if ( !bBootstrapped && IsReallyVisible() )
+ BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
+
+ // initializations
+ if ( !pCols || !pCols->Count() || !rWin.IsUpdateMode() )
+ return;
+ if ( getDataWindow()->bResizeOnPaint )
+ Resize();
+ // MI: wer war das denn? Window::Update();
+
+ ImplPaintData(rWin, rRect, FALSE, TRUE);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::UpdateScrollbars()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bBootstrapped || !IsUpdateMode() )
+ return;
+
+ // Rekursionsschutz
+ BrowserDataWin *pBDW = (BrowserDataWin*) pDataWin;
+ if ( pBDW->bInUpdateScrollbars )
+ {
+ pBDW->bHadRecursion = TRUE;
+ return;
+ }
+ pBDW->bInUpdateScrollbars = TRUE;
+
+ // the size of the corner window (and the width of the VSB/height of the HSB)
+ ULONG nCornerSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if (IsZoom())
+ nCornerSize = (ULONG)(nCornerSize * (double)GetZoom());
+
+ // needs VScroll?
+ long nMaxRows = (pDataWin->GetSizePixel().Height()) / GetDataRowHeight();
+ BOOL bNeedsVScroll = getDataWindow()->bAutoVScroll
+ ? nTopRow || ( nRowCount > nMaxRows )
+ : !getDataWindow()->bNoVScroll;
+ Size aDataWinSize = pDataWin->GetSizePixel();
+ if ( !bNeedsVScroll )
+ {
+ if ( pVScroll->IsVisible() )
+ {
+ pVScroll->Hide();
+ Size aNewSize( aDataWinSize );
+ aNewSize.Width() = GetOutputSizePixel().Width();
+ aDataWinSize = aNewSize;
+ }
+ }
+ else if ( !pVScroll->IsVisible() )
+ {
+ Size aNewSize( aDataWinSize );
+ aNewSize.Width() = GetOutputSizePixel().Width() - nCornerSize;
+ aDataWinSize = aNewSize;
+ }
+
+ // needs HScroll?
+ ULONG nLastCol = GetColumnAtXPosPixel( aDataWinSize.Width() - 1 );
+
+ USHORT nFrozenCols = FrozenColCount();
+ BOOL bNeedsHScroll = getDataWindow()->bAutoHScroll
+ ? ( nFirstCol > nFrozenCols ) || ( nLastCol <= pCols->Count() )
+ : !getDataWindow()->bNoHScroll;
+ if ( !bNeedsHScroll )
+ {
+ if ( aHScroll.IsVisible() )
+ {
+ aHScroll.Hide();
+ }
+ aDataWinSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight();
+ if ( nControlAreaWidth != USHRT_MAX )
+ aDataWinSize.Height() -= nCornerSize;
+ }
+ else if ( !aHScroll.IsVisible() )
+ {
+ Size aNewSize( aDataWinSize );
+ aNewSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight() - nCornerSize;
+ aDataWinSize = aNewSize;
+ }
+
+ // adjust position and Width of horizontal scrollbar
+ ULONG nHScrX = nControlAreaWidth == USHRT_MAX
+ ? 0
+ : nControlAreaWidth;
+
+ aHScroll.SetPosSizePixel(
+ Point( nHScrX, GetOutputSizePixel().Height() - nCornerSize ),
+ Size( aDataWinSize.Width() - nHScrX, nCornerSize ) );
+
+ // Scrollable Columns insgesamt
+ short nScrollCols = short(pCols->Count()) - (short)nFrozenCols;
+ /*short nVisibleHSize= std::max(nLastCol == BROWSER_INVALIDID
+ ? pCols->Count() - nFirstCol -1
+ : nLastCol - nFirstCol - 1, 0);
+
+ aHScroll.SetVisibleSize( nVisibleHSize );
+ aHScroll.SetRange( Range( 0, Max( std::min(nScrollCols, nVisibleHSize), (short)0 ) ) );
+ if ( bNeedsHScroll && !aHScroll.IsVisible() )
+ aHScroll.Show();*/
+
+ // Sichtbare Columns
+ short nVisibleHSize = nLastCol == BROWSER_INVALIDID
+ ? (short)( pCols->Count() - nFirstCol )
+ : (short)( nLastCol - nFirstCol );
+
+ short nRange = Max( nScrollCols, (short)0 );
+ aHScroll.SetVisibleSize( nVisibleHSize );
+ aHScroll.SetRange( Range( 0, nRange ));
+ if ( bNeedsHScroll && !aHScroll.IsVisible() )
+ aHScroll.Show();
+
+ // adjust position and height of vertical scrollbar
+ pVScroll->SetPageSize( nMaxRows );
+
+ if ( nTopRow > nRowCount )
+ {
+ nTopRow = nRowCount - 1;
+ DBG_ERROR("BrowseBox: nTopRow > nRowCount");
+ }
+
+ if ( pVScroll->GetThumbPos() != nTopRow )
+ pVScroll->SetThumbPos( nTopRow );
+ long nVisibleSize = Min( Min( nRowCount, nMaxRows ), long(nRowCount-nTopRow) );
+ pVScroll->SetVisibleSize( nVisibleSize ? nVisibleSize : 1 );
+ pVScroll->SetRange( Range( 0, nRowCount ) );
+ pVScroll->SetPosSizePixel(
+ Point( aDataWinSize.Width(), GetTitleHeight() ),
+ Size( nCornerSize, aDataWinSize.Height()) );
+ if ( nRowCount <
+ long( aDataWinSize.Height() / GetDataRowHeight() ) )
+ ScrollRows( -nTopRow );
+ if ( bNeedsVScroll && !pVScroll->IsVisible() )
+ pVScroll->Show();
+
+ pDataWin->SetPosSizePixel(
+ Point( 0, GetTitleHeight() ),
+ aDataWinSize );
+
+ // needs corner-window?
+ // (do that AFTER positioning BOTH scrollbars)
+ ULONG nActualCorderWidth = 0;
+ if (aHScroll.IsVisible() && pVScroll && pVScroll->IsVisible() )
+ {
+ // if we have both scrollbars, the corner window fills the point of intersection of these two
+ nActualCorderWidth = nCornerSize;
+ }
+ else if ( !aHScroll.IsVisible() && ( nControlAreaWidth != USHRT_MAX ) )
+ {
+ // if we have no horizontal scrollbar, but a control area, we need the corner window to
+ // fill the space between the control are and the right border
+ nActualCorderWidth = GetOutputSizePixel().Width() - nControlAreaWidth;
+ }
+ if ( nActualCorderWidth )
+ {
+ if ( !getDataWindow()->pCornerWin )
+ getDataWindow()->pCornerWin = new ScrollBarBox( this, 0 );
+ getDataWindow()->pCornerWin->SetPosSizePixel(
+ Point( GetOutputSizePixel().Width() - nActualCorderWidth, aHScroll.GetPosPixel().Y() ),
+ Size( nActualCorderWidth, nCornerSize ) );
+ getDataWindow()->pCornerWin->Show();
+ }
+ else
+ DELETEZ( getDataWindow()->pCornerWin );
+
+ // ggf. Headerbar mitscrollen
+ if ( getDataWindow()->pHeaderBar )
+ {
+ long nWidth = 0;
+ for ( USHORT nCol = 0;
+ nCol < pCols->Count() && nCol < nFirstCol;
+ ++nCol )
+ {
+ // HandleColumn nicht
+ if ( pCols->GetObject(nCol)->GetId() )
+ nWidth += pCols->GetObject(nCol)->Width();
+ }
+
+ getDataWindow()->pHeaderBar->SetOffset( nWidth );
+ }
+
+ pBDW->bInUpdateScrollbars = FALSE;
+ if ( pBDW->bHadRecursion )
+ {
+ pBDW->bHadRecursion = FALSE;
+ UpdateScrollbars();
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetUpdateMode( BOOL bUpdate )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ BOOL bWasUpdate = IsUpdateMode();
+ if ( bWasUpdate == bUpdate )
+ return;
+
+ Control::SetUpdateMode( bUpdate );
+ // OV
+ // Wenn an der BrowseBox WB_CLIPCHILDREN gesetzt ist (wg. Flackerminimierung),
+ // wird das Datenfenster nicht von SetUpdateMode invalidiert.
+ if( bUpdate )
+ getDataWindow()->Invalidate();
+ getDataWindow()->SetUpdateMode( bUpdate );
+
+
+ if ( bUpdate )
+ {
+ if ( bBootstrapped )
+ {
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ }
+ DoShowCursor( "SetUpdateMode" );
+ }
+ else
+ DoHideCursor( "SetUpdateMode" );
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GetUpdateMode() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return getDataWindow()->IsUpdateMode();
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetFrozenWidth() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ long nWidth = 0;
+ for ( USHORT nCol = 0;
+ nCol < pCols->Count() && pCols->GetObject(nCol)->IsFrozen();
+ ++nCol )
+ nWidth += pCols->GetObject(nCol)->Width();
+ return nWidth;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ColumnInserted( USHORT nPos )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( pColSel )
+ pColSel->Insert( nPos );
+ UpdateScrollbars();
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::FrozenColCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ USHORT nCol;
+ for ( nCol = 0;
+ nCol < pCols->Count() && pCols->GetObject(nCol)->IsFrozen();
+ ++nCol )
+ /* empty loop */;
+ return nCol;
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK(BrowseBox,ScrollHdl,ScrollBar*,pBar)
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( pBar->GetDelta() == 0 )
+ return 0;
+
+ if ( pBar->GetDelta() < 0 && getDataWindow()->bNoScrollBack )
+ {
+ UpdateScrollbars();
+ return 0;
+ }
+
+ if ( pBar == &aHScroll )
+ ScrollColumns( aHScroll.GetDelta() );
+ if ( pBar == pVScroll )
+ ScrollRows( pVScroll->GetDelta() );
+
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( BrowseBox,EndScrollHdl,ScrollBar*, EMPTYARG )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // kein Focus grabben!
+ /// GrabFocus();
+
+ if ( /*pBar->GetDelta() <= 0 &&*/ getDataWindow()->bNoScrollBack )
+ {
+ // UpdateScrollbars();
+ EndScroll();
+ return 0;
+ }
+
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( BrowseBox, StartDragHdl, HeaderBar*, pBar )
+{
+ pBar->SetDragSize( pDataWin->GetOutputSizePixel().Height() );
+ return 0;
+}
+
+//-------------------------------------------------------------------
+// MI: es wurde immer nur die 1. Spalte resized
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+void BrowseBox::MouseButtonDown( const MouseEvent& rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ GrabFocus();
+
+ // onl< mouse events in the title-line are supported
+ const Point &rEvtPos = rEvt.GetPosPixel();
+ if ( rEvtPos.Y() >= GetTitleHeight() )
+ return;
+
+ long nX = 0;
+ long nWidth = GetOutputSizePixel().Width();
+ for ( USHORT nCol = 0; nCol < pCols->Count() && nX < nWidth; ++nCol )
+ {
+ // is this column visible?
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+ if ( pCol->IsFrozen() || nCol >= nFirstCol )
+ {
+ // compute right end of column
+ long nR = nX + pCol->Width() - 1;
+
+ // at the end of a column (and not handle column)?
+ if ( pCol->GetId() && Abs( nR - rEvtPos.X() ) < 2 )
+ {
+ // start resizing the column
+ bResizing = TRUE;
+ nResizeCol = nCol;
+ nDragX = nResizeX = rEvtPos.X();
+ SetPointer( Pointer( POINTER_HSPLIT ) );
+ CaptureMouse();
+ pDataWin->DrawLine( Point( nDragX, 0 ),
+ Point( nDragX, pDataWin->GetSizePixel().Height() ) );
+ nMinResizeX = nX + MIN_COLUMNWIDTH;
+ return;
+ }
+ else if ( nX < rEvtPos.X() && nR > rEvtPos.X() )
+ {
+ MouseButtonDown( BrowserMouseEvent(
+ this, rEvt, -1, nCol, pCol->GetId(), Rectangle() ) );
+ return;
+ }
+ nX = nR + 1;
+ }
+ }
+
+ // event occured out of data area
+ if ( rEvt.IsRight() )
+ pDataWin->Command(
+ CommandEvent( Point( 1, LONG_MAX ), COMMAND_CONTEXTMENU, TRUE ) );
+ else
+ SetNoSelection();
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",on)
+#endif
+
+//-------------------------------------------------------------------
+
+void BrowseBox::MouseMove( const MouseEvent& rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_TRACE( "BrowseBox::MouseMove( MouseEvent )" );
+
+ Pointer aNewPointer;
+
+ USHORT nX = 0;
+ for ( USHORT nCol = 0;
+ nCol < USHORT(pCols->Count()) &&
+ ( nX + pCols->GetObject(nCol)->Width() ) < USHORT(GetOutputSizePixel().Width());
+ ++nCol )
+ // is this column visible?
+ if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol )
+ {
+ // compute right end of column
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+ USHORT nR = (USHORT)(nX + pCol->Width() - 1);
+
+ // show resize-pointer?
+ if ( bResizing || ( pCol->GetId() &&
+ Abs( ((long) nR ) - rEvt.GetPosPixel().X() ) < MIN_COLUMNWIDTH ) )
+ {
+ aNewPointer = Pointer( POINTER_HSPLIT );
+ if ( bResizing )
+ {
+ // alte Hilfslinie loeschen
+ pDataWin->HideTracking() ;
+
+ // erlaubte breite abholen und neues Delta
+ nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX );
+ long nDeltaX = nDragX - nResizeX;
+ USHORT nId = GetColumnId(nResizeCol);
+ ULONG nOldWidth = GetColumnWidth(nId);
+ nDragX = QueryColumnResize( GetColumnId(nResizeCol),
+ nOldWidth + nDeltaX )
+ + nResizeX - nOldWidth;
+
+ // neue Hilfslinie zeichnen
+ pDataWin->ShowTracking( Rectangle( Point( nDragX, 0 ),
+ Size( 1, pDataWin->GetSizePixel().Height() ) ),
+ SHOWTRACK_SPLIT|SHOWTRACK_WINDOW );
+ }
+
+ }
+
+ nX = nR + 1;
+ }
+
+ SetPointer( aNewPointer );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::MouseButtonUp( const MouseEvent & rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( bResizing )
+ {
+ // Hilfslinie loeschen
+ pDataWin->HideTracking();
+
+ // width changed?
+ nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX );
+ if ( (nDragX - nResizeX) != (long)pCols->GetObject(nResizeCol)->Width() )
+ {
+ // resize column
+ long nMaxX = pDataWin->GetSizePixel().Width();
+ nDragX = Min( nDragX, nMaxX );
+ long nDeltaX = nDragX - nResizeX;
+ USHORT nId = GetColumnId(nResizeCol);
+ SetColumnWidth( GetColumnId(nResizeCol), GetColumnWidth(nId) + nDeltaX );
+ ColumnResized( nId );
+ }
+
+ // end action
+ SetPointer( Pointer() );
+ ReleaseMouse();
+ bResizing = FALSE;
+ }
+ else
+ MouseButtonUp( BrowserMouseEvent( (BrowserDataWin*)pDataWin,
+ MouseEvent( Point( rEvt.GetPosPixel().X(),
+ rEvt.GetPosPixel().Y() - pDataWin->GetPosPixel().Y() ),
+ rEvt.GetClicks(), rEvt.GetMode(), rEvt.GetButtons(),
+ rEvt.GetModifier() ) ) );
+}
+
+//-------------------------------------------------------------------
+
+BOOL bExtendedMode = FALSE;
+BOOL bFieldMode = FALSE;
+
+void BrowseBox::MouseButtonDown( const BrowserMouseEvent& rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ GrabFocus();
+
+ // adjust selection while and after double-click
+ if ( rEvt.GetClicks() == 2 )
+ {
+ SetNoSelection();
+ if ( rEvt.GetRow() >= 0 )
+ {
+ GoToRow( rEvt.GetRow() );
+ SelectRow( rEvt.GetRow(), TRUE, FALSE );
+ }
+ else
+ {
+ if ( bColumnCursor && rEvt.GetColumn() != 0 )
+ {
+ if ( rEvt.GetColumn() < pCols->Count() )
+ SelectColumnPos( rEvt.GetColumn(), TRUE, FALSE);
+ }
+ }
+ DoubleClick( rEvt );
+ }
+ // selections
+ else if ( ( rEvt.GetMode() & ( MOUSE_SELECT | MOUSE_SIMPLECLICK ) ) &&
+ ( bColumnCursor || rEvt.GetRow() >= 0 ) )
+ {
+ if ( rEvt.GetClicks() == 1 )
+ {
+ // initialise flags
+ bHit = FALSE;
+ a1stPoint =
+ a2ndPoint = PixelToLogic( rEvt.GetPosPixel() );
+
+ // selection out of range?
+ if ( rEvt.GetRow() >= nRowCount ||
+ rEvt.GetColumnId() == BROWSER_INVALIDID )
+ {
+ SetNoSelection();
+ return;
+ }
+
+ // while selecting, no cursor
+ bSelecting = TRUE;
+ DoHideCursor( "MouseButtonDown" );
+
+ // DataRow?
+ if ( rEvt.GetRow() >= 0 )
+ {
+ // Zeilenselektion?
+ if ( rEvt.GetColumnId() == 0 || !bColumnCursor )
+ {
+ if ( bMultiSelection )
+ {
+ // remove column-selection, if exists
+ if ( pColSel && pColSel->GetSelectCount() )
+ {
+ ToggleSelection();
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ bSelect = TRUE;
+ }
+
+ // expanding mode?
+ if ( rEvt.GetMode() & MOUSE_RANGESELECT )
+ {
+ // select the further touched rows too
+ bSelect = TRUE;
+ ExpandRowSelection( rEvt );
+ return;
+ }
+
+ // click in the selected area?
+ else if ( IsRowSelected( rEvt.GetRow() ) )
+ {
+ // auf Drag&Drop warten
+ bHit = TRUE;
+ bExtendedMode = MOUSE_MULTISELECT ==
+ ( rEvt.GetMode() & MOUSE_MULTISELECT );
+ return;
+ }
+
+ // extension mode?
+ else if ( rEvt.GetMode() & MOUSE_MULTISELECT )
+ {
+ // determine the new selection range
+ // and selection/deselection
+ aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
+ SelectRow( rEvt.GetRow(),
+ !uRow.pSel->IsSelected( rEvt.GetRow() ) );
+ bSelect = TRUE;
+ return;
+ }
+ }
+
+ // select directly
+ SetNoSelection();
+ GoToRow( rEvt.GetRow() );
+ SelectRow( rEvt.GetRow(), TRUE );
+ aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
+ bSelect = TRUE;
+ }
+ else // Column/Field-Selection
+ {
+ // click in selected column
+ if ( IsColumnSelected( rEvt.GetColumn() ) ||
+ IsRowSelected( rEvt.GetRow() ) )
+ {
+ bHit = TRUE;
+ bFieldMode = TRUE;
+ return;
+ }
+
+ SetNoSelection();
+ GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
+ bSelect = TRUE;
+ }
+ }
+ else
+ {
+ if ( bMultiSelection && rEvt.GetColumnId() == 0 )
+ {
+ // toggle all-selection
+ if ( uRow.pSel->GetSelectCount() > ( GetRowCount() / 2 ) )
+ SetNoSelection();
+ else
+ SelectAll();
+ }
+ else
+ SelectColumnId( rEvt.GetColumnId(), TRUE, FALSE );
+ }
+
+ // ggf. Cursor wieder an
+ bSelecting = FALSE;
+ DoShowCursor( "MouseButtonDown" );
+ if ( bSelect )
+ Select();
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::MouseMove( const BrowserMouseEvent& )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::MouseButtonUp( const BrowserMouseEvent &rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // D&D was possible, but did not occur
+ if ( bHit )
+ {
+ aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
+ if ( bExtendedMode )
+ SelectRow( rEvt.GetRow(), FALSE );
+ else
+ {
+ SetNoSelection();
+ if ( bFieldMode )
+ GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
+ else
+ {
+ GoToRow( rEvt.GetRow() );
+ SelectRow( rEvt.GetRow(), TRUE );
+ }
+ }
+ bSelect = TRUE;
+ bExtendedMode = FALSE;
+ bFieldMode = FALSE;
+ bHit = FALSE;
+ }
+
+ // activate cursor
+ if ( bSelecting )
+ {
+ bSelecting = FALSE;
+ DoShowCursor( "MouseButtonUp" );
+ if ( bSelect )
+ Select();
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::KeyInput( const KeyEvent& rEvt )
+{
+ if ( !ProcessKey( rEvt ) )
+ Control::KeyInput( rEvt );
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::ProcessKey( const KeyEvent& rEvt )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ USHORT nCode = rEvt.GetKeyCode().GetCode();
+ BOOL bShift = rEvt.GetKeyCode().IsShift();
+ BOOL bCtrl = rEvt.GetKeyCode().IsMod1();
+ BOOL bAlt = rEvt.GetKeyCode().IsMod2();
+
+ USHORT nId = BROWSER_NONE;
+
+ if ( !bAlt && !bCtrl && !bShift )
+ {
+ switch ( nCode )
+ {
+ case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
+ case KEY_UP: nId = BROWSER_CURSORUP; break;
+ case KEY_HOME: nId = BROWSER_CURSORHOME; break;
+ case KEY_END: nId = BROWSER_CURSOREND; break;
+ case KEY_TAB:
+ if ( !bColumnCursor )
+ break;
+ case KEY_RIGHT: nId = BROWSER_CURSORRIGHT; break;
+ case KEY_LEFT: nId = BROWSER_CURSORLEFT; break;
+ case KEY_SPACE: nId = BROWSER_SELECT; break;
+ }
+ if ( BROWSER_NONE != nId )
+ SetNoSelection();
+
+ switch ( nCode )
+ {
+ case KEY_PAGEDOWN: nId = BROWSER_CURSORPAGEDOWN; break;
+ case KEY_PAGEUP: nId = BROWSER_CURSORPAGEUP; break;
+ }
+ }
+
+ if ( !bAlt && !bCtrl && bShift )
+ switch ( nCode )
+ {
+ case KEY_DOWN: nId = BROWSER_SELECTDOWN; break;
+ case KEY_UP: nId = BROWSER_SELECTUP; break;
+ case KEY_TAB:
+ if ( !bColumnCursor )
+ break;
+ nId = BROWSER_CURSORLEFT; break;
+ case KEY_HOME: nId = BROWSER_SELECTHOME; break;
+ case KEY_END: nId = BROWSER_SELECTEND; break;
+ }
+
+
+ if ( !bAlt && bCtrl && !bShift )
+ switch ( nCode )
+ {
+ case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
+ case KEY_UP: nId = BROWSER_CURSORUP; break;
+ case KEY_PAGEDOWN: nId = BROWSER_CURSORENDOFFILE; break;
+ case KEY_PAGEUP: nId = BROWSER_CURSORTOPOFFILE; break;
+ case KEY_HOME: nId = BROWSER_CURSORTOPOFSCREEN; break;
+ case KEY_END: nId = BROWSER_CURSORENDOFSCREEN; break;
+ case KEY_SPACE: nId = BROWSER_ENHANCESELECTION; break;
+ case KEY_LEFT: nId = BROWSER_MOVECOLUMNLEFT; break;
+ case KEY_RIGHT: nId = BROWSER_MOVECOLUMNRIGHT; break;
+ }
+
+ if ( nId != BROWSER_NONE )
+ Dispatch( nId );
+ return nId != BROWSER_NONE;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::Dispatch( USHORT nId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ long nRowsOnPage = pDataWin->GetSizePixel().Height() / GetDataRowHeight();
+ BOOL bDone = FALSE;
+
+ switch ( nId )
+ {
+ case BROWSER_SELECTCOLUMN:
+ if ( ColCount() )
+ SelectColumnId( GetCurColumnId() );
+ break;
+
+ case BROWSER_CURSORDOWN:
+ if ( ( GetCurRow() + 1 ) < nRowCount )
+ bDone = GoToRow( GetCurRow() + 1, FALSE );
+ break;
+ case BROWSER_CURSORUP:
+ if ( GetCurRow() > 0 )
+ bDone = GoToRow( GetCurRow() - 1, FALSE );
+ break;
+ case BROWSER_SELECTHOME:
+ if ( GetRowCount() )
+ {
+ DoHideCursor( "BROWSER_SELECTHOME" );
+ for ( long nRow = GetCurRow(); nRow >= 0; --nRow )
+ SelectRow( nRow );
+ GoToRow( 0, TRUE );
+ DoShowCursor( "BROWSER_SELECTHOME" );
+ }
+ break;
+ case BROWSER_SELECTEND:
+ if ( GetRowCount() )
+ {
+ DoHideCursor( "BROWSER_SELECTEND" );
+ long nRows = GetRowCount();
+ for ( long nRow = GetCurRow(); nRow < nRows; ++nRow )
+ SelectRow( nRow );
+ GoToRow( GetRowCount() - 1, TRUE );
+ DoShowCursor( "BROWSER_SELECTEND" );
+ }
+ break;
+ case BROWSER_SELECTDOWN:
+ {
+ if ( GetRowCount() && ( GetCurRow() + 1 ) < nRowCount )
+ {
+ // deselect the current row, if it isn't the first
+ // and there is no other selected row above
+ long nRow = GetCurRow();
+ BOOL bLocalSelect = ( !IsRowSelected( nRow ) ||
+ GetSelectRowCount() == 1 || IsRowSelected( nRow - 1 ) );
+ SelectRow( nRow, bLocalSelect, TRUE );
+ bDone = GoToRow( GetCurRow() + 1 , FALSE );
+ if ( bDone )
+ SelectRow( GetCurRow(), TRUE, TRUE );
+ }
+ else
+ bDone = ScrollRows( 1 ) != 0;
+ break;
+ }
+ case BROWSER_SELECTUP:
+ if ( GetRowCount() )
+ {
+ // deselect the current row, if it isn't the first
+ // and there is no other selected row under
+ long nRow = GetCurRow();
+ BOOL bLocalSelect = ( !IsRowSelected( nRow ) ||
+ GetSelectRowCount() == 1 || IsRowSelected( nRow + 1 ) );
+ SelectRow( nCurRow, bLocalSelect, TRUE );
+ bDone = GoToRow( nRow - 1 , FALSE );
+ if ( bDone )
+ SelectRow( GetCurRow(), TRUE, TRUE );
+ }
+ break;
+ case BROWSER_CURSORPAGEDOWN:
+ bDone = (BOOL)ScrollRows( nRowsOnPage );
+ break;
+ case BROWSER_CURSORPAGEUP:
+ bDone = (BOOL)ScrollRows( -nRowsOnPage );
+ break;
+ case BROWSER_CURSOREND:
+ if ( bColumnCursor )
+ {
+ USHORT nNewId = GetColumnId(ColCount() -1);
+ bDone = (nNewId != 0) && GoToColumnId( nNewId );
+ break;
+ }
+ case BROWSER_CURSORENDOFFILE:
+ bDone = GoToRow( nRowCount - 1, FALSE );
+ break;
+ case BROWSER_CURSORRIGHT:
+ if ( bColumnCursor )
+ {
+ USHORT nNewPos = GetColumnPos( GetCurColumnId() ) + 1;
+ USHORT nNewId = GetColumnId( nNewPos );
+ if (nNewId != 0) // Am Zeilenende ?
+ bDone = GoToColumnId( nNewId );
+ else
+ {
+ USHORT nColId = ( GetColumnId(0) == 0 ) ? GetColumnId(1) : GetColumnId(0);
+ if ( GetRowCount() )
+ bDone = ( nCurRow < GetRowCount() - 1 ) && GoToRowColumnId( nCurRow + 1, nColId );
+ else if ( ColCount() )
+ GoToColumnId( nColId );
+ }
+ }
+ else
+ bDone = ScrollColumns( 1 ) != 0;
+ break;
+ case BROWSER_CURSORHOME:
+ if ( bColumnCursor )
+ {
+ USHORT nNewId = GetColumnId(1);
+ bDone = (nNewId != 0) && GoToColumnId( nNewId );
+ break;
+ }
+ case BROWSER_CURSORTOPOFFILE:
+ bDone = GoToRow( 0, FALSE );
+ break;
+ case BROWSER_CURSORLEFT:
+ if ( bColumnCursor )
+ {
+ USHORT nNewPos = GetColumnPos( GetCurColumnId() ) - 1;
+ USHORT nNewId = GetColumnId( nNewPos );
+ if (nNewId != 0)
+ bDone = GoToColumnId( nNewId );
+ else
+ {
+ if ( GetRowCount() )
+ bDone = (nCurRow > 0) && GoToRowColumnId(nCurRow - 1, GetColumnId(ColCount() -1));
+ else if ( ColCount() )
+ GoToColumnId( GetColumnId(ColCount() -1) );
+ }
+ }
+ else
+ bDone = ScrollColumns( -1 ) != 0;
+ break;
+ case BROWSER_ENHANCESELECTION:
+ if ( GetRowCount() )
+ SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), TRUE );
+ bDone = TRUE;
+ break;
+ case BROWSER_SELECT:
+ if ( GetRowCount() )
+ SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), FALSE );
+ bDone = TRUE;
+ break;
+ case BROWSER_MOVECOLUMNLEFT:
+ case BROWSER_MOVECOLUMNRIGHT:
+ { // check if column moving is allowed
+ BrowserHeader* pHeaderBar = getDataWindow()->pHeaderBar;
+ if ( pHeaderBar && pHeaderBar->IsDragable() )
+ {
+ USHORT nColId = GetCurColumnId();
+ BOOL bColumnSelected = IsColumnSelected(nColId);
+ USHORT nNewPos = GetColumnPos(nColId);
+ BOOL bMoveAllowed = FALSE;
+ if ( BROWSER_MOVECOLUMNLEFT == nId && nNewPos > 1 )
+ --nNewPos,bMoveAllowed = TRUE;
+ else if ( BROWSER_MOVECOLUMNRIGHT == nId && nNewPos < (ColCount()-1) )
+ ++nNewPos,bMoveAllowed = TRUE;
+
+ if ( bMoveAllowed )
+ {
+ SetColumnPos( nColId, nNewPos );
+ ColumnMoved( nColId );
+ MakeFieldVisible(GetCurRow(),nColId,TRUE);
+ if ( bColumnSelected )
+ SelectColumnId(nColId);
+ }
+ }
+ }
+ break;
+ }
+
+ //! return bDone;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetCursorColor(const Color& _rCol)
+{
+ if (_rCol == m_aCursorColor)
+ return;
+
+ // ensure the cursor is hidden
+ DoHideCursor("SetCursorColor");
+ if (!m_bFocusOnlyCursor)
+ DoHideCursor("SetCursorColor - force");
+
+ m_aCursorColor = _rCol;
+
+ if (!m_bFocusOnlyCursor)
+ DoShowCursor("SetCursorColor - force");
+ DoShowCursor("SetCursorColor");
+}
+// -----------------------------------------------------------------------------
+Rectangle BrowseBox::calcHeaderRect(sal_Bool _bIsColumnBar,BOOL _bOnScreen)
+{
+ Window* pParent = NULL;
+ if ( !_bOnScreen )
+ pParent = GetAccessibleParentWindow();
+
+ Point aTopLeft;
+ long nWidth;
+ long nHeight;
+ if ( _bIsColumnBar )
+ {
+ nWidth = GetDataWindow().GetOutputSizePixel().Width();
+ nHeight = GetDataRowHeight();
+ }
+ else
+ {
+ aTopLeft.Y() = GetDataRowHeight();
+ nWidth = GetColumnWidth(0);
+ nHeight = GetWindowExtentsRelative( pParent ).GetHeight() - aTopLeft.Y() - GetControlArea().GetSize().B();
+ }
+ aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
+ return Rectangle(aTopLeft,Size(nWidth,nHeight));
+}
+// -----------------------------------------------------------------------------
+Rectangle BrowseBox::calcTableRect(BOOL _bOnScreen)
+{
+ Window* pParent = NULL;
+ if ( !_bOnScreen )
+ pParent = GetAccessibleParentWindow();
+
+ Rectangle aRect( GetWindowExtentsRelative( pParent ) );
+ Rectangle aRowBar = calcHeaderRect(FALSE,pParent == NULL);
+
+ long nX = aRowBar.Right() - aRect.Left();
+ long nY = aRowBar.Top() - aRect.Top();
+ Size aSize(aRect.GetSize());
+
+ return Rectangle(aRowBar.TopRight(), Size(aSize.A() - nX, aSize.B() - nY - aHScroll.GetSizePixel().Height()) );
+}
+// -----------------------------------------------------------------------------
+Rectangle BrowseBox::GetFieldRectPixelAbs( sal_Int32 _nRowId,sal_uInt16 _nColId, BOOL /*_bIsHeader*/, BOOL _bOnScreen )
+{
+ Window* pParent = NULL;
+ if ( !_bOnScreen )
+ pParent = GetAccessibleParentWindow();
+
+ Rectangle aRect = GetFieldRectPixel(_nRowId,_nColId,_bOnScreen);
+
+ Point aTopLeft = aRect.TopLeft();
+ aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
+
+ return Rectangle(aTopLeft,aRect.GetSize());
+}
+
+// ------------------------------------------------------------------------- EOF
+
diff --git a/svtools/source/brwbox/brwbox3.cxx b/svtools/source/brwbox/brwbox3.cxx
new file mode 100644
index 000000000000..102af1b6e1a1
--- /dev/null
+++ b/svtools/source/brwbox/brwbox3.cxx
@@ -0,0 +1,568 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/brwbox.hxx>
+#include <svtools/AccessibleBrowseBoxObjType.hxx>
+#include <tools/debug.hxx>
+#include <tools/multisel.hxx>
+#include "datwin.hxx"
+#include "brwimpl.hxx"
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+
+// Accessibility ==============================================================
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using ::com::sun::star::accessibility::XAccessible;
+using namespace ::com::sun::star::accessibility;
+
+// ============================================================================
+namespace svt
+{
+ using namespace ::com::sun::star::lang;
+ using namespace utl;
+
+ Reference< XAccessible > getHeaderCell( BrowseBoxImpl::THeaderCellMap& _raHeaderCells,
+ sal_Int32 _nPos,
+ AccessibleBrowseBoxObjType _eType,
+ const Reference< XAccessible >& _rParent,
+ BrowseBox& _rBrowseBox,
+ IAccessibleFactory& rFactory
+ )
+ {
+ Reference< XAccessible > xRet;
+ BrowseBoxImpl::THeaderCellMap::iterator aFind = _raHeaderCells.find( _nPos );
+ if ( aFind == _raHeaderCells.end() )
+ {
+ Reference< XAccessible > xAccessible = rFactory.createAccessibleBrowseBoxHeaderCell(
+ _nPos,
+ _rParent,
+ _rBrowseBox,
+ NULL,
+ _eType
+ );
+ aFind = _raHeaderCells.insert( BrowseBoxImpl::THeaderCellMap::value_type( _nPos, xAccessible ) ).first;
+ }
+ if ( aFind != _raHeaderCells.end() )
+ xRet = aFind->second;
+ return xRet;
+ }
+
+ // ============================================================================
+ // ----------------------------------------------------------------------------
+ Reference< XAccessible > BrowseBoxImpl::getAccessibleHeaderBar( AccessibleBrowseBoxObjType _eObjType )
+ {
+ if ( m_pAccessible && m_pAccessible->isAlive() )
+ return m_pAccessible->getHeaderBar( _eObjType );
+ return NULL;
+ }
+
+ // ----------------------------------------------------------------------------
+ Reference< XAccessible > BrowseBoxImpl::getAccessibleTable( )
+ {
+ if ( m_pAccessible && m_pAccessible->isAlive() )
+ return m_pAccessible->getTable( );
+ return NULL;
+ }
+}
+
+// ============================================================================
+
+Reference< XAccessible > BrowseBox::CreateAccessible()
+{
+ Window* pParent = GetAccessibleParentWindow();
+ DBG_ASSERT( pParent, "BrowseBox::CreateAccessible - parent not found" );
+
+ if( pParent && !m_pImpl->m_pAccessible)
+ {
+ Reference< XAccessible > xAccParent = pParent->GetAccessible();
+ if( xAccParent.is() )
+ {
+ m_pImpl->m_pAccessible = getAccessibleFactory().createAccessibleBrowseBox(
+ xAccParent, *this
+ );
+ }
+ }
+
+ Reference< XAccessible > xAccessible;
+ if ( m_pImpl->m_pAccessible )
+ xAccessible = m_pImpl->m_pAccessible->getMyself();
+
+ return xAccessible;
+}
+// -----------------------------------------------------------------------------
+
+// Children -------------------------------------------------------------------
+
+Reference< XAccessible > BrowseBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
+{
+ // BBINDEX_TABLE must be the table
+ OSL_ENSURE(m_pImpl->m_pAccessible,"Invalid call: Accessible is null");
+
+ return m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxTableCell(
+ m_pImpl->getAccessibleTable(),
+ *this,
+ NULL,
+ _nRow,
+ _nColumnPos,
+ OFFSET_DEFAULT
+ );
+}
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > BrowseBox::CreateAccessibleRowHeader( sal_Int32 _nRow )
+{
+ return svt::getHeaderCell(
+ m_pImpl->m_aRowHeaderCellMap,
+ _nRow,
+ svt::BBTYPE_ROWHEADERCELL,
+ m_pImpl->getAccessibleHeaderBar(svt::BBTYPE_ROWHEADERBAR),
+ *this,
+ m_pImpl->m_aFactoryAccess.getFactory()
+ );
+}
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > BrowseBox::CreateAccessibleColumnHeader( sal_uInt16 _nColumnPos )
+{
+ return svt::getHeaderCell(
+ m_pImpl->m_aColHeaderCellMap,
+ _nColumnPos,
+ svt::BBTYPE_COLUMNHEADERCELL,
+ m_pImpl->getAccessibleHeaderBar(svt::BBTYPE_COLUMNHEADERBAR),
+ *this,
+ m_pImpl->m_aFactoryAccess.getFactory()
+ );
+}
+// -----------------------------------------------------------------------------
+
+sal_Int32 BrowseBox::GetAccessibleControlCount() const
+{
+ return 0;
+}
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > BrowseBox::CreateAccessibleControl( sal_Int32 )
+{
+ DBG_ASSERT( FALSE, "BrowseBox::CreateAccessibleControl: to be overwritten!" );
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+
+// Conversions ----------------------------------------------------------------
+
+sal_Bool BrowseBox::ConvertPointToCellAddress(
+ sal_Int32& rnRow, sal_uInt16& rnColumnPos, const Point& rPoint )
+{
+ //! TODO has to be checked
+ rnRow = GetRowAtYPosPixel(rPoint.Y());
+ rnColumnPos = GetColumnAtXPosPixel(rPoint.X());
+ return rnRow != BROWSER_INVALIDID && rnColumnPos != BROWSER_INVALIDID;
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool BrowseBox::ConvertPointToRowHeader( sal_Int32& rnRow, const Point& rPoint )
+{
+ rnRow = GetRowAtYPosPixel(rPoint.Y());
+ // USHORT nColumnId = GetColumnAtXPosPixel(rPoint.X());
+ return rnRow != BROWSER_INVALIDID;// && nColumnId == 0;
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool BrowseBox::ConvertPointToColumnHeader( sal_uInt16& _rnColumnPos, const Point& _rPoint )
+{
+ _rnColumnPos = GetColumnAtXPosPixel(_rPoint.X());
+ return _rnColumnPos != BROWSER_INVALIDID;
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool BrowseBox::ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint )
+{
+ //! TODO has to be checked
+ sal_Int32 nRow = 0;
+ sal_uInt16 nColumn = 0;
+ sal_Bool bRet = ConvertPointToCellAddress(nRow,nColumn,_rPoint);
+ if ( bRet )
+ _rnIndex = nRow * ColCount() + nColumn;
+
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+
+// Object data and state ------------------------------------------------------
+
+OUString BrowseBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType eObjType,sal_Int32 ) const
+{
+ OUString aRetText;
+ switch( eObjType )
+ {
+ case ::svt::BBTYPE_BROWSEBOX:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "BrowseBox" ) );
+ break;
+ case ::svt::BBTYPE_TABLE:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "Table" ) );
+ break;
+ case ::svt::BBTYPE_ROWHEADERBAR:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderBar" ) );
+ break;
+ case ::svt::BBTYPE_COLUMNHEADERBAR:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) );
+ break;
+ case ::svt::BBTYPE_TABLECELL:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "TableCell" ) );
+#if OSL_DEBUG_LEVEL > 1
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( " [" ) );
+ aRetText += OUString::valueOf(sal_Int32(GetCurRow()));
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) );
+ aRetText += OUString::valueOf(sal_Int32(GetCurColumnId()));
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( "]" ) );
+#endif
+ break;
+ case ::svt::BBTYPE_ROWHEADERCELL:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderCell" ) );
+#if OSL_DEBUG_LEVEL > 1
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( " [" ) );
+ aRetText += OUString::valueOf(sal_Int32(GetCurRow()));
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) );
+ aRetText += OUString::valueOf(sal_Int32(GetCurColumnId()));
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( "]" ) );
+#endif
+ break;
+ case ::svt::BBTYPE_COLUMNHEADERCELL:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderCell" ) );
+#if OSL_DEBUG_LEVEL > 1
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( " [" ) );
+ aRetText += OUString::valueOf(sal_Int32(GetCurRow()));
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) );
+ aRetText += OUString::valueOf(sal_Int32(GetCurColumnId()));
+ aRetText += OUString( RTL_CONSTASCII_USTRINGPARAM( "]" ) );
+#endif
+ break;
+ default:
+ OSL_ENSURE(0,"BrowseBox::GetAccessibleName: invalid enum!");
+ }
+ return aRetText;
+}
+// -----------------------------------------------------------------------------
+
+OUString BrowseBox::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType eObjType,sal_Int32 ) const
+{
+ OUString aRetText;
+ switch( eObjType )
+ {
+ case ::svt::BBTYPE_BROWSEBOX:
+ aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "BrowseBox description" ) );
+ break;
+ case ::svt::BBTYPE_TABLE:
+ // aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLE description" ) );
+ break;
+ case ::svt::BBTYPE_ROWHEADERBAR:
+ // aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERBAR description" ) );
+ break;
+ case ::svt::BBTYPE_COLUMNHEADERBAR:
+ // aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERBAR description" ) );
+ break;
+ case ::svt::BBTYPE_TABLECELL:
+ // aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLECELL description" ) );
+ break;
+ case ::svt::BBTYPE_ROWHEADERCELL:
+ // aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERCELL description" ) );
+ break;
+ case ::svt::BBTYPE_COLUMNHEADERCELL:
+ // aRetText = OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERCELL description" ) );
+ break;
+ case ::svt::BBTYPE_CHECKBOXCELL:
+ break;
+ }
+ return aRetText;
+}
+// -----------------------------------------------------------------------------
+
+OUString BrowseBox::GetRowDescription( sal_Int32 ) const
+{
+ return OUString();
+}
+// -----------------------------------------------------------------------------
+
+OUString BrowseBox::GetColumnDescription( sal_uInt16 _nColumn ) const
+{
+ return OUString( GetColumnTitle( GetColumnId( _nColumn ) ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void BrowseBox::FillAccessibleStateSet(
+ ::utl::AccessibleStateSetHelper& rStateSet,
+ ::svt::AccessibleBrowseBoxObjType eObjType ) const
+{
+ switch( eObjType )
+ {
+ case ::svt::BBTYPE_BROWSEBOX:
+ case ::svt::BBTYPE_TABLE:
+
+ rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ if ( HasFocus() )
+ rStateSet.AddState( AccessibleStateType::FOCUSED );
+ if ( IsActive() )
+ rStateSet.AddState( AccessibleStateType::ACTIVE );
+ if ( GetUpdateMode() )
+ rStateSet.AddState( AccessibleStateType::EDITABLE );
+ if ( IsEnabled() )
+ {
+ rStateSet.AddState( AccessibleStateType::ENABLED );
+ rStateSet.AddState( AccessibleStateType::SENSITIVE );
+ }
+ if ( IsReallyVisible() )
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( eObjType == ::svt::BBTYPE_TABLE )
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+
+ break;
+ case ::svt::BBTYPE_ROWHEADERBAR:
+ rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( GetSelectRowCount() )
+ rStateSet.AddState( AccessibleStateType::FOCUSED );
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ break;
+ case ::svt::BBTYPE_COLUMNHEADERBAR:
+ rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( GetSelectColumnCount() )
+ rStateSet.AddState( AccessibleStateType::FOCUSED );
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ break;
+ case ::svt::BBTYPE_TABLECELL:
+ {
+ sal_Int32 nRow = GetCurRow();
+ sal_uInt16 nColumn = GetCurColumnId();
+ if ( IsFieldVisible(nRow,nColumn) )
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( !IsFrozen( nColumn ) )
+ rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ rStateSet.AddState( AccessibleStateType::TRANSIENT );
+ }
+ break;
+ case ::svt::BBTYPE_ROWHEADERCELL:
+ case ::svt::BBTYPE_COLUMNHEADERCELL:
+ case ::svt::BBTYPE_CHECKBOXCELL:
+ OSL_ENSURE(0,"Illegal call here!");
+ break;
+ }
+}
+// -----------------------------------------------------------------------
+void BrowseBox::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet,
+ sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const
+{
+ //! TODO check if the state is valid for table cells
+ if ( IsCellVisible( _nRow, _nColumnPos ) )
+ _rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( GetCurrRow() == _nRow && GetCurrColumn() == _nColumnPos )
+ _rStateSet.AddState( AccessibleStateType::FOCUSED );
+ else // only transient when column is not focused
+ _rStateSet.AddState( AccessibleStateType::TRANSIENT );
+}
+// -----------------------------------------------------------------------------
+
+void BrowseBox::GrabTableFocus()
+{
+ GrabFocus();
+}
+// -----------------------------------------------------------------------------
+String BrowseBox::GetCellText(long, USHORT ) const
+{
+ DBG_ASSERT(0,"This method has to be implemented by the derived classes! BUG!!");
+ return String();
+}
+
+// -----------------------------------------------------------------------------
+void BrowseBox::commitHeaderBarEvent(sal_Int16 nEventId,
+ const Any& rNewValue, const Any& rOldValue, sal_Bool _bColumnHeaderBar )
+{
+ if ( isAccessibleAlive() )
+ m_pImpl->m_pAccessible->commitHeaderBarEvent( nEventId,
+ rNewValue, rOldValue, _bColumnHeaderBar );
+}
+
+// -----------------------------------------------------------------------------
+void BrowseBox::commitTableEvent( sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
+{
+ if ( isAccessibleAlive() )
+ m_pImpl->m_pAccessible->commitTableEvent( _nEventId, _rNewValue, _rOldValue );
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::commitBrowseBoxEvent( sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
+{
+ if ( isAccessibleAlive() )
+ m_pImpl->m_pAccessible->commitEvent( _nEventId, _rNewValue, _rOldValue);
+}
+
+// -----------------------------------------------------------------------------
+::svt::IAccessibleFactory& BrowseBox::getAccessibleFactory()
+{
+ return m_pImpl->m_aFactoryAccess.getFactory();
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool BrowseBox::isAccessibleAlive( ) const
+{
+ return ( NULL != m_pImpl->m_pAccessible ) && m_pImpl->m_pAccessible->isAlive();
+}
+// -----------------------------------------------------------------------------
+// IAccessibleTableProvider
+// -----------------------------------------------------------------------------
+sal_Int32 BrowseBox::GetCurrRow() const
+{
+ return GetCurRow();
+}
+// -----------------------------------------------------------------------------
+sal_uInt16 BrowseBox::GetCurrColumn() const
+{
+ return GetColumnPos( GetCurColumnId() );
+}
+// -----------------------------------------------------------------------------
+sal_Bool BrowseBox::HasRowHeader() const
+{
+ return ( GetColumnId( 0 ) == 0 ); // HandleColumn == RowHeader
+}
+// -----------------------------------------------------------------------------
+sal_Bool BrowseBox::IsCellFocusable() const
+{
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+sal_Bool BrowseBox::GoToCell( sal_Int32 _nRow, sal_uInt16 _nColumn )
+{
+ return GoToRowColumnId( _nRow, GetColumnId( _nColumn ) );
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::SelectColumn( sal_uInt16 _nColumn, sal_Bool _bSelect )
+{
+ SelectColumnPos( _nColumn, _bSelect );
+}
+// -----------------------------------------------------------------------------
+sal_Bool BrowseBox::IsColumnSelected( long _nColumn ) const
+{
+ return ( pColSel && (0 <= _nColumn) && (_nColumn <= 0xFFF) ) ?
+ pColSel->IsSelected( static_cast< sal_uInt16 >( _nColumn ) ) :
+ sal_False;
+}
+// -----------------------------------------------------------------------------
+sal_Int32 BrowseBox::GetSelectedRowCount() const
+{
+ return GetSelectRowCount();
+}
+// -----------------------------------------------------------------------------
+sal_Int32 BrowseBox::GetSelectedColumnCount() const
+{
+ const MultiSelection* pColumnSel = GetColumnSelection();
+ return pColumnSel ? pColumnSel->GetSelectCount() : 0;
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::GetAllSelectedRows( ::com::sun::star::uno::Sequence< sal_Int32 >& _rRows ) const
+{
+ sal_Int32 nCount = GetSelectRowCount();
+ if( nCount )
+ {
+ _rRows.realloc( nCount );
+ _rRows[ 0 ] = const_cast< BrowseBox* >( this )->FirstSelectedRow();
+ for( sal_Int32 nIndex = 1; nIndex < nCount; ++nIndex )
+ _rRows[ nIndex ] = const_cast< BrowseBox* >( this )->NextSelectedRow();
+ DBG_ASSERT( const_cast< BrowseBox* >( this )->NextSelectedRow() == BROWSER_ENDOFSELECTION,
+ "BrowseBox::GetAllSelectedRows - too many selected rows found" );
+ }
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::GetAllSelectedColumns( ::com::sun::star::uno::Sequence< sal_Int32 >& _rColumns ) const
+{
+ const MultiSelection* pColumnSel = GetColumnSelection();
+ sal_Int32 nCount = GetSelectedColumnCount();
+ if( pColumnSel && nCount )
+ {
+ _rColumns.realloc( nCount );
+
+ sal_Int32 nIndex = 0;
+ sal_uInt32 nRangeCount = pColumnSel->GetRangeCount();
+ for( sal_uInt32 nRange = 0; nRange < nRangeCount; ++nRange )
+ {
+ const Range& rRange = pColumnSel->GetRange( nRange );
+ // loop has to include aRange.Max()
+ for( sal_Int32 nCol = rRange.Min(); nCol <= rRange.Max(); ++nCol )
+ {
+ DBG_ASSERT( nIndex < nCount,
+ "GetAllSelectedColumns - range overflow" );
+ _rColumns[ nIndex ] = nCol;
+ ++nIndex;
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Bool BrowseBox::IsCellVisible( sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const
+{
+ return IsFieldVisible( _nRow, GetColumnId( _nColumnPos ) );
+}
+// -----------------------------------------------------------------------------
+String BrowseBox::GetAccessibleCellText(long _nRow, USHORT _nColPos) const
+{
+ return GetCellText( _nRow, GetColumnId( _nColPos ) );
+}
+
+// -----------------------------------------------------------------------------
+BOOL BrowseBox::GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector )
+{
+ return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, nBase, rVector );
+}
+// -----------------------------------------------------------------------------
+Rectangle BrowseBox::GetWindowExtentsRelative( Window *pRelativeWindow ) const
+{
+ return Control::GetWindowExtentsRelative( pRelativeWindow );
+}
+// -----------------------------------------------------------------------------
+void BrowseBox::GrabFocus()
+{
+ Control::GrabFocus();
+}
+// -----------------------------------------------------------------------------
+Reference< XAccessible > BrowseBox::GetAccessible( BOOL bCreate )
+{
+ return Control::GetAccessible( bCreate );
+}
+// -----------------------------------------------------------------------------
+Window* BrowseBox::GetAccessibleParentWindow() const
+{
+ return Control::GetAccessibleParentWindow();
+}
+// -----------------------------------------------------------------------------
+Window* BrowseBox::GetWindowInstance()
+{
+ return this;
+}
diff --git a/svtools/source/brwbox/brwhead.cxx b/svtools/source/brwbox/brwhead.cxx
new file mode 100644
index 000000000000..39845b84f7e0
--- /dev/null
+++ b/svtools/source/brwbox/brwhead.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/brwhead.hxx>
+#include <svtools/brwbox.hxx>
+
+#ifndef GCC
+#endif
+
+//===================================================================
+
+BrowserHeader::BrowserHeader( BrowseBox* pParent, WinBits nWinBits )
+ :HeaderBar( pParent, nWinBits )
+ ,_pBrowseBox( pParent )
+{
+ long nHeight = pParent->IsZoom() ? pParent->CalcZoom(pParent->GetTitleHeight()) : pParent->GetTitleHeight();
+
+ SetPosSizePixel( Point( 0, 0),
+ Size( pParent->GetOutputSizePixel().Width(),
+ nHeight ) );
+ Show();
+}
+
+//-------------------------------------------------------------------
+
+void BrowserHeader::Command( const CommandEvent& rCEvt )
+{
+ if ( !GetCurItemId() && COMMAND_CONTEXTMENU == rCEvt.GetCommand() )
+ {
+ Point aPos( rCEvt.GetMousePosPixel() );
+ if ( _pBrowseBox->IsFrozen(0) )
+ aPos.X() += _pBrowseBox->GetColumnWidth(0);
+ _pBrowseBox->GetDataWindow().Command( CommandEvent(
+ Point( aPos.X(), aPos.Y() - GetSizePixel().Height() ),
+ COMMAND_CONTEXTMENU, rCEvt.IsMouseEvent() ) );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowserHeader::Select()
+{
+ HeaderBar::Select();
+}
+
+//-------------------------------------------------------------------
+
+void BrowserHeader::EndDrag()
+{
+ // call before other actions, it looks more nice in most cases
+ HeaderBar::EndDrag();
+ Update();
+
+ // not aborted?
+ USHORT nId = GetCurItemId();
+ if ( nId )
+ {
+ // Handle-Column?
+ if ( nId == USHRT_MAX-1 )
+ nId = 0;
+
+ if ( !IsItemMode() )
+ {
+ // column resize
+ _pBrowseBox->SetColumnWidth( nId, GetItemSize( nId ) );
+ _pBrowseBox->ColumnResized( nId );
+ SetItemSize( nId, _pBrowseBox->GetColumnWidth( nId ) );
+ }
+ else
+ {
+ // column drag
+ // Hat sich die Position eigentlich veraendert
+ // Handlecolumn beruecksichtigen
+ USHORT nOldPos = _pBrowseBox->GetColumnPos(nId),
+ nNewPos = GetItemPos( nId );
+
+ if (!_pBrowseBox->GetColumnId(0)) // Handle
+ nNewPos++;
+
+ if (nOldPos != nNewPos)
+ {
+ _pBrowseBox->SetColumnPos( nId, nNewPos );
+ _pBrowseBox->ColumnMoved( nId );
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+
+
+
diff --git a/svtools/source/brwbox/brwimpl.hxx b/svtools/source/brwbox/brwimpl.hxx
new file mode 100644
index 000000000000..3c9ddb2876f7
--- /dev/null
+++ b/svtools/source/brwbox/brwimpl.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 _SVTOOLS_BRWIMPL_HXX
+#define _SVTOOLS_BRWIMPL_HXX
+
+#include "svtaccessiblefactory.hxx"
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <map>
+#include <functional>
+
+namespace svt
+{
+ class BrowseBoxImpl
+ {
+ // member
+ public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > AccessibleRef;
+ typedef ::std::map< sal_Int32, AccessibleRef > THeaderCellMap;
+
+ struct THeaderCellMapFunctorDispose : ::std::unary_function<THeaderCellMap::value_type,void>
+ {
+ inline void operator()(const THeaderCellMap::value_type& _aType)
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp(
+ _aType.second, ::com::sun::star::uno::UNO_QUERY );
+ OSL_ENSURE( xComp.is() || !_aType.second.is(), "THeaderCellMapFunctorDispose: invalid accessible cell (no XComponent)!" );
+ if ( xComp.is() )
+ try
+ {
+ xComp->dispose();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "THeaderCellMapFunctorDispose: caught an exception!" );
+ }
+ }
+ };
+
+ public:
+ AccessibleFactoryAccess m_aFactoryAccess;
+ IAccessibleBrowseBox* m_pAccessible;
+ THeaderCellMap m_aColHeaderCellMap;
+ THeaderCellMap m_aRowHeaderCellMap;
+
+ public:
+ BrowseBoxImpl() : m_pAccessible(NULL)
+ {
+ }
+
+
+ /// @see AccessibleBrowseBox::getHeaderBar
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ getAccessibleHeaderBar( AccessibleBrowseBoxObjType _eObjType );
+
+ /// @see AccessibleBrowseBox::getTable
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ getAccessibleTable( );
+
+ };
+}
+
+#endif // _SVTOOLS_BRWIMPL_HXX
diff --git a/svtools/source/brwbox/datwin.cxx b/svtools/source/brwbox/datwin.cxx
new file mode 100644
index 000000000000..cb43e4989355
--- /dev/null
+++ b/svtools/source/brwbox/datwin.cxx
@@ -0,0 +1,782 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "datwin.hxx"
+
+#ifndef GCC
+#endif
+
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+
+#ifndef _HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+
+#include <tools/debug.hxx>
+
+DECLARE_LIST( BrowserColumns, BrowserColumn* )
+
+//===================================================================
+void ButtonFrame::Draw( OutputDevice& rDev )
+{
+ Color aOldFillColor = rDev.GetFillColor();
+ Color aOldLineColor = rDev.GetLineColor();
+
+ const StyleSettings &rSettings = rDev.GetSettings().GetStyleSettings();
+ Color aColLight( rSettings.GetLightColor() );
+ Color aColShadow( rSettings.GetShadowColor() );
+ Color aColFace( rSettings.GetFaceColor() );
+
+ rDev.SetLineColor( aColFace );
+ rDev.SetFillColor( aColFace );
+ rDev.DrawRect( aRect );
+
+ if( rDev.GetOutDevType() == OUTDEV_WINDOW )
+ {
+ Window *pWin = (Window*) &rDev;
+ if( bPressed )
+ pWin->DrawSelectionBackground( aRect, 0, TRUE, FALSE, FALSE );
+ }
+ else
+ {
+ rDev.SetLineColor( bPressed ? aColShadow : aColLight );
+ rDev.DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
+ rDev.DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() - 1 ) );
+ rDev.SetLineColor( bPressed ? aColLight : aColShadow );
+ rDev.DrawLine( aRect.BottomRight(), Point( aRect.Right(), aRect.Top() ) );
+ rDev.DrawLine( aRect.BottomRight(), Point( aRect.Left(), aRect.Bottom() ) );
+ }
+
+ if ( aText.Len() )
+ {
+ String aVal = rDev.GetEllipsisString(aText,aInnerRect.GetWidth() - 2*MIN_COLUMNWIDTH);
+
+ Font aFont( rDev.GetFont() );
+ BOOL bOldTransp = aFont.IsTransparent();
+ if ( !bOldTransp )
+ {
+ aFont.SetTransparent( TRUE );
+ rDev.SetFont( aFont );
+ }
+
+ Color aOldColor = rDev.GetTextColor();
+ if (m_bDrawDisabled)
+ rDev.SetTextColor(rSettings.GetDisableColor());
+
+ rDev.DrawText( Point(
+ ( aInnerRect.Left() + aInnerRect.Right() ) / 2 - ( rDev.GetTextWidth(aVal) / 2 ),
+ aInnerRect.Top() ), aVal );
+
+ // restore settings
+ if ( !bOldTransp )
+ {
+ aFont.SetTransparent(FALSE);
+ rDev.SetFont( aFont );
+ }
+ if (m_bDrawDisabled)
+ rDev.SetTextColor(aOldColor);
+ }
+
+ if ( bCurs )
+ {
+ rDev.SetLineColor( Color( COL_BLACK ) );
+ rDev.SetFillColor();
+ rDev.DrawRect( Rectangle(
+ Point( aRect.Left(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) ) );
+ }
+
+ rDev.SetLineColor( aOldLineColor );
+ rDev.SetFillColor( aOldFillColor );
+}
+
+//-------------------------------------------------------------------
+
+BrowserColumn::BrowserColumn( USHORT nItemId, const class Image &rImage,
+ const String& rTitle, ULONG nWidthPixel, const Fraction& rCurrentZoom,
+ HeaderBarItemBits nFlags )
+: _nId( nItemId ),
+ _nWidth( nWidthPixel ),
+ _aImage( rImage ),
+ _aTitle( rTitle ),
+ _bFrozen( FALSE ),
+ _nFlags( nFlags )
+{
+ double n = (double)_nWidth;
+ n *= (double)rCurrentZoom.GetDenominator();
+ n /= (double)rCurrentZoom.GetNumerator();
+ _nOriginalWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5);
+}
+
+BrowserColumn::~BrowserColumn()
+{
+}
+
+//-------------------------------------------------------------------
+
+void BrowserColumn::SetWidth(ULONG nNewWidthPixel, const Fraction& rCurrentZoom)
+{
+ _nWidth = nNewWidthPixel;
+ double n = (double)_nWidth;
+ n *= (double)rCurrentZoom.GetDenominator();
+ n /= (double)rCurrentZoom.GetNumerator();
+ _nOriginalWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5);
+}
+
+//-------------------------------------------------------------------
+
+void BrowserColumn::Draw( BrowseBox& rBox, OutputDevice& rDev, const Point& rPos, BOOL bCurs )
+{
+ if ( _nId == 0 )
+ {
+ // paint handle column
+ ButtonFrame( rPos, Size( Width()-1, rBox.GetDataRowHeight()-1 ),
+ String(), FALSE, bCurs,
+ 0 != (BROWSER_COLUMN_TITLEABBREVATION&_nFlags) ).Draw( rDev );
+ Color aOldLineColor = rDev.GetLineColor();
+ rDev.SetLineColor( Color( COL_BLACK ) );
+ rDev.DrawLine(
+ Point( rPos.X(), rPos.Y()+rBox.GetDataRowHeight()-1 ),
+ Point( rPos.X() + Width() - 1, rPos.Y()+rBox.GetDataRowHeight()-1 ) );
+ rDev.DrawLine(
+ Point( rPos.X() + Width() - 1, rPos.Y() ),
+ Point( rPos.X() + Width() - 1, rPos.Y()+rBox.GetDataRowHeight()-1 ) );
+ rDev.SetLineColor( aOldLineColor );
+
+ rBox.DoPaintField( rDev,
+ Rectangle(
+ Point( rPos.X() + 2, rPos.Y() + 2 ),
+ Size( Width()-1, rBox.GetDataRowHeight()-1 ) ),
+ GetId(),
+ BrowseBox::BrowserColumnAccess() );
+ }
+ else
+ {
+ // paint data column
+ long nWidth = Width() == LONG_MAX ? rBox.GetDataWindow().GetSizePixel().Width() : Width();
+
+ rBox.DoPaintField( rDev,
+ Rectangle(
+ Point( rPos.X() + MIN_COLUMNWIDTH, rPos.Y() ),
+ Size( nWidth-2*MIN_COLUMNWIDTH, rBox.GetDataRowHeight()-1 ) ),
+ GetId(),
+ BrowseBox::BrowserColumnAccess() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowserColumn::ZoomChanged(const Fraction& rNewZoom)
+{
+ double n = (double)_nOriginalWidth;
+ n *= (double)rNewZoom.GetNumerator();
+ n /= (double)rNewZoom.GetDenominator();
+
+ _nWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5);
+}
+
+//-------------------------------------------------------------------
+
+BrowserDataWin::BrowserDataWin( BrowseBox* pParent )
+ :Control( pParent, WinBits(WB_CLIPCHILDREN) )
+ ,DragSourceHelper( this )
+ ,DropTargetHelper( this )
+ ,pHeaderBar( 0 )
+ ,pEventWin( pParent )
+ ,pCornerWin( 0 )
+ ,pDtorNotify( 0 )
+ ,bInPaint( FALSE )
+ ,bInCommand( FALSE )
+ ,bNoScrollBack( FALSE )
+ ,bNoHScroll( FALSE )
+ ,bNoVScroll( FALSE )
+ ,bUpdateMode( TRUE )
+ ,bResizeOnPaint( FALSE )
+ ,bUpdateOnUnlock( FALSE )
+ ,bInUpdateScrollbars( FALSE )
+ ,bHadRecursion( FALSE )
+ ,bOwnDataChangedHdl( FALSE )
+ ,bCallingDropCallback( FALSE )
+ ,nUpdateLock( 0 )
+ ,nCursorHidden( 0 )
+ ,m_nDragRowDividerLimit( 0 )
+ ,m_nDragRowDividerOffset( 0 )
+{
+ aMouseTimer.SetTimeoutHdl( LINK( this, BrowserDataWin, RepeatedMouseMove ) );
+ aMouseTimer.SetTimeout( 100 );
+}
+
+//-------------------------------------------------------------------
+BrowserDataWin::~BrowserDataWin()
+{
+ if( pDtorNotify )
+ *pDtorNotify = TRUE;
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::LeaveUpdateLock()
+{
+ if ( !--nUpdateLock )
+ {
+ DoOutstandingInvalidations();
+ if (bUpdateOnUnlock )
+ {
+ Control::Update();
+ bUpdateOnUnlock = FALSE;
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+void InitSettings_Impl( Window *pWin,
+ BOOL bFont, BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings =
+ pWin->GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetFieldFont();
+ if ( pWin->IsControlFont() )
+ aFont.Merge( pWin->GetControlFont() );
+ pWin->SetZoomedPointFont( aFont );
+ }
+
+ if ( bFont || bForeground )
+ {
+ Color aTextColor = rStyleSettings.GetWindowTextColor();
+ if ( pWin->IsControlForeground() )
+ aTextColor = pWin->GetControlForeground();
+ pWin->SetTextColor( aTextColor );
+ }
+
+ if ( bBackground )
+ {
+ if( pWin->IsControlBackground() )
+ pWin->SetBackground( pWin->GetControlBackground() );
+ else
+ pWin->SetBackground( rStyleSettings.GetWindowColor() );
+ }
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::Update()
+{
+ if ( !nUpdateLock )
+ Control::Update();
+ else
+ bUpdateOnUnlock = TRUE;
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ if( !bOwnDataChangedHdl )
+ {
+ InitSettings_Impl( this, TRUE, TRUE, TRUE );
+ Invalidate();
+ InitSettings_Impl( GetParent(), TRUE, TRUE, TRUE );
+ GetParent()->Invalidate();
+ GetParent()->Resize();
+ }
+ }
+ else
+ Control::DataChanged( rDCEvt );
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::Paint( const Rectangle& rRect )
+{
+ if ( !nUpdateLock && GetUpdateMode() )
+ {
+ if ( bInPaint )
+ {
+ aInvalidRegion.Insert( new Rectangle( rRect ) );
+ return;
+ }
+ bInPaint = TRUE;
+ ( (BrowseBox*) GetParent() )->PaintData( *this, rRect );
+ bInPaint = FALSE;
+ DoOutstandingInvalidations();
+ }
+ else
+ aInvalidRegion.Insert( new Rectangle( rRect ) );
+}
+
+//-------------------------------------------------------------------
+
+BrowseEvent BrowserDataWin::CreateBrowseEvent( const Point& rPosPixel )
+{
+ BrowseBox *pBox = GetParent();
+
+ // seek to row under mouse
+ long nRelRow = rPosPixel.Y() < 0
+ ? -1
+ : rPosPixel.Y() / pBox->GetDataRowHeight();
+ long nRow = nRelRow < 0 ? -1 : nRelRow + pBox->nTopRow;
+
+ // find column under mouse
+ long nMouseX = rPosPixel.X();
+ long nColX = 0;
+ USHORT nCol;
+ for ( nCol = 0;
+ nCol < pBox->pCols->Count() && nColX < GetSizePixel().Width();
+ ++nCol )
+ if ( pBox->pCols->GetObject(nCol)->IsFrozen() || nCol >= pBox->nFirstCol )
+ {
+ nColX += pBox->pCols->GetObject(nCol)->Width();
+ if ( nMouseX < nColX )
+ break;
+ }
+ USHORT nColId = BROWSER_INVALIDID;
+ if ( nCol < pBox->pCols->Count() )
+ nColId = pBox->pCols->GetObject(nCol)->GetId();
+
+ // compute the field rectangle and field relative MouseEvent
+ Rectangle aFieldRect;
+ if ( nCol < pBox->pCols->Count() )
+ {
+ nColX -= pBox->pCols->GetObject(nCol)->Width();
+ aFieldRect = Rectangle(
+ Point( nColX, nRelRow * pBox->GetDataRowHeight() ),
+ Size( pBox->pCols->GetObject(nCol)->Width(),
+ pBox->GetDataRowHeight() ) );
+ }
+
+ // assemble and return the BrowseEvent
+ return BrowseEvent( this, nRow, nCol, nColId, aFieldRect );
+}
+
+//-------------------------------------------------------------------
+sal_Int8 BrowserDataWin::AcceptDrop( const AcceptDropEvent& _rEvt )
+{
+ bCallingDropCallback = sal_True;
+ sal_Int8 nReturn = DND_ACTION_NONE;
+ nReturn = GetParent()->AcceptDrop( BrowserAcceptDropEvent( this, _rEvt ) );
+ bCallingDropCallback = sal_False;
+ return nReturn;
+}
+
+//-------------------------------------------------------------------
+sal_Int8 BrowserDataWin::ExecuteDrop( const ExecuteDropEvent& _rEvt )
+{
+ bCallingDropCallback = sal_True;
+ sal_Int8 nReturn = DND_ACTION_NONE;
+ nReturn = GetParent()->ExecuteDrop( BrowserExecuteDropEvent( this, _rEvt ) );
+ bCallingDropCallback = sal_False;
+ return nReturn;
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel )
+{
+ if ( !GetParent()->bRowDividerDrag )
+ {
+ Point aEventPos( _rPosPixel );
+ aEventPos.Y() += GetParent()->GetTitleHeight();
+ GetParent()->StartDrag( _nAction, aEventPos );
+ }
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::Command( const CommandEvent& rEvt )
+{
+ // Scrollmaus-Event?
+ BrowseBox *pBox = GetParent();
+ if ( ( (rEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rEvt.GetCommand() == COMMAND_AUTOSCROLL) ) &&
+ ( HandleScrollCommand( rEvt, &pBox->aHScroll, pBox->pVScroll ) ) )
+ return;
+
+ Point aEventPos( rEvt.GetMousePosPixel() );
+ long nRow = pBox->GetRowAtYPosPixel( aEventPos.Y(), FALSE);
+ MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT );
+ if ( COMMAND_CONTEXTMENU == rEvt.GetCommand() && rEvt.IsMouseEvent() &&
+ nRow < pBox->GetRowCount() && !pBox->IsRowSelected(nRow) )
+ {
+ BOOL bDeleted = FALSE;
+ pDtorNotify = &bDeleted;
+ bInCommand = TRUE;
+ MouseButtonDown( aMouseEvt );
+ if( bDeleted )
+ return;
+ MouseButtonUp( aMouseEvt );
+ if( bDeleted )
+ return;
+ pDtorNotify = 0;
+ bInCommand = FALSE;
+ }
+
+ aEventPos.Y() += GetParent()->GetTitleHeight();
+ CommandEvent aEvt( aEventPos, rEvt.GetCommand(),
+ rEvt.IsMouseEvent(), rEvt.GetData() );
+ bInCommand = TRUE;
+ BOOL bDeleted = FALSE;
+ pDtorNotify = &bDeleted;
+ GetParent()->Command( aEvt );
+ if( bDeleted )
+ return;
+ pDtorNotify = 0;
+ bInCommand = FALSE;
+
+ if ( COMMAND_STARTDRAG == rEvt.GetCommand() )
+ MouseButtonUp( aMouseEvt );
+
+ Control::Command( rEvt );
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowserDataWin::ImplRowDividerHitTest( const BrowserMouseEvent& _rEvent )
+{
+ if ( ! ( GetParent()->IsInteractiveRowHeightEnabled()
+ && ( _rEvent.GetRow() >= 0 )
+ && ( _rEvent.GetRow() < GetParent()->GetRowCount() )
+ && ( _rEvent.GetColumnId() == 0 )
+ )
+ )
+ return FALSE;
+
+ long nDividerDistance = GetParent()->GetDataRowHeight() - ( _rEvent.GetPosPixel().Y() % GetParent()->GetDataRowHeight() );
+ return ( nDividerDistance <= 4 );
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::MouseButtonDown( const MouseEvent& rEvt )
+{
+ aLastMousePos = OutputToScreenPixel( rEvt.GetPosPixel() );
+
+ BrowserMouseEvent aBrowserEvent( this, rEvt );
+ if ( ( aBrowserEvent.GetClicks() == 1 ) && ImplRowDividerHitTest( aBrowserEvent ) )
+ {
+ StartRowDividerDrag( aBrowserEvent.GetPosPixel() );
+ return;
+ }
+
+ GetParent()->MouseButtonDown( BrowserMouseEvent( this, rEvt ) );
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::MouseMove( const MouseEvent& rEvt )
+{
+ // Pseudo MouseMoves verhindern
+ Point aNewPos = OutputToScreenPixel( rEvt.GetPosPixel() );
+ if ( ( aNewPos == aLastMousePos ) )
+ return;
+ aLastMousePos = aNewPos;
+
+ // transform to a BrowseEvent
+ BrowserMouseEvent aBrowserEvent( this, rEvt );
+ GetParent()->MouseMove( aBrowserEvent );
+
+ // pointer shape
+ PointerStyle ePointerStyle = POINTER_ARROW;
+ if ( ImplRowDividerHitTest( aBrowserEvent ) )
+ ePointerStyle = POINTER_VSIZEBAR;
+ SetPointer( Pointer( ePointerStyle ) );
+
+ // dragging out of the visible area?
+ if ( rEvt.IsLeft() &&
+ ( rEvt.GetPosPixel().Y() > GetSizePixel().Height() ||
+ rEvt.GetPosPixel().Y() < 0 ) )
+ {
+ // repeat the event
+ aRepeatEvt = rEvt;
+ aMouseTimer.Start();
+ }
+ else
+ // killing old repeat-event
+ if ( aMouseTimer.IsActive() )
+ aMouseTimer.Stop();
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( BrowserDataWin, RepeatedMouseMove, void *, EMPTYARG )
+{
+ GetParent()->MouseMove( BrowserMouseEvent( this, aRepeatEvt ) );
+ return 0;
+}
+IMPL_LINK_INLINE_END( BrowserDataWin, RepeatedMouseMove, void *, EMPTYARG )
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::MouseButtonUp( const MouseEvent& rEvt )
+{
+ // Pseudo MouseMoves verhindern
+ Point aNewPos = OutputToScreenPixel( rEvt.GetPosPixel() );
+ aLastMousePos = aNewPos;
+
+ // Move an die aktuelle Position simulieren
+ MouseMove( rEvt );
+
+ // eigentliches Up-Handling
+ ReleaseMouse();
+ if ( aMouseTimer.IsActive() )
+ aMouseTimer.Stop();
+ GetParent()->MouseButtonUp( BrowserMouseEvent( this, rEvt ) );
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::StartRowDividerDrag( const Point& _rStartPos )
+{
+ long nDataRowHeight = GetParent()->GetDataRowHeight();
+ // the exact separation pos of the two rows
+ long nDragRowDividerCurrentPos = _rStartPos.Y();
+ if ( ( nDragRowDividerCurrentPos % nDataRowHeight ) > nDataRowHeight / 2 )
+ nDragRowDividerCurrentPos += nDataRowHeight;
+ nDragRowDividerCurrentPos /= nDataRowHeight;
+ nDragRowDividerCurrentPos *= nDataRowHeight;
+
+ m_nDragRowDividerOffset = nDragRowDividerCurrentPos - _rStartPos.Y();
+
+ m_nDragRowDividerLimit = nDragRowDividerCurrentPos - nDataRowHeight;
+
+ GetParent()->bRowDividerDrag = TRUE;
+ GetParent()->ImplStartTracking();
+
+ Rectangle aDragSplitRect( 0, m_nDragRowDividerLimit, GetOutputSizePixel().Width(), nDragRowDividerCurrentPos );
+ ShowTracking( aDragSplitRect, SHOWTRACK_SMALL );
+
+ StartTracking();
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( !GetParent()->bRowDividerDrag )
+ return;
+
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+ // stop resizing at our bottom line
+ if ( aMousePos.Y() > GetOutputSizePixel().Height() )
+ aMousePos.Y() = GetOutputSizePixel().Height();
+
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ HideTracking();
+ GetParent()->bRowDividerDrag = FALSE;
+ GetParent()->ImplEndTracking();
+
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ long nNewRowHeight = aMousePos.Y() + m_nDragRowDividerOffset - m_nDragRowDividerLimit;
+
+ // care for minimum row height
+ if ( nNewRowHeight < GetParent()->QueryMinimumRowHeight() )
+ nNewRowHeight = GetParent()->QueryMinimumRowHeight();
+
+ GetParent()->SetDataRowHeight( nNewRowHeight );
+ GetParent()->RowHeightChanged();
+ }
+ }
+ else
+ {
+ GetParent()->ImplTracking();
+
+ long nDragRowDividerCurrentPos = aMousePos.Y() + m_nDragRowDividerOffset;
+
+ // care for minimum row height
+ if ( nDragRowDividerCurrentPos < m_nDragRowDividerLimit + GetParent()->QueryMinimumRowHeight() )
+ nDragRowDividerCurrentPos = m_nDragRowDividerLimit + GetParent()->QueryMinimumRowHeight();
+
+ Rectangle aDragSplitRect( 0, m_nDragRowDividerLimit, GetOutputSizePixel().Width(), nDragRowDividerCurrentPos );
+ ShowTracking( aDragSplitRect, SHOWTRACK_SMALL );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::KeyInput( const KeyEvent& rEvt )
+{
+ // pass to parent window
+ if ( !GetParent()->ProcessKey( rEvt ) )
+ Control::KeyInput( rEvt );
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::RequestHelp( const HelpEvent& rHEvt )
+{
+ pEventWin = this;
+ GetParent()->RequestHelp( rHEvt );
+ pEventWin = GetParent();
+}
+
+//===================================================================
+
+BrowseEvent::BrowseEvent( Window* pWindow,
+ long nAbsRow, USHORT nColumn, USHORT nColumnId,
+ const Rectangle& rRect ):
+ pWin(pWindow),
+ nRow(nAbsRow),
+ aRect(rRect),
+ nCol(nColumn),
+ nColId(nColumnId)
+{
+}
+
+//===================================================================
+BrowserMouseEvent::BrowserMouseEvent( BrowserDataWin *pWindow,
+ const MouseEvent& rEvt ):
+ MouseEvent(rEvt),
+ BrowseEvent( pWindow->CreateBrowseEvent( rEvt.GetPosPixel() ) )
+{
+}
+
+//-------------------------------------------------------------------
+
+BrowserMouseEvent::BrowserMouseEvent( Window *pWindow, const MouseEvent& rEvt,
+ long nAbsRow, USHORT nColumn, USHORT nColumnId,
+ const Rectangle& rRect ):
+ MouseEvent(rEvt),
+ BrowseEvent( pWindow, nAbsRow, nColumn, nColumnId, rRect )
+{
+}
+
+//===================================================================
+
+BrowserAcceptDropEvent::BrowserAcceptDropEvent( BrowserDataWin *pWindow, const AcceptDropEvent& rEvt )
+ :AcceptDropEvent(rEvt)
+ ,BrowseEvent( pWindow->CreateBrowseEvent( rEvt.maPosPixel ) )
+{
+}
+
+//===================================================================
+
+BrowserExecuteDropEvent::BrowserExecuteDropEvent( BrowserDataWin *pWindow, const ExecuteDropEvent& rEvt )
+ :ExecuteDropEvent(rEvt)
+ ,BrowseEvent( pWindow->CreateBrowseEvent( rEvt.maPosPixel ) )
+{
+}
+
+//===================================================================
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::SetUpdateMode( BOOL bMode )
+{
+ DBG_ASSERT( !bUpdateMode || aInvalidRegion.Count() == 0,
+ "invalid region not empty" );
+ if ( bMode == bUpdateMode )
+ return;
+
+ bUpdateMode = bMode;
+ if ( bMode )
+ DoOutstandingInvalidations();
+}
+
+//-------------------------------------------------------------------
+void BrowserDataWin::DoOutstandingInvalidations()
+{
+ for ( Rectangle* pRect = aInvalidRegion.First();
+ pRect;
+ pRect = aInvalidRegion.Next() )
+ {
+ Control::Invalidate( *pRect );
+ delete pRect;
+ }
+ aInvalidRegion.Clear();
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::Invalidate( USHORT nFlags )
+{
+ if ( !GetUpdateMode() )
+ {
+ for ( Rectangle* pRect = aInvalidRegion.First();
+ pRect;
+ pRect = aInvalidRegion.Next() )
+ delete pRect;
+ aInvalidRegion.Clear();
+ aInvalidRegion.Insert( new Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
+ }
+ else
+ Window::Invalidate( nFlags );
+}
+
+//-------------------------------------------------------------------
+
+void BrowserDataWin::Invalidate( const Rectangle& rRect, USHORT nFlags )
+{
+ if ( !GetUpdateMode() )
+ aInvalidRegion.Insert( new Rectangle( rRect ) );
+ else
+ Window::Invalidate( rRect, nFlags );
+}
+
+//===================================================================
+
+void BrowserScrollBar::Tracking( const TrackingEvent& rTEvt )
+{
+ ULONG nPos = GetThumbPos();
+ if ( nPos != _nLastPos )
+ {
+ if ( _nTip )
+ Help::HideTip( _nTip );
+
+ String aTip( String::CreateFromInt32(nPos) );
+ aTip += '/';
+ if ( _pDataWin->GetRealRowCount().Len() )
+ aTip += _pDataWin->GetRealRowCount();
+ else
+ aTip += String::CreateFromInt32(GetRangeMax());
+ Rectangle aRect( GetPointerPosPixel(), Size( GetTextHeight(), GetTextWidth( aTip ) ) );
+ _nTip = Help::ShowTip( this, aRect, aTip );
+ _nLastPos = nPos;
+ }
+
+ ScrollBar::Tracking( rTEvt );
+}
+
+//-------------------------------------------------------------------
+
+void BrowserScrollBar::EndScroll()
+{
+ if ( _nTip )
+ Help::HideTip( _nTip );
+ _nTip = 0;
+ ScrollBar::EndScroll();
+}
+
+
diff --git a/svtools/source/brwbox/datwin.hxx b/svtools/source/brwbox/datwin.hxx
new file mode 100644
index 000000000000..1deb8aeb5b56
--- /dev/null
+++ b/svtools/source/brwbox/datwin.hxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SFXDATWIN_HXX
+#define _SFXDATWIN_HXX
+
+#ifndef _BRWBOX_HXX
+#include <svtools/brwbox.hxx>
+#endif
+#include <svtools/brwhead.hxx>
+#include <vcl/timer.hxx>
+#ifndef _IMAGE_HXX //autogen
+#include <vcl/image.hxx>
+#endif
+#include <tools/list.hxx>
+#include <svtools/transfer.hxx>
+
+//===================================================================
+
+#define MIN_COLUMNWIDTH 2
+#define DRAG_CRITICAL 4
+
+DECLARE_LIST( RectangleList, Rectangle* )
+
+//===================================================================
+
+class ButtonFrame
+{
+ Rectangle aRect;
+ Rectangle aInnerRect;
+ String aText;
+ BOOL bPressed;
+ BOOL bCurs;
+ BOOL bAbbr;
+ BOOL m_bDrawDisabled;
+
+public:
+ ButtonFrame( const Point& rPt, const Size& rSz,
+ const String &rText,
+ BOOL bPress = FALSE,
+ BOOL bCursor = FALSE,
+ BOOL bAbbreviate = TRUE,
+ BOOL _bDrawDisabled = FALSE)
+ :aRect( rPt, rSz )
+ ,aInnerRect( Point( aRect.Left()+1, aRect.Top()+1 ),
+ Size( aRect.GetWidth()-2, aRect.GetHeight()-2 ) )
+ ,aText(rText)
+ ,bPressed(bPress)
+ ,bCurs(bCursor)
+ ,bAbbr(bAbbreviate)
+ ,m_bDrawDisabled(_bDrawDisabled)
+ {
+ }
+
+ void Draw( OutputDevice& rDev );
+};
+
+//===================================================================
+
+class BrowserColumn
+{
+ USHORT _nId;
+ ULONG _nOriginalWidth;
+ ULONG _nWidth;
+ Image _aImage;
+ String _aTitle;
+ BOOL _bFrozen;
+ HeaderBarItemBits _nFlags;
+
+public:
+ BrowserColumn( USHORT nItemId, const Image &rImage,
+ const String& rTitle, ULONG nWidthPixel, const Fraction& rCurrentZoom,
+ HeaderBarItemBits nFlags );
+ virtual ~BrowserColumn();
+
+ USHORT GetId() const { return _nId; }
+
+ ULONG Width() { return _nWidth; }
+ Image& GetImage() { return _aImage; }
+ String& Title() { return _aTitle; }
+ HeaderBarItemBits& Flags() { return _nFlags; }
+
+ BOOL IsFrozen() const { return _bFrozen; }
+ void Freeze( BOOL bFreeze = TRUE ) { _bFrozen = bFreeze; }
+
+ virtual void Draw( BrowseBox& rBox, OutputDevice& rDev,
+ const Point& rPos, BOOL bCurs );
+
+ void SetWidth(ULONG nNewWidthPixel, const Fraction& rCurrentZoom);
+ void ZoomChanged(const Fraction& rNewZoom);
+};
+
+//===================================================================
+
+class BrowserDataWin
+ :public Control
+ ,public DragSourceHelper
+ ,public DropTargetHelper
+{
+public:
+ BrowserHeader* pHeaderBar; // only for BROWSER_HEADERBAR_NEW
+ Window* pEventWin; // Window of forwarded events
+ ScrollBarBox* pCornerWin; // Window in the corner btw the ScrollBars
+ BOOL* pDtorNotify;
+ AutoTimer aMouseTimer; // recalls MouseMove on dragging out
+ MouseEvent aRepeatEvt; // a MouseEvent to repeat
+ Point aLastMousePos; // verhindert pseudo-MouseMoves
+
+ String aRealRowCount; // zur Anzeige im VScrollBar
+
+ RectangleList aInvalidRegion; // invalidated Rectangles during !UpdateMode
+ FASTBOOL bInPaint; // TRUE while in Paint
+ FASTBOOL bInCommand; // TRUE while in Command
+ FASTBOOL bNoScrollBack; // nur vorwaerts scrollen
+ FASTBOOL bNoHScroll; // kein horizontaler Scrollbar
+ FASTBOOL bNoVScroll; // no vertical scrollbar
+ FASTBOOL bAutoHScroll; // autohide horizontaler Scrollbar
+ FASTBOOL bAutoVScroll; // autohide horizontaler Scrollbar
+ FASTBOOL bUpdateMode; // nicht SV-UpdateMode wegen Invalidate()
+ FASTBOOL bAutoSizeLastCol;// last column always fills up window
+ FASTBOOL bResizeOnPaint; // outstanding resize-event
+ FASTBOOL bUpdateOnUnlock; // Update() while locked
+ FASTBOOL bInUpdateScrollbars; // Rekursionsschutz
+ FASTBOOL bHadRecursion; // Rekursion war aufgetreten
+ FASTBOOL bOwnDataChangedHdl; // dont change colors in DataChanged
+ FASTBOOL bCallingDropCallback; // we're in a callback to AcceptDrop or ExecuteDrop curently
+ USHORT nUpdateLock; // lock count, dont call Control::Update()!
+ short nCursorHidden; // new conuter for DoHide/ShowCursor
+
+ long m_nDragRowDividerLimit;
+ long m_nDragRowDividerOffset;
+
+public:
+ BrowserDataWin( BrowseBox* pParent );
+ ~BrowserDataWin();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+ virtual void Paint( const Rectangle& rRect );
+ virtual void RequestHelp( const HelpEvent& rHEvt );
+ virtual void Command( const CommandEvent& rEvt );
+ virtual void MouseButtonDown( const MouseEvent& rEvt );
+ virtual void MouseMove( const MouseEvent& rEvt );
+ DECL_LINK( RepeatedMouseMove, void * );
+
+ virtual void MouseButtonUp( const MouseEvent& rEvt );
+ virtual void KeyInput( const KeyEvent& rEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+
+ // DropTargetHelper overridables
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );
+
+ // DragSourceHelper overridables
+ virtual void StartDrag( sal_Int8 _nAction, const Point& _rPosPixel );
+
+
+ BrowseEvent CreateBrowseEvent( const Point& rPosPixel );
+ void Repaint();
+ BrowseBox* GetParent() const
+ { return (BrowseBox*) Window::GetParent(); }
+ const String& GetRealRowCount() const { return aRealRowCount; }
+
+ void SetUpdateMode( BOOL bMode );
+ FASTBOOL GetUpdateMode() const { return bUpdateMode; }
+ void EnterUpdateLock() { ++nUpdateLock; }
+ void LeaveUpdateLock();
+ void Update();
+ void DoOutstandingInvalidations();
+ void Invalidate( USHORT nFlags = 0 );
+ void Invalidate( const Rectangle& rRect, USHORT nFlags = 0 );
+ void Invalidate( const Region& rRegion, USHORT nFlags = 0 )
+ { Control::Invalidate( rRegion, nFlags ); }
+
+protected:
+ void StartRowDividerDrag( const Point& _rStartPos );
+ BOOL ImplRowDividerHitTest( const BrowserMouseEvent& _rEvent );
+};
+
+//-------------------------------------------------------------------
+
+inline void BrowserDataWin::Repaint()
+{
+ if ( GetUpdateMode() )
+ Update();
+ Paint( Rectangle( Point(), GetOutputSizePixel() ) );
+}
+
+//===================================================================
+
+class BrowserScrollBar: public ScrollBar
+{
+ ULONG _nTip;
+ ULONG _nLastPos;
+ BrowserDataWin* _pDataWin;
+
+public:
+ BrowserScrollBar( Window* pParent, WinBits nStyle,
+ BrowserDataWin *pDataWin )
+ : ScrollBar( pParent, nStyle ),
+ _nTip( 0 ),
+ _nLastPos( ULONG_MAX ),
+ _pDataWin( pDataWin )
+ {}
+ //ScrollBar( Window* pParent, const ResId& rResId );
+
+ virtual void Tracking( const TrackingEvent& rTEvt );
+ virtual void EndScroll();
+};
+
+//===================================================================
+
+void InitSettings_Impl( Window *pWin,
+ BOOL bFont = TRUE, BOOL bForeground = TRUE, BOOL bBackground = TRUE );
+
+//===================================================================
+
+#ifdef DBG_MI
+
+void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho );
+#define LOG(pThis,what,who) DoLog_Impl(pThis,what,who)
+
+#else
+
+#define LOG(pThis,what,who)
+
+#endif
+
+
+#endif
+
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
new file mode 100644
index 000000000000..edf56f0b9b34
--- /dev/null
+++ b/svtools/source/brwbox/ebbcontrols.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_svtools.hxx"
+#include <svtools/editbrowsebox.hxx>
+#include <vcl/decoview.hxx>
+#include <svtools/fmtfield.hxx>
+#include <svtools/xtextedt.hxx>
+
+#include <algorithm>
+
+// .......................................................................
+namespace svt
+{
+// .......................................................................
+
+ TYPEINIT0(CellController);
+ TYPEINIT1(EditCellController, CellController);
+ TYPEINIT1(SpinCellController, CellController);
+ TYPEINIT1(CheckBoxCellController, CellController);
+ TYPEINIT1(ComboBoxCellController, CellController);
+ TYPEINIT1(ListBoxCellController, CellController);
+
+ TYPEINIT1( FormattedFieldCellController, EditCellController );
+
+ //==================================================================
+ //= ComboBoxControl
+ //==================================================================
+ ComboBoxControl::ComboBoxControl(Window* pParent, WinBits nWinStyle)
+ :ComboBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
+ {
+ EnableAutoSize(sal_False);
+ EnableAutocomplete(sal_True);
+ SetDropDownLineCount(5);
+ }
+
+ //------------------------------------------------------------------
+ long ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
+ {
+ switch (rNEvt.GetType())
+ {
+ case EVENT_KEYINPUT:
+ if (!IsInDropDown())
+ {
+ const KeyEvent *pEvt = rNEvt.GetKeyEvent();
+ const KeyCode rKey = pEvt->GetKeyCode();
+
+ if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
+ (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
+ {
+ // select next resp. previous entry
+ int nPos = GetEntryPos(GetText());
+ nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
+ if (nPos < 0)
+ nPos = 0;
+ if (nPos >= GetEntryCount())
+ nPos = GetEntryCount() - 1;
+ SetText(GetEntry(sal::static_int_cast< USHORT >(nPos)));
+ return 1;
+ }
+ }
+ break;
+ }
+ return ComboBox::PreNotify(rNEvt);
+ }
+
+ //==================================================================
+ //= ComboBoxCellController
+ //==================================================================
+ //------------------------------------------------------------------
+ ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
+ :CellController(pWin)
+ {
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
+ {
+ ComboBoxControl& rBox = GetComboBox();
+ switch (rEvt.GetKeyCode().GetCode())
+ {
+ case KEY_END:
+ case KEY_RIGHT:
+ {
+ Selection aSel = rBox.GetSelection();
+ return !aSel && aSel.Max() == rBox.GetText().Len();
+ }
+ case KEY_HOME:
+ case KEY_LEFT:
+ {
+ Selection aSel = rBox.GetSelection();
+ return !aSel && aSel.Min() == 0;
+ }
+ case KEY_UP:
+ case KEY_DOWN:
+ if (rBox.IsInDropDown())
+ return sal_False;
+ if (!rEvt.GetKeyCode().IsShift() &&
+ rEvt.GetKeyCode().IsMod1())
+ return sal_False;
+ // drop down the list box
+ else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
+ return sal_False;
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ case KEY_RETURN:
+ if (rBox.IsInDropDown())
+ return sal_False;
+ default:
+ return sal_True;
+ }
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool ComboBoxCellController::IsModified() const
+ {
+ return GetComboBox().GetSavedValue() != GetComboBox().GetText();
+ }
+
+ //------------------------------------------------------------------
+ void ComboBoxCellController::ClearModified()
+ {
+ GetComboBox().SaveValue();
+ }
+
+ //------------------------------------------------------------------
+ void ComboBoxCellController::SetModifyHdl(const Link& rLink)
+ {
+ GetComboBox().SetModifyHdl(rLink);
+ }
+
+ //==================================================================
+ //= ListBoxControl
+ //==================================================================
+ //------------------------------------------------------------------
+ ListBoxControl::ListBoxControl(Window* pParent, WinBits nWinStyle)
+ :ListBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
+ {
+ EnableAutoSize(sal_False);
+ EnableMultiSelection(sal_False);
+ SetDropDownLineCount(20);
+ }
+
+ //------------------------------------------------------------------
+ long ListBoxControl::PreNotify( NotifyEvent& rNEvt )
+ {
+ switch (rNEvt.GetType())
+ {
+ case EVENT_KEYINPUT:
+ if (!IsInDropDown())
+ {
+ const KeyEvent *pEvt = rNEvt.GetKeyEvent();
+ const KeyCode rKey = pEvt->GetKeyCode();
+
+ if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
+ (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
+ {
+ // select next resp. previous entry
+ int nPos = GetSelectEntryPos();
+ nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
+ if (nPos < 0)
+ nPos = 0;
+ if (nPos >= GetEntryCount())
+ nPos = GetEntryCount() - 1;
+ SelectEntryPos(sal::static_int_cast< USHORT >(nPos));
+ Select(); // for calling Modify
+ return 1;
+ }
+ else if (GetParent()->PreNotify(rNEvt))
+ return 1;
+ }
+ break;
+ }
+ return ListBox::PreNotify(rNEvt);
+ }
+
+ //==================================================================
+ //= ListBoxCellController
+ //==================================================================
+ //------------------------------------------------------------------
+ ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
+ :CellController(pWin)
+ {
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
+ {
+ ListBoxControl& rBox = GetListBox();
+ switch (rEvt.GetKeyCode().GetCode())
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ if (!rEvt.GetKeyCode().IsShift() &&
+ rEvt.GetKeyCode().IsMod1())
+ return sal_False;
+ // drop down the list box
+ else
+ if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
+ return sal_False;
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ if (rBox.IsTravelSelect())
+ return sal_False;
+ default:
+ return sal_True;
+ }
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool ListBoxCellController::IsModified() const
+ {
+ return GetListBox().GetSelectEntryPos() != GetListBox().GetSavedValue();
+ }
+
+ //------------------------------------------------------------------
+ void ListBoxCellController::ClearModified()
+ {
+ GetListBox().SaveValue();
+ }
+
+ //------------------------------------------------------------------
+ void ListBoxCellController::SetModifyHdl(const Link& rLink)
+ {
+ GetListBox().SetSelectHdl(rLink);
+ }
+
+ //==================================================================
+ //= CheckBoxControl
+ //==================================================================
+ //------------------------------------------------------------------
+ CheckBoxControl::CheckBoxControl(Window* pParent, WinBits nWinStyle)
+ :Control(pParent, nWinStyle)
+ {
+ const Wallpaper& rParentBackground = pParent->GetBackground();
+ if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() )
+ SetBackground( rParentBackground );
+ else
+ {
+ SetPaintTransparent( sal_True );
+ SetBackground();
+ }
+
+ EnableChildTransparentMode();
+
+ pBox = new TriStateBox(this,WB_CENTER|WB_VCENTER);
+ pBox->EnableChildTransparentMode();
+ pBox->SetPaintTransparent( sal_True );
+ pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) );
+ pBox->Show();
+ }
+
+ //------------------------------------------------------------------
+ CheckBoxControl::~CheckBoxControl()
+ {
+ delete pBox;
+ }
+
+ //------------------------------------------------------------------
+ IMPL_LINK( CheckBoxControl, OnClick, void*, EMPTYARG )
+ {
+ m_aClickLink.Call(pBox);
+ return m_aModifyLink.Call(pBox);
+ }
+
+ //------------------------------------------------------------------
+ void CheckBoxControl::Resize()
+ {
+ Control::Resize();
+ pBox->SetPosSizePixel(Point(0,0),GetSizePixel());
+ }
+
+ //------------------------------------------------------------------------------
+ void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent )
+ {
+ if ( _rEvent.GetType() == DATACHANGED_SETTINGS )
+ pBox->SetSettings( GetSettings() );
+ }
+
+ //------------------------------------------------------------------------------
+ void CheckBoxControl::StateChanged( StateChangedType nStateChange )
+ {
+ Control::StateChanged(nStateChange);
+ if ( nStateChange == STATE_CHANGE_ZOOM )
+ pBox->SetZoom(GetZoom());
+ }
+
+ //------------------------------------------------------------------
+ void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+ {
+ pBox->Draw(pDev,rPos,rSize,nFlags);
+ }
+
+ //------------------------------------------------------------------
+ void CheckBoxControl::GetFocus()
+ {
+ pBox->GrabFocus();
+ }
+
+ //------------------------------------------------------------------
+ void CheckBoxControl::Paint(const Rectangle& rClientRect)
+ {
+ Control::Paint(rClientRect);
+ if (HasFocus())
+ ShowFocus(aFocusRect);
+ }
+
+ //------------------------------------------------------------------
+ long CheckBoxControl::PreNotify(NotifyEvent& rEvt)
+ {
+ switch (rEvt.GetType())
+ {
+ case EVENT_GETFOCUS:
+ ShowFocus(aFocusRect);
+ break;
+ case EVENT_LOSEFOCUS:
+ HideFocus();
+ }
+ return Control::PreNotify(rEvt);
+ }
+
+ //==================================================================
+ //= CheckBoxCellController
+ //==================================================================
+ //------------------------------------------------------------------
+ sal_Bool CheckBoxCellController::WantMouseEvent() const
+ {
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------
+ CheckBox& CheckBoxCellController::GetCheckBox() const
+ {
+ return ((CheckBoxControl &)GetWindow()).GetBox();
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool CheckBoxCellController::IsModified() const
+ {
+ return GetCheckBox().GetSavedValue() != GetCheckBox().GetState();
+ }
+
+ //------------------------------------------------------------------
+ void CheckBoxCellController::ClearModified()
+ {
+ GetCheckBox().SaveValue();
+ }
+
+ //------------------------------------------------------------------
+ void CheckBoxCellController::SetModifyHdl(const Link& rLink)
+ {
+ ((CheckBoxControl &)GetWindow()).SetModifyHdl(rLink);
+ }
+
+ //==================================================================
+ //= MultiLineEditImplementation
+ //==================================================================
+ //------------------------------------------------------------------
+ String MultiLineEditImplementation::GetText( LineEnd aSeparator ) const
+ {
+ return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetText( aSeparator );
+ }
+
+ //------------------------------------------------------------------
+ String MultiLineEditImplementation::GetSelected( LineEnd aSeparator ) const
+ {
+ return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetSelected( aSeparator );
+ }
+
+ //==================================================================
+ //= EditCellController
+ //==================================================================
+ //------------------------------------------------------------------
+ EditCellController::EditCellController( Edit* _pEdit )
+ :CellController( _pEdit )
+ ,m_pEditImplementation( new EditImplementation( *_pEdit ) )
+ ,m_bOwnImplementation( TRUE )
+ {
+ }
+
+ //------------------------------------------------------------------
+ EditCellController::EditCellController( MultiLineTextCell* _pEdit )
+ :CellController( _pEdit )
+ ,m_pEditImplementation( new MultiLineEditImplementation( *_pEdit ) )
+ ,m_bOwnImplementation( TRUE )
+ {
+ }
+
+ //------------------------------------------------------------------
+ EditCellController::EditCellController( IEditImplementation* _pImplementation )
+ :CellController( &_pImplementation->GetControl() )
+ ,m_pEditImplementation( _pImplementation )
+ ,m_bOwnImplementation( FALSE )
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ EditCellController::~EditCellController( )
+ {
+ if ( m_bOwnImplementation )
+ DELETEZ( m_pEditImplementation );
+ }
+
+ //-----------------------------------------------------------------------------
+ void EditCellController::SetModified()
+ {
+ m_pEditImplementation->SetModified();
+ }
+
+ //-----------------------------------------------------------------------------
+ void EditCellController::ClearModified()
+ {
+ m_pEditImplementation->ClearModified();
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const
+ {
+ sal_Bool bResult;
+ switch (rEvt.GetKeyCode().GetCode())
+ {
+ case KEY_END:
+ case KEY_RIGHT:
+ {
+ Selection aSel = m_pEditImplementation->GetSelection();
+ bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).Len();
+ } break;
+ case KEY_HOME:
+ case KEY_LEFT:
+ {
+ Selection aSel = m_pEditImplementation->GetSelection();
+ bResult = !aSel && aSel.Min() == 0;
+ } break;
+ default:
+ bResult = sal_True;
+ }
+ return bResult;
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool EditCellController::IsModified() const
+ {
+ return m_pEditImplementation->IsModified();
+ }
+
+ //------------------------------------------------------------------
+ void EditCellController::SetModifyHdl(const Link& rLink)
+ {
+ m_pEditImplementation->SetModifyHdl(rLink);
+ }
+
+ //==================================================================
+ //= SpinCellController
+ //==================================================================
+ //------------------------------------------------------------------
+ SpinCellController::SpinCellController(SpinField* pWin)
+ :CellController(pWin)
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ void SpinCellController::SetModified()
+ {
+ GetSpinWindow().SetModifyFlag();
+ }
+
+ //-----------------------------------------------------------------------------
+ void SpinCellController::ClearModified()
+ {
+ GetSpinWindow().ClearModifyFlag();
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const
+ {
+ sal_Bool bResult;
+ switch (rEvt.GetKeyCode().GetCode())
+ {
+ case KEY_END:
+ case KEY_RIGHT:
+ {
+ Selection aSel = GetSpinWindow().GetSelection();
+ bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().Len();
+ } break;
+ case KEY_HOME:
+ case KEY_LEFT:
+ {
+ Selection aSel = GetSpinWindow().GetSelection();
+ bResult = !aSel && aSel.Min() == 0;
+ } break;
+ default:
+ bResult = sal_True;
+ }
+ return bResult;
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool SpinCellController::IsModified() const
+ {
+ return GetSpinWindow().IsModified();
+ }
+
+ //------------------------------------------------------------------
+ void SpinCellController::SetModifyHdl(const Link& rLink)
+ {
+ GetSpinWindow().SetModifyHdl(rLink);
+ }
+
+ //==================================================================
+ //= FormattedFieldCellController
+ //==================================================================
+ //------------------------------------------------------------------
+ FormattedFieldCellController::FormattedFieldCellController( FormattedField* _pFormatted )
+ :EditCellController( _pFormatted )
+ {
+ }
+
+ //------------------------------------------------------------------
+ void FormattedFieldCellController::CommitModifications()
+ {
+ static_cast< FormattedField& >( GetWindow() ).Commit();
+ }
+
+ //==================================================================
+ //= MultiLineTextCell
+ //==================================================================
+ //------------------------------------------------------------------
+ void MultiLineTextCell::Modify()
+ {
+ GetTextEngine()->SetModified( TRUE );
+ MultiLineEdit::Modify();
+ }
+
+ //------------------------------------------------------------------
+ BOOL MultiLineTextCell::dispatchKeyEvent( const KeyEvent& _rEvent )
+ {
+ Selection aOldSelection( GetSelection() );
+
+ BOOL bWasModified = IsModified();
+ ClearModifyFlag( );
+
+ BOOL bHandled = GetTextView()->KeyInput( _rEvent );
+
+ BOOL bIsModified = IsModified();
+ if ( bWasModified && !bIsModified )
+ // not sure whether this can really happen
+ SetModifyFlag();
+
+ if ( bHandled ) // the view claimed it handled the key input
+ {
+ // unfortunately, KeyInput also returns <TRUE/> (means "I handled this key input")
+ // when nothing really changed. Let's care for this.
+ Selection aNewSelection( GetSelection() );
+ if ( aNewSelection != aOldSelection // selection changed
+ || bIsModified // or some other modification
+ )
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ //------------------------------------------------------------------
+ long MultiLineTextCell::PreNotify( NotifyEvent& rNEvt )
+ {
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ if ( IsWindowOrChild( rNEvt.GetWindow() ) )
+ {
+ // give the text view a chance to handle the keys
+ // this is necessary since a lot of keys which are normally handled
+ // by this view (in KeyInput) are intercepted by the EditBrowseBox,
+ // which uses them for other reasons. An example is the KeyUp key,
+ // which is used by both the text view and the edit browse box
+
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
+ USHORT nCode = rKeyCode.GetCode();
+
+ if ( ( nCode == KEY_RETURN ) && ( rKeyCode.GetModifier() == KEY_MOD1 ) )
+ {
+ KeyEvent aEvent( pKeyEvent->GetCharCode(),
+ KeyCode( KEY_RETURN ),
+ pKeyEvent->GetRepeat()
+ );
+ if ( dispatchKeyEvent( aEvent ) )
+ return 1;
+ }
+
+ if ( ( nCode != KEY_TAB ) && ( nCode != KEY_RETURN ) ) // everything but tab and enter
+ {
+ if ( dispatchKeyEvent( *pKeyEvent ) )
+ return 1;
+ }
+ }
+ }
+ return MultiLineEdit::PreNotify( rNEvt );
+ }
+
+// .......................................................................
+} // namespace svt
+// .......................................................................
+
+
diff --git a/svtools/source/brwbox/editbrowsebox.cxx b/svtools/source/brwbox/editbrowsebox.cxx
new file mode 100644
index 000000000000..4f0afbaf5d2d
--- /dev/null
+++ b/svtools/source/brwbox/editbrowsebox.cxx
@@ -0,0 +1,1437 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/editbrowsebox.hxx>
+
+#ifndef _SVTOOLS_EDITBROWSEBOX_HRC_
+#include "editbrowsebox.hrc"
+#endif
+
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <vcl/window.hxx>
+
+#ifndef _EDIT_HXX //autogen
+#include <vcl/edit.hxx>
+#endif
+#include <tools/resid.hxx>
+#include <vcl/spinfld.hxx>
+#include <svtools/svtdata.hxx>
+
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+#include <algorithm>
+#include <tools/multisel.hxx>
+#include "editbrowseboximpl.hxx"
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <comphelper/types.hxx>
+
+// .......................................................................
+namespace svt
+{
+// .......................................................................
+ namespace
+ {
+ //..............................................................
+ sal_Bool isHiContrast(Window* _pWindow)
+ {
+ OSL_ENSURE(_pWindow,"Window must be not null!");
+ return _pWindow && _pWindow->GetSettings().GetStyleSettings().GetHighContrastMode();
+ }
+
+ //..............................................................
+ sal_uInt16 getRealGetFocusFlags( Window* _pWindow )
+ {
+ sal_uInt16 nFlags = 0;
+ while ( _pWindow && !nFlags )
+ {
+ nFlags = _pWindow->GetGetFocusFlags( );
+ _pWindow = _pWindow->GetParent();
+ }
+ return nFlags;
+ }
+ }
+
+ using namespace ::com::sun::star::uno;
+ using namespace com::sun::star::accessibility::AccessibleEventId;
+ using com::sun::star::accessibility::XAccessible;
+ //==================================================================
+
+ #define HANDLE_ID 0
+
+ //==================================================================
+ //= EditBrowserHeader
+ //==================================================================
+ //------------------------------------------------------------------------------
+ void EditBrowserHeader::DoubleClick()
+ {
+ sal_uInt16 nColId = GetCurItemId();
+ if (nColId)
+ {
+ sal_uInt32 nAutoWidth = ((EditBrowseBox*)GetParent())->GetAutoColumnWidth(nColId);
+ if (nAutoWidth != ((EditBrowseBox*)GetParent())->GetColumnWidth(nColId))
+ {
+ ((EditBrowseBox*)GetParent())->SetColumnWidth(nColId, nAutoWidth);
+ ((EditBrowseBox*)GetParent())->ColumnResized(nColId);
+ }
+ }
+ }
+
+
+ //==================================================================
+ //= EditBrowseBox
+ //==================================================================
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::BrowserMouseEventPtr::Clear()
+ {
+ DELETEZ(pEvent);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::BrowserMouseEventPtr::Set(const BrowserMouseEvent* pEvt, sal_Bool bIsDown)
+ {
+ if (pEvt == pEvent)
+ {
+ bDown = bIsDown;
+ return;
+ }
+ Clear();
+ if (pEvt)
+ {
+ pEvent = new BrowserMouseEvent(pEvt->GetWindow(),
+ *pEvt,
+ pEvt->GetRow(),
+ pEvt->GetColumn(),
+ pEvt->GetColumnId(),
+ pEvt->GetRect());
+ bDown = bIsDown;
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ DBG_NAME(EditBrowseBox);
+ void EditBrowseBox::impl_construct()
+ {
+ m_aImpl = ::std::auto_ptr<EditBrowseBoxImpl>(new EditBrowseBoxImpl());
+ m_aImpl->m_bHiContrast = isHiContrast(&GetDataWindow());
+
+ SetCompoundControl(sal_True);
+ SetGridLineColor( Color( COL_LIGHTGRAY ) );
+
+ ImplInitSettings(sal_True, sal_True, sal_True);
+
+ pCheckBoxPaint = new CheckBoxControl(&GetDataWindow());
+ pCheckBoxPaint->SetPaintTransparent( sal_True );
+ pCheckBoxPaint->SetBackground();
+ }
+
+ //------------------------------------------------------------------------------
+ EditBrowseBox::EditBrowseBox(Window* pParent, const ResId& rId, sal_Int32 nBrowserFlags, BrowserMode _nMode )
+ :BrowseBox( pParent, rId, _nMode )
+ ,nStartEvent(0)
+ ,nEndEvent(0)
+ ,nCellModifiedEvent(0)
+ ,nPaintRow(-1)
+ ,nEditRow(-1)
+ ,nOldEditRow(-1)
+ ,nEditCol(0)
+ ,nOldEditCol(0)
+ ,bHasFocus(sal_False)
+ ,bPaintStatus(sal_True)
+ ,bActiveBeforeTracking( sal_False )
+ ,m_nBrowserFlags(nBrowserFlags)
+ {
+ DBG_CTOR(EditBrowseBox,NULL);
+
+ impl_construct();
+ }
+
+ //==================================================================
+ EditBrowseBox::EditBrowseBox( Window* pParent, sal_Int32 nBrowserFlags, WinBits nBits, BrowserMode _nMode )
+ :BrowseBox( pParent, nBits, _nMode )
+ ,nStartEvent(0)
+ ,nEndEvent(0)
+ ,nCellModifiedEvent(0)
+ ,nPaintRow(-1)
+ ,nEditRow(-1)
+ ,nOldEditRow(-1)
+ ,nEditCol(0)
+ ,nOldEditCol(0)
+ ,bHasFocus(sal_False)
+ ,bPaintStatus(sal_True)
+ ,bActiveBeforeTracking( sal_False )
+ ,m_nBrowserFlags(nBrowserFlags)
+ ,pHeader(NULL)
+ {
+ DBG_CTOR(EditBrowseBox,NULL);
+
+ impl_construct();
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::Init()
+ {
+ // spaetes Construieren,
+ }
+
+ //------------------------------------------------------------------------------
+ EditBrowseBox::~EditBrowseBox()
+ {
+ if (nStartEvent)
+ Application::RemoveUserEvent(nStartEvent);
+ if (nEndEvent)
+ Application::RemoveUserEvent(nEndEvent);
+ if (nCellModifiedEvent)
+ Application::RemoveUserEvent(nCellModifiedEvent);
+
+ delete pCheckBoxPaint;
+
+ DBG_DTOR(EditBrowseBox,NULL);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::RemoveRows()
+ {
+ BrowseBox::Clear();
+ nOldEditRow = nEditRow = nPaintRow = -1;
+ nEditCol = nOldEditCol = 0;
+ }
+
+ //------------------------------------------------------------------------------
+ BrowserHeader* EditBrowseBox::CreateHeaderBar(BrowseBox* pParent)
+ {
+ pHeader = imp_CreateHeaderBar(pParent);
+ if (!IsUpdateMode())
+ pHeader->SetUpdateMode(sal_False);
+ return pHeader;
+ }
+
+ //------------------------------------------------------------------------------
+ BrowserHeader* EditBrowseBox::imp_CreateHeaderBar(BrowseBox* pParent)
+ {
+ return new EditBrowserHeader(pParent);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::LoseFocus()
+ {
+ BrowseBox::LoseFocus();
+ DetermineFocus( 0 );
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::GetFocus()
+ {
+ BrowseBox::GetFocus();
+
+ // This should handle the case that the BrowseBox (or one of it's children)
+ // gets the focus from outside by pressing Tab
+ if (IsEditing() && Controller()->GetWindow().IsVisible())
+ Controller()->GetWindow().GrabFocus();
+
+ DetermineFocus( getRealGetFocusFlags( this ) );
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool EditBrowseBox::SeekRow(long nRow)
+ {
+ nPaintRow = nRow;
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_LINK(EditBrowseBox, StartEditHdl, void*, EMPTYARG)
+ {
+ nStartEvent = 0;
+ if (IsEditing())
+ {
+ EnableAndShow();
+ if (!aController->GetWindow().HasFocus() && (m_pFocusWhileRequest == Application::GetFocusWindow()))
+ aController->GetWindow().GrabFocus();
+ }
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::PaintField( OutputDevice& rDev, const Rectangle& rRect,
+ sal_uInt16 nColumnId ) const
+ {
+ if (nColumnId == HANDLE_ID)
+ {
+ if (bPaintStatus)
+ PaintStatusCell(rDev, rRect);
+ }
+ else
+ {
+ // don't paint the current cell
+ if (&rDev == &GetDataWindow())
+ // but only if we're painting onto our data win (which is the usual painting)
+ if (nPaintRow == nEditRow)
+ {
+ if (IsEditing() && nEditCol == nColumnId && aController->GetWindow().IsVisible())
+ return;
+ }
+ PaintCell(rDev, rRect, nColumnId);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ Image EditBrowseBox::GetImage(RowStatus eStatus) const
+ {
+ sal_Bool bHiContrast = isHiContrast(&GetDataWindow());
+ if ( !m_aStatusImages.GetImageCount() || (bHiContrast != m_aImpl->m_bHiContrast) )
+ {
+ m_aImpl->m_bHiContrast = bHiContrast;
+ const_cast<EditBrowseBox*>(this)->m_aStatusImages = ImageList(SvtResId(bHiContrast ? RID_SVTOOLS_IMAGELIST_EDITBWSEBOX_H : RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX));
+ }
+
+ Image aImage;
+ bool bNeedMirror = IsRTLEnabled();
+ switch (eStatus)
+ {
+ case CURRENT:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENT);
+ break;
+ case CURRENTNEW:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENTNEW);
+ break;
+ case MODIFIED:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_MODIFIED);
+ bNeedMirror = false; // the pen is not mirrored
+ break;
+ case NEW:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_NEW);
+ break;
+ case DELETED:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_DELETED);
+ break;
+ case PRIMARYKEY:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_PRIMARYKEY);
+ break;
+ case CURRENT_PRIMARYKEY:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENT_PRIMARYKEY);
+ break;
+ case FILTER:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_FILTER);
+ break;
+ case HEADERFOOTER:
+ aImage = m_aStatusImages.GetImage(IMG_EBB_HEADERFOOTER);
+ break;
+ case CLEAN:
+ break;
+ }
+ if ( bNeedMirror )
+ {
+ BitmapEx aBitmap( aImage.GetBitmapEx() );
+ aBitmap.Mirror( BMP_MIRROR_HORZ );
+ aImage = Image( aBitmap );
+ }
+ return aImage;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const
+ {
+ if (nPaintRow < 0)
+ return;
+
+ RowStatus eStatus = GetRowStatus( nPaintRow );
+ sal_Int32 nBrowserFlags = GetBrowserFlags();
+
+ if (nBrowserFlags & EBBF_NO_HANDLE_COLUMN_CONTENT)
+ return;
+
+ // draw the text of the header column
+ if (nBrowserFlags & EBBF_HANDLE_COLUMN_TEXT )
+ {
+ rDev.DrawText( rRect, GetCellText( nPaintRow, 0 ),
+ TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_CLIP );
+ }
+ // draw an image
+ else if (eStatus != CLEAN && rDev.GetOutDevType() == OUTDEV_WINDOW)
+ {
+ Image aImage(GetImage(eStatus));
+ // calc the image position
+ Size aImageSize(aImage.GetSizePixel());
+ aImageSize.Width() = CalcZoom(aImageSize.Width());
+ aImageSize.Height() = CalcZoom(aImageSize.Height());
+ Point aPos( rRect.TopLeft() );
+
+ if ( ( aImageSize.Width() > rRect.GetWidth() ) || ( aImageSize.Height() > rRect.GetHeight() ) )
+ rDev.SetClipRegion(rRect);
+
+ if ( aImageSize.Width() < rRect.GetWidth() )
+ aPos.X() += ( rRect.GetWidth() - aImageSize.Width() ) / 2;
+
+ if ( aImageSize.Height() < rRect.GetHeight() )
+ aPos.Y() += ( rRect.GetHeight() - aImageSize.Height() ) / 2;
+
+ if ( IsZoom() )
+ rDev.DrawImage( aPos, aImageSize, aImage, 0 );
+ else
+ rDev.DrawImage( aPos, aImage, 0 );
+
+ if (rDev.IsClipRegion())
+ rDev.SetClipRegion();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ImplStartTracking()
+ {
+ bActiveBeforeTracking = IsEditing();
+ if ( bActiveBeforeTracking )
+ {
+ DeactivateCell();
+ Update();
+ }
+
+ BrowseBox::ImplStartTracking();
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ImplTracking()
+ {
+ BrowseBox::ImplTracking();
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ImplEndTracking()
+ {
+ if ( bActiveBeforeTracking )
+ ActivateCell();
+ bActiveBeforeTracking = sal_False;
+
+ BrowseBox::ImplEndTracking();
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::RowHeightChanged()
+ {
+ if ( IsEditing() )
+ {
+ Rectangle aRect( GetCellRect( nEditRow, nEditCol, sal_False ) );
+ CellControllerRef aCellController( Controller() );
+ ResizeController( aCellController, aRect );
+ aCellController->GetWindow().GrabFocus();
+ }
+
+ BrowseBox::RowHeightChanged();
+ }
+
+ //------------------------------------------------------------------------------
+ EditBrowseBox::RowStatus EditBrowseBox::GetRowStatus(long) const
+ {
+ return CLEAN;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::KeyInput( const KeyEvent& rEvt )
+ {
+ sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
+ sal_Bool bShift = rEvt.GetKeyCode().IsShift();
+ sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1();
+
+ switch (nCode)
+ {
+ case KEY_RETURN:
+ if (!bCtrl && !bShift && IsTabAllowed(sal_True))
+ {
+ Dispatch(BROWSER_CURSORRIGHT);
+ }
+ else
+ BrowseBox::KeyInput(rEvt);
+ return;
+ case KEY_TAB:
+ if (!bCtrl && !bShift)
+ {
+ if (IsTabAllowed(sal_True))
+ Dispatch(BROWSER_CURSORRIGHT);
+ else
+ // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
+ // that tab isn't allowed here. So give the Control class a chance
+ Control::KeyInput(rEvt);
+ return;
+ }
+ else if (!bCtrl && bShift)
+ {
+ if (IsTabAllowed(sal_False))
+ Dispatch(BROWSER_CURSORLEFT);
+ else
+ // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
+ // that tab isn't allowed here. So give the Control class a chance
+ Control::KeyInput(rEvt);
+ return;
+ }
+ default:
+ BrowseBox::KeyInput(rEvt);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::MouseButtonDown(const BrowserMouseEvent& rEvt)
+ {
+ sal_uInt16 nColPos = GetColumnPos( rEvt.GetColumnId() );
+ long nRow = rEvt.GetRow();
+
+ // absorb double clicks
+ if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0)
+ return;
+
+ // change to a new position
+ if (IsEditing() && (nColPos != nEditCol || nRow != nEditRow) && (nColPos != BROWSER_INVALIDID) && (nRow < GetRowCount()))
+ {
+ CellControllerRef aCellController(Controller());
+ HideAndDisable(aCellController);
+ }
+
+ // we are about to leave the current cell. If there is a "this cell has been modified" notification
+ // pending (asynchronously), this may be deadly -> do it synchronously
+ // 95826 - 2002-10-14 - fs@openoffice.org
+ if ( nCellModifiedEvent )
+ {
+ Application::RemoveUserEvent( nCellModifiedEvent );
+ nCellModifiedEvent = 0;
+ LINK( this, EditBrowseBox, CellModifiedHdl ).Call( NULL );
+ }
+
+ if (0 == rEvt.GetColumnId())
+ { // it was the handle column. save the current cell content if necessary
+ // (clicking on the handle column results in selecting the current row)
+ // 23.01.2001 - 82797 - FS
+ if (IsEditing() && aController->IsModified())
+ SaveModified();
+ }
+
+ aMouseEvent.Set(&rEvt,sal_True);
+ BrowseBox::MouseButtonDown(rEvt);
+ aMouseEvent.Clear();
+
+ if (0 != (m_nBrowserFlags & EBBF_ACTIVATE_ON_BUTTONDOWN))
+ {
+ // the base class does not travel upon MouseButtonDown, but implActivateCellOnMouseEvent assumes we traveled ...
+ GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
+ if (rEvt.GetRow() >= 0)
+ implActivateCellOnMouseEvent(rEvt, sal_False);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::MouseButtonUp( const BrowserMouseEvent& rEvt )
+ {
+ // absorb double clicks
+ if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0)
+ return;
+
+ aMouseEvent.Set(&rEvt,sal_False);
+ BrowseBox::MouseButtonUp(rEvt);
+ aMouseEvent.Clear();
+
+ if (0 == (m_nBrowserFlags & EBBF_ACTIVATE_ON_BUTTONDOWN))
+ if (rEvt.GetRow() >= 0)
+ implActivateCellOnMouseEvent(rEvt, sal_True);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::implActivateCellOnMouseEvent(const BrowserMouseEvent& _rEvt, sal_Bool _bUp)
+ {
+ if (!IsEditing())
+ ActivateCell();
+ else if (IsEditing() && !aController->GetWindow().IsEnabled())
+ DeactivateCell();
+ else if (IsEditing() && !aController->GetWindow().HasChildPathFocus())
+ AsynchGetFocus();
+
+ if (IsEditing() && aController->GetWindow().IsEnabled() && aController->WantMouseEvent())
+ { // forwards the event to the control
+
+ // If the field has been moved previously, we have to adjust the position
+
+ aController->GetWindow().GrabFocus();
+
+ // the position of the event relative to the controller's window
+ Point aPos = _rEvt.GetPosPixel() - _rEvt.GetRect().TopLeft();
+ // the (child) window which should really get the event
+ Window* pRealHandler = aController->GetWindow().FindWindow(aPos);
+ if (pRealHandler)
+ // the coords relative to this real handler
+ aPos -= pRealHandler->GetPosPixel();
+ else
+ pRealHandler = &aController->GetWindow();
+
+ // the faked event
+ MouseEvent aEvent(aPos, _rEvt.GetClicks(), _rEvt.GetMode(),
+ _rEvt.GetButtons(),
+ _rEvt.GetModifier());
+
+ pRealHandler->MouseButtonDown(aEvent);
+ if (_bUp)
+ pRealHandler->MouseButtonUp(aEvent);
+
+ Window *pWin = &aController->GetWindow();
+ if (!pWin->IsTracking())
+ {
+ for (pWin = pWin->GetWindow(WINDOW_FIRSTCHILD);
+ pWin && !pWin->IsTracking();
+ pWin = pWin->GetWindow(WINDOW_NEXT))
+ {
+ }
+ }
+ if (pWin && pWin->IsTracking())
+ pWin->EndTracking();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::Dispatch( sal_uInt16 _nId )
+ {
+ if ( _nId == BROWSER_ENHANCESELECTION )
+ { // this is a workaround for the bug in the base class:
+ // if the row selection is to be extended (which is what BROWSER_ENHANCESELECTION tells us)
+ // then the base class does not revert any column selections, while, for doing a "simple"
+ // selection (BROWSER_SELECT), it does. In fact, it does not only revert the col selection then,
+ // but also any current row selections.
+ // This clearly tells me that the both ids are for row selection only - there this behaviour does
+ // make sense.
+ // But here, where we have column selection, too, we take care of this ourself.
+ if ( GetSelectColumnCount( ) )
+ {
+ while ( GetSelectColumnCount( ) )
+ SelectColumnPos(
+ sal::static_int_cast< USHORT >(FirstSelectedColumn()),
+ sal_False );
+ Select();
+ }
+ }
+ BrowseBox::Dispatch( _nId );
+ }
+
+ //------------------------------------------------------------------------------
+ long EditBrowseBox::PreNotify(NotifyEvent& rEvt)
+ {
+ switch (rEvt.GetType())
+ {
+ case EVENT_KEYINPUT:
+ if ( (IsEditing() && Controller()->GetWindow().HasChildPathFocus())
+ || rEvt.GetWindow() == &GetDataWindow()
+ || (!IsEditing() && HasChildPathFocus())
+ )
+ {
+ const KeyEvent* pKeyEvent = rEvt.GetKeyEvent();
+ sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
+ sal_Bool bShift = pKeyEvent->GetKeyCode().IsShift();
+ sal_Bool bCtrl = pKeyEvent->GetKeyCode().IsMod1();
+ sal_Bool bAlt = pKeyEvent->GetKeyCode().IsMod2();
+ sal_Bool bLocalSelect= sal_False;
+ sal_Bool bNonEditOnly = sal_False;
+ sal_uInt16 nId = BROWSER_NONE;
+
+ if (!bAlt && !bCtrl && !bShift )
+ switch ( nCode )
+ {
+ case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
+ case KEY_UP: nId = BROWSER_CURSORUP; break;
+ case KEY_PAGEDOWN: nId = BROWSER_CURSORPAGEDOWN; break;
+ case KEY_PAGEUP: nId = BROWSER_CURSORPAGEUP; break;
+ case KEY_HOME: nId = BROWSER_CURSORHOME; break;
+ case KEY_END: nId = BROWSER_CURSOREND; break;
+
+ case KEY_TAB:
+ // ask if traveling to the next cell is allowed
+ if (IsTabAllowed(sal_True))
+ nId = BROWSER_CURSORRIGHT;
+ break;
+
+ case KEY_RETURN:
+ // save the cell content (if necessary)
+ if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified())
+ {
+ // maybe we're not visible ...
+ EnableAndShow();
+ aController->GetWindow().GrabFocus();
+ return 1;
+ }
+ // ask if traveling to the next cell is allowed
+ if (IsTabAllowed(sal_True))
+ nId = BROWSER_CURSORRIGHT;
+
+ break;
+ case KEY_RIGHT: nId = BROWSER_CURSORRIGHT; break;
+ case KEY_LEFT: nId = BROWSER_CURSORLEFT; break;
+ case KEY_SPACE: nId = BROWSER_SELECT; bNonEditOnly = bLocalSelect = sal_True;break;
+ }
+
+ if ( !bAlt && !bCtrl && bShift )
+ switch ( nCode )
+ {
+ case KEY_DOWN: nId = BROWSER_SELECTDOWN; bLocalSelect = sal_True;break;
+ case KEY_UP: nId = BROWSER_SELECTUP; bLocalSelect = sal_True;break;
+ case KEY_HOME: nId = BROWSER_SELECTHOME; bLocalSelect = sal_True;break;
+ case KEY_END: nId = BROWSER_SELECTEND; bLocalSelect = sal_True;break;
+ case KEY_TAB:
+ if (IsTabAllowed(sal_False))
+ nId = BROWSER_CURSORLEFT;
+ break;
+ }
+
+ if ( !bAlt && bCtrl && bShift )
+ switch ( nCode )
+ {
+ case KEY_SPACE: nId = BROWSER_SELECTCOLUMN; bLocalSelect = sal_True; break;
+ }
+
+
+ if ( !bAlt && bCtrl && !bShift )
+ switch ( nCode )
+ {
+ case KEY_DOWN: nId = BROWSER_SCROLLUP; break;
+ case KEY_UP: nId = BROWSER_SCROLLDOWN; break;
+ case KEY_PAGEDOWN: nId = BROWSER_CURSORENDOFFILE; break;
+ case KEY_PAGEUP: nId = BROWSER_CURSORTOPOFFILE; break;
+ case KEY_HOME: nId = BROWSER_CURSORTOPOFSCREEN; break;
+ case KEY_END: nId = BROWSER_CURSORENDOFSCREEN; break;
+ case KEY_SPACE: nId = BROWSER_ENHANCESELECTION; bLocalSelect = sal_True;break;
+ }
+
+
+ if ( ( nId != BROWSER_NONE )
+ && ( !IsEditing()
+ || ( !bNonEditOnly
+ && aController->MoveAllowed( *pKeyEvent )
+ )
+ )
+ )
+ {
+ if (nId == BROWSER_SELECT || BROWSER_SELECTCOLUMN == nId )
+ {
+ // save the cell content (if necessary)
+ if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified())
+ {
+ // maybe we're not visible ...
+ EnableAndShow();
+ aController->GetWindow().GrabFocus();
+ return 1;
+ }
+ }
+
+ Dispatch(nId);
+
+ if (bLocalSelect && (GetSelectRowCount() || GetSelection() != NULL))
+ DeactivateCell();
+ return 1;
+ }
+ }
+ }
+ return BrowseBox::PreNotify(rEvt);
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool EditBrowseBox::IsTabAllowed(sal_Bool) const
+ {
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ long EditBrowseBox::Notify(NotifyEvent& rEvt)
+ {
+ switch (rEvt.GetType())
+ {
+ case EVENT_GETFOCUS:
+ DetermineFocus( getRealGetFocusFlags( this ) );
+ break;
+
+ case EVENT_LOSEFOCUS:
+ DetermineFocus( 0 );
+ break;
+ }
+ return BrowseBox::Notify(rEvt);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::StateChanged( StateChangedType nType )
+ {
+ BrowseBox::StateChanged( nType );
+
+ bool bNeedCellReActivation = false;
+ if ( nType == STATE_CHANGE_MIRRORING )
+ {
+ bNeedCellReActivation = true;
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ ImplInitSettings( sal_True, sal_False, sal_False );
+ bNeedCellReActivation = true;
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ ImplInitSettings( sal_True, sal_False, sal_False );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( sal_False, sal_True, sal_False );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( sal_False, sal_False, sal_True );
+ Invalidate();
+ }
+ else if (nType == STATE_CHANGE_STYLE)
+ {
+ WinBits nStyle = GetStyle();
+ if (!(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+
+ SetStyle(nStyle);
+ }
+ if ( bNeedCellReActivation )
+ {
+ if ( IsEditing() )
+ {
+ DeactivateCell();
+ ActivateCell();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::DataChanged( const DataChangedEvent& rDCEvt )
+ {
+ BrowseBox::DataChanged( rDCEvt );
+
+ if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
+ ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
+ {
+ ImplInitSettings( sal_True, sal_True, sal_True );
+ Invalidate();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if (bFont)
+ {
+ Font aFont = rStyleSettings.GetFieldFont();
+ if (IsControlFont())
+ {
+ GetDataWindow().SetControlFont(GetControlFont());
+ aFont.Merge(GetControlFont());
+ }
+ else
+ GetDataWindow().SetControlFont();
+
+ GetDataWindow().SetZoomedPointFont(aFont);
+ }
+
+ if ( bFont || bForeground )
+ {
+ Color aTextColor = rStyleSettings.GetFieldTextColor();
+ if (IsControlForeground())
+ {
+ aTextColor = GetControlForeground();
+ GetDataWindow().SetControlForeground(aTextColor);
+ }
+ else
+ GetDataWindow().SetControlForeground();
+
+ GetDataWindow().SetTextColor( aTextColor );
+ }
+
+ if ( bBackground )
+ {
+ if (GetDataWindow().IsControlBackground())
+ {
+ GetDataWindow().SetControlBackground(GetControlBackground());
+ GetDataWindow().SetBackground(GetDataWindow().GetControlBackground());
+ GetDataWindow().SetFillColor(GetDataWindow().GetControlBackground());
+ }
+ else
+ {
+ GetDataWindow().SetControlBackground();
+ GetDataWindow().SetBackground( rStyleSettings.GetFieldColor() );
+ GetDataWindow().SetFillColor( rStyleSettings.GetFieldColor() );
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool EditBrowseBox::IsCursorMoveAllowed(long nNewRow, sal_uInt16 nNewColId) const
+ {
+ sal_uInt16 nInfo = 0;
+
+ if (GetSelectColumnCount() || (aMouseEvent.Is() && aMouseEvent->GetRow() < 0))
+ nInfo |= COLSELECT;
+ if ((GetSelection() != NULL && GetSelectRowCount()) ||
+ (aMouseEvent.Is() && aMouseEvent->GetColumnId() == HANDLE_ID))
+ nInfo |= ROWSELECT;
+ if (!nInfo && nNewRow != nEditRow)
+ nInfo |= ROWCHANGE;
+ if (!nInfo && nNewColId != nEditCol)
+ nInfo |= COLCHANGE;
+
+ if (nInfo == 0) // nothing happened
+ return sal_True;
+
+ // save the cell content
+ if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified())
+ {
+ // maybe we're not visible ...
+ EnableAndShow();
+ aController->GetWindow().GrabFocus();
+ return sal_False;
+ }
+
+ EditBrowseBox * pTHIS = (EditBrowseBox *) this;
+
+ // save the cell content if
+ // a) a selection is beeing made
+ // b) the row is changing
+ if (IsModified() && (nInfo & (ROWCHANGE | COLSELECT | ROWSELECT)) &&
+ !pTHIS->SaveRow())
+ {
+ if (nInfo & COLSELECT ||
+ nInfo & ROWSELECT)
+ {
+ // cancel selected
+ pTHIS->SetNoSelection();
+ }
+
+ if (IsEditing())
+ {
+ if (!Controller()->GetWindow().IsVisible())
+ {
+ EnableAndShow();
+ }
+ aController->GetWindow().GrabFocus();
+ }
+ return sal_False;
+ }
+
+ if (nNewRow != nEditRow)
+ {
+ Window& rWindow = GetDataWindow();
+ // don't paint too much
+ // update the status immediatly if possible
+ if ((nEditRow >= 0) && (GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT) == 0)
+ {
+ Rectangle aRect = GetFieldRectPixel(nEditRow, 0, sal_False );
+ // status cell should be painted if and only if text is displayed
+ // note: bPaintStatus is mutable, but Solaris has problems with assigning
+ // probably because it is part of a bitfield
+ pTHIS->bPaintStatus = static_cast< sal_Bool >
+ (( GetBrowserFlags() & EBBF_HANDLE_COLUMN_TEXT ) == EBBF_HANDLE_COLUMN_TEXT );
+ rWindow.Paint(aRect);
+ pTHIS->bPaintStatus = sal_True;
+ }
+
+ // don't paint during row change
+ rWindow.EnablePaint(sal_False);
+
+ // the last veto chance for derived classes
+ if (!pTHIS->CursorMoving(nNewRow, nNewColId))
+ {
+ pTHIS->InvalidateStatusCell(nEditRow);
+ rWindow.EnablePaint(sal_True);
+ return sal_False;
+ }
+ else
+ {
+ rWindow.EnablePaint(sal_True);
+ return sal_True;
+ }
+ }
+ else
+ return pTHIS->CursorMoving(nNewRow, nNewColId);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ColumnMoved(sal_uInt16 nId)
+ {
+ BrowseBox::ColumnMoved(nId);
+ if (IsEditing())
+ {
+ Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False));
+ CellControllerRef aControllerRef = Controller();
+ ResizeController(aControllerRef, aRect);
+ Controller()->GetWindow().GrabFocus();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool EditBrowseBox::SaveRow()
+ {
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool EditBrowseBox::CursorMoving(long, sal_uInt16)
+ {
+ ((EditBrowseBox *) this)->DeactivateCell(sal_False);
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::CursorMoved()
+ {
+ long nNewRow = GetCurRow();
+ if (nEditRow != nNewRow)
+ {
+ if ((GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT) == 0)
+ InvalidateStatusCell(nNewRow);
+ nEditRow = nNewRow;
+ }
+ ActivateCell();
+ GetDataWindow().EnablePaint(sal_True);
+ // should not be called here because the descant event is not needed here
+ //BrowseBox::CursorMoved();
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::EndScroll()
+ {
+ if (IsEditing())
+ {
+ Rectangle aRect = GetCellRect(nEditRow, nEditCol, sal_False);
+ ResizeController(aController,aRect);
+ AsynchGetFocus();
+ }
+ BrowseBox::EndScroll();
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ActivateCell(long nRow, sal_uInt16 nCol, sal_Bool bCellFocus)
+ {
+ if (IsEditing())
+ return;
+
+ nEditCol = nCol;
+
+ if ((GetSelectRowCount() && GetSelection() != NULL) || GetSelectColumnCount() ||
+ (aMouseEvent.Is() && (aMouseEvent.IsDown() || aMouseEvent->GetClicks() > 1))) // bei MouseDown passiert noch nichts
+ {
+ return;
+ }
+
+ if (nEditRow >= 0 && nEditCol > HANDLE_ID)
+ {
+ aController = GetController(nRow, nCol);
+ if (aController.Is())
+ {
+ Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False));
+ ResizeController(aController, aRect);
+
+ InitController(aController, nEditRow, nEditCol);
+
+ aController->ClearModified();
+ aController->SetModifyHdl(LINK(this,EditBrowseBox,ModifyHdl));
+ EnableAndShow();
+
+ if ( isAccessibleAlive() )
+ implCreateActiveAccessible();
+
+ // activate the cell only of the browser has the focus
+ if ( bHasFocus && bCellFocus )
+ AsynchGetFocus();
+ }
+ else
+ {
+ // no controller -> we have a new "active descendant"
+ if ( isAccessibleAlive() && HasFocus() )
+ {
+ commitTableEvent(
+ ACTIVE_DESCENDANT_CHANGED,
+ makeAny( CreateAccessibleCell( nRow, GetColumnPos( nCol ) ) ),
+ Any()
+ );
+ }
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::DeactivateCell(sal_Bool bUpdate)
+ {
+ if (IsEditing())
+ {
+ if ( isAccessibleAlive() )
+ {
+ commitBrowseBoxEvent( CHILD, Any(), makeAny( m_aImpl->m_xActiveCell ) );
+ m_aImpl->clearActiveCell();
+ }
+
+ aOldController = aController;
+ aController.Clear();
+
+ // reset the modify handler
+ aOldController->SetModifyHdl(Link());
+
+ if (bHasFocus)
+ GrabFocus(); // ensure that we have (and keep) the focus
+
+ HideAndDisable(aOldController);
+
+ // update if requested
+ if (bUpdate)
+ Update();
+
+ nOldEditCol = nEditCol;
+ nOldEditRow = nEditRow;
+
+ // release the controller (asynchronously)
+ if (nEndEvent)
+ Application::RemoveUserEvent(nEndEvent);
+ nEndEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,EndEditHdl));
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ Rectangle EditBrowseBox::GetCellRect(long nRow, sal_uInt16 nColId, sal_Bool bRel) const
+ {
+ Rectangle aRect( GetFieldRectPixel(nRow, nColId, bRel));
+ if ((GetMode() & BROWSER_CURSOR_WO_FOCUS) == BROWSER_CURSOR_WO_FOCUS)
+ {
+ aRect.Top() += 1;
+ aRect.Bottom() -= 1;
+ }
+ return aRect;
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_LINK(EditBrowseBox, EndEditHdl, void*, EMPTYARG)
+ {
+ nEndEvent = 0;
+ ReleaseController(aOldController, nOldEditRow, nOldEditCol);
+
+ aOldController = CellControllerRef();
+ nOldEditRow = -1;
+ nOldEditCol = 0;
+
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_LINK(EditBrowseBox, ModifyHdl, void*, EMPTYARG)
+ {
+ if (nCellModifiedEvent)
+ Application::RemoveUserEvent(nCellModifiedEvent);
+ nCellModifiedEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,CellModifiedHdl));
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_LINK(EditBrowseBox, CellModifiedHdl, void*, EMPTYARG)
+ {
+ nCellModifiedEvent = 0;
+ CellModified();
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ColumnResized( sal_uInt16 )
+ {
+ if (IsEditing())
+ {
+ Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False));
+ CellControllerRef aControllerRef = Controller();
+ ResizeController(aControllerRef, aRect);
+ Controller()->GetWindow().GrabFocus();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_uInt16 EditBrowseBox::AppendColumn(const String& rName, sal_uInt16 nWidth, sal_uInt16 nPos, sal_uInt16 nId)
+ {
+ if (nId == (sal_uInt16)-1)
+ {
+ // look for the next free id
+ for (nId = ColCount(); nId > 0 && GetColumnPos(nId) != BROWSER_INVALIDID; nId--)
+ ;
+
+ if (!nId)
+ {
+ // if there is no handle column
+ // increment the id
+ if (!ColCount() || GetColumnId(0))
+ nId = ColCount() + 1;
+ }
+ }
+
+ DBG_ASSERT(nId, "EditBrowseBox::AppendColumn: invalid id!");
+
+ long w = nWidth;
+ if (!w)
+ w = GetDefaultColumnWidth(rName);
+
+ InsertDataColumn(nId, rName, w, (HIB_CENTER | HIB_VCENTER | HIB_CLICKABLE), nPos);
+ return nId;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::Resize()
+ {
+ BrowseBox::Resize();
+
+ // if the window is smaller than "title line height" + "control area",
+ // do nothing
+ if (GetOutputSizePixel().Height() <
+ (GetControlArea().GetHeight() + GetDataWindow().GetPosPixel().Y()))
+ return;
+
+ // the size of the control area
+ Point aPoint(GetControlArea().TopLeft());
+ sal_uInt16 nX = (sal_uInt16)aPoint.X();
+
+ ArrangeControls(nX, (sal_uInt16)aPoint.Y());
+
+ if (!nX)
+ nX = USHRT_MAX;
+ ReserveControlArea((sal_uInt16)nX);
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ArrangeControls(sal_uInt16&, sal_uInt16)
+ {
+ }
+
+ //------------------------------------------------------------------------------
+ CellController* EditBrowseBox::GetController(long, sal_uInt16)
+ {
+ return NULL;
+ }
+
+ //-----------------------------------------------------------------------------
+ void EditBrowseBox::ResizeController(CellControllerRef& rController, const Rectangle& rRect)
+ {
+ rController->GetWindow().SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::InitController(CellControllerRef&, long, sal_uInt16)
+ {
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::ReleaseController(CellControllerRef&, long, sal_uInt16)
+ {
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::CellModified()
+ {
+ }
+
+
+ //------------------------------------------------------------------------------
+ sal_Bool EditBrowseBox::SaveModified()
+ {
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::DoubleClick(const BrowserMouseEvent& rEvt)
+ {
+ // when double clicking on the column, the optimum size will be calculated
+ sal_uInt16 nColId = rEvt.GetColumnId();
+ if (nColId != HANDLE_ID)
+ SetColumnWidth(nColId, GetAutoColumnWidth(nColId));
+ }
+
+ //------------------------------------------------------------------------------
+ sal_uInt32 EditBrowseBox::GetAutoColumnWidth(sal_uInt16 nColId)
+ {
+ sal_uInt32 nCurColWidth = GetColumnWidth(nColId);
+ sal_uInt32 nMinColWidth = CalcZoom(20); // minimum
+ sal_uInt32 nNewColWidth = nMinColWidth;
+ long nMaxRows = Min(long(GetVisibleRows()), GetRowCount());
+ long nLastVisRow = GetTopRow() + nMaxRows - 1;
+
+ if (GetTopRow() <= nLastVisRow) // calc the column with using the cell contents
+ {
+ for (long i = GetTopRow(); i <= nLastVisRow; ++i)
+ nNewColWidth = std::max(nNewColWidth,GetTotalCellWidth(i,nColId) + 12);
+
+ if (nNewColWidth == nCurColWidth) // size has not changed
+ nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
+ }
+ else
+ nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
+ return nNewColWidth;
+ }
+
+ //------------------------------------------------------------------------------
+ sal_uInt32 EditBrowseBox::GetTotalCellWidth(long, sal_uInt16)
+ {
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::InvalidateHandleColumn()
+ {
+ Rectangle aHdlFieldRect( GetFieldRectPixel( 0, 0 ));
+ Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() );
+ aInvalidRect.Right() = aHdlFieldRect.Right();
+ Invalidate( aInvalidRect );
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::PaintTristate(OutputDevice&, const Rectangle& rRect,const TriState& eState,sal_Bool _bEnabled) const
+ {
+ pCheckBoxPaint->GetBox().SetState(eState);
+ pCheckBoxPaint->SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
+
+ // First update the parent, preventing that while painting this window
+ // an update for the parent is done (because it's in the queue already)
+ // which may lead to hiding this window immediately
+// #95598# comment out OJ
+/* if (pCheckBoxPaint->GetParent())
+ pCheckBoxPaint->GetParent()->Update();
+*/
+ pCheckBoxPaint->GetBox().Enable(_bEnabled);
+ pCheckBoxPaint->Show();
+ pCheckBoxPaint->SetParentUpdateMode( sal_False );
+ pCheckBoxPaint->Update();
+ pCheckBoxPaint->Hide();
+ pCheckBoxPaint->SetParentUpdateMode( sal_True );
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::AsynchGetFocus()
+ {
+ if (nStartEvent)
+ Application::RemoveUserEvent(nStartEvent);
+
+ m_pFocusWhileRequest = Application::GetFocusWindow();
+ nStartEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,StartEditHdl));
+ }
+
+ //------------------------------------------------------------------------------
+ void EditBrowseBox::SetBrowserFlags(sal_Int32 nFlags)
+ {
+ if (m_nBrowserFlags == nFlags)
+ return;
+
+ sal_Bool RowPicturesChanges = ((m_nBrowserFlags & EBBF_NO_HANDLE_COLUMN_CONTENT) !=
+ (nFlags & EBBF_NO_HANDLE_COLUMN_CONTENT));
+ m_nBrowserFlags = nFlags;
+
+ if (RowPicturesChanges)
+ InvalidateStatusCell(GetCurRow());
+ }
+ //------------------------------------------------------------------------------
+ inline void EditBrowseBox::HideAndDisable(CellControllerRef& rController)
+ {
+ rController->suspend();
+ }
+ //------------------------------------------------------------------------------
+ inline void EditBrowseBox::EnableAndShow() const
+ {
+ Controller()->resume();
+ }
+ //===============================================================================
+
+ DBG_NAME(CellController);
+ //------------------------------------------------------------------------------
+ CellController::CellController(Control* pW)
+ :pWindow( pW )
+ ,bSuspended( sal_True )
+ {
+ DBG_CTOR(CellController,NULL);
+
+ DBG_ASSERT(pWindow, "CellController::CellController: missing the window!");
+ DBG_ASSERT(!pWindow->IsVisible(), "CellController::CellController: window should not be visible!");
+ }
+
+ //-----------------------------------------------------------------------------
+ CellController::~CellController()
+ {
+
+ DBG_DTOR(CellController,NULL);
+ }
+
+ //-----------------------------------------------------------------------------
+ void CellController::suspend( )
+ {
+ DBG_ASSERT( bSuspended == !GetWindow().IsVisible(), "CellController::suspend: inconsistence!" );
+ if ( !isSuspended( ) )
+ {
+ CommitModifications();
+ GetWindow().Hide( );
+ GetWindow().Disable( );
+ bSuspended = sal_True;
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ void CellController::resume( )
+ {
+ DBG_ASSERT( bSuspended == !GetWindow().IsVisible(), "CellController::resume: inconsistence!" );
+ if ( isSuspended( ) )
+ {
+ GetWindow().Enable( );
+ GetWindow().Show( );
+ bSuspended = sal_False;
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ void CellController::CommitModifications()
+ {
+ // nothing to do in this base class
+ }
+
+ //-----------------------------------------------------------------------------
+ sal_Bool CellController::WantMouseEvent() const
+ {
+ return sal_False;
+ }
+
+ //-----------------------------------------------------------------------------
+ void CellController::SetModified()
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ sal_Bool CellController::MoveAllowed(const KeyEvent&) const
+ {
+ return sal_True;
+ }
+// .......................................................................
+} // namespace svt
+// .......................................................................
+
diff --git a/svtools/source/brwbox/editbrowsebox.hrc b/svtools/source/brwbox/editbrowsebox.hrc
new file mode 100644
index 000000000000..5902365b1b05
--- /dev/null
+++ b/svtools/source/brwbox/editbrowsebox.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.
+ *
+ ************************************************************************/
+
+#ifndef _SVTOOLS_EDITBROWSEBOX_HRC_
+#define _SVTOOLS_EDITBROWSEBOX_HRC_
+
+#define IMG_EBB_CURRENT 1
+#define IMG_EBB_MODIFIED 2
+#define IMG_EBB_NEW 3
+#define IMG_EBB_DELETED 4
+#define IMG_EBB_CURRENTNEW 5
+#define IMG_EBB_PRIMARYKEY 6
+#define IMG_EBB_CURRENT_PRIMARYKEY 7
+#define IMG_EBB_FILTER 8
+#define IMG_EBB_HEADERFOOTER 9
+
+#endif // _SVTOOLS_EDITBROWSEBOX_HRC_
+
diff --git a/svtools/source/brwbox/editbrowsebox.src b/svtools/source/brwbox/editbrowsebox.src
new file mode 100644
index 000000000000..6511d97ea86a
--- /dev/null
+++ b/svtools/source/brwbox/editbrowsebox.src
@@ -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 _SVTOOLS_EDITBROWSEBOX_HRC_
+#include "editbrowsebox.hrc"
+#endif
+
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+ImageList RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX
+{
+ Prefix = "ed";
+ MaskColor = Color {
+ Red = 0xFFFF;
+ Green = 0x0000;
+ Blue = 0xFFFF;
+ };
+ IdList = {
+ IMG_EBB_CURRENT; IMG_EBB_MODIFIED;
+ IMG_EBB_NEW;IMG_EBB_DELETED;IMG_EBB_CURRENTNEW;
+ IMG_EBB_PRIMARYKEY; IMG_EBB_CURRENT_PRIMARYKEY; IMG_EBB_FILTER;IMG_EBB_HEADERFOOTER;
+ };
+ IdCount = { 9; };
+};
+
+ImageList RID_SVTOOLS_IMAGELIST_EDITBWSEBOX_H
+{
+ Prefix = "edh";
+ MaskColor = Color {
+ Red = 0xFFFF;
+ Green = 0x0000;
+ Blue = 0xFFFF;
+ };
+ IdList = {
+ IMG_EBB_CURRENT; IMG_EBB_MODIFIED;
+ IMG_EBB_NEW;IMG_EBB_DELETED;IMG_EBB_CURRENTNEW;
+ IMG_EBB_PRIMARYKEY; IMG_EBB_CURRENT_PRIMARYKEY; IMG_EBB_FILTER;IMG_EBB_HEADERFOOTER;
+ };
+ IdCount = { 9; };
+};
diff --git a/svtools/source/brwbox/editbrowsebox2.cxx b/svtools/source/brwbox/editbrowsebox2.cxx
new file mode 100644
index 000000000000..ed62b2cb1520
--- /dev/null
+++ b/svtools/source/brwbox/editbrowsebox2.cxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/editbrowsebox.hxx>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include "editbrowseboximpl.hxx"
+#include <comphelper/types.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include "svtaccessiblefactory.hxx"
+
+namespace svt
+{
+ using namespace com::sun::star::accessibility;
+ using namespace com::sun::star::uno;
+ using namespace ::com::sun::star::accessibility::AccessibleEventId;
+
+// -----------------------------------------------------------------------------
+Reference< XAccessible > EditBrowseBox::CreateAccessibleCheckBoxCell(long _nRow, USHORT _nColumnPos,const TriState& eState,sal_Bool _bEnabled)
+{
+ Reference< XAccessible > xAccessible( GetAccessible() );
+ Reference< XAccessibleContext > xAccContext;
+ if ( xAccessible.is() )
+ xAccContext = xAccessible->getAccessibleContext();
+
+ Reference< XAccessible > xReturn;
+ if ( xAccContext.is() )
+ {
+ xReturn = getAccessibleFactory().createAccessibleCheckBoxCell(
+ xAccContext->getAccessibleChild( ::svt::BBINDEX_TABLE ),
+ *this,
+ NULL,
+ _nRow,
+ _nColumnPos,
+ eState,
+ _bEnabled,
+ sal_True
+ );
+ }
+ return xReturn;
+}
+// -----------------------------------------------------------------------------
+Reference< XAccessible > EditBrowseBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
+{
+ return BrowseBox::CreateAccessibleCell( _nRow, _nColumnPos );
+}
+// -----------------------------------------------------------------------------
+sal_Int32 EditBrowseBox::GetAccessibleControlCount() const
+{
+ return IsEditing() ? 1 : 0;
+}
+// -----------------------------------------------------------------------------
+void EditBrowseBox::implCreateActiveAccessible( )
+{
+ DBG_ASSERT( IsEditing(), "EditBrowseBox::implCreateActiveAccessible: not to be called if we're not editing currently!" );
+ DBG_ASSERT( !m_aImpl->m_xActiveCell.is(), "EditBrowseBox::implCreateActiveAccessible: not to be called if the old one is still alive!" );
+
+ if ( !m_aImpl->m_xActiveCell.is() && IsEditing() )
+ {
+ Reference< XAccessible > xCont = aController->GetWindow().GetAccessible();
+ Reference< XAccessible > xMy = GetAccessible();
+ if ( xMy.is() && xCont.is() )
+ {
+ m_aImpl->m_xActiveCell = getAccessibleFactory().createEditBrowseBoxTableCellAccess(
+ xMy, // parent accessible
+ xCont, // control accessible
+ VCLUnoHelper::GetInterface( &aController->GetWindow() ), // focus window (for notifications)
+ *this, // the browse box
+ GetCurRow(),
+ GetColumnPos( GetCurColumnId() )
+ );
+
+ commitBrowseBoxEvent( CHILD, makeAny( m_aImpl->m_xActiveCell ), Any() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+Reference< XAccessible > EditBrowseBox::CreateAccessibleControl( sal_Int32
+#ifdef DBG_UTIL
+_nIndex
+#endif
+)
+{
+ DBG_ASSERT( 0 == _nIndex, "EditBrowseBox::CreateAccessibleControl: invalid index!" );
+
+ if ( isAccessibleAlive() )
+ {
+ if ( !m_aImpl->m_xActiveCell.is() )
+ implCreateActiveAccessible();
+ }
+
+ return m_aImpl->m_xActiveCell;
+}
+// -----------------------------------------------------------------------------
+Reference<XAccessible > EditBrowseBox::CreateAccessibleRowHeader( sal_Int32 _nRow )
+{
+ return BrowseBox::CreateAccessibleRowHeader( _nRow );
+}
+// -----------------------------------------------------------------------------
+void EditBrowseBoxImpl::clearActiveCell()
+{
+ try
+ {
+ ::comphelper::disposeComponent(m_xActiveCell);
+ }
+ catch(const Exception&)
+ {
+ OSL_ENSURE( sal_False, "EditBrowseBoxImpl::clearActiveCell: caught an exception while disposing the AccessibleCell!" );
+ }
+
+ m_xActiveCell = NULL;
+}
+// -----------------------------------------------------------------------------
+void EditBrowseBox::GrabTableFocus()
+{
+ if ( aController.Is() )
+ aController->GetWindow().GrabFocus();
+}
+//------------------------------------------------------------------------------
+void EditBrowseBox::DetermineFocus( const sal_uInt16 _nGetFocusFlags )
+{
+ sal_Bool bFocus = sal_False;
+ for (Window* pWindow = Application::GetFocusWindow();
+ pWindow && !bFocus;
+ pWindow = pWindow->GetParent())
+ bFocus = pWindow == this;
+
+ if (bFocus != bHasFocus)
+ {
+ bHasFocus = bFocus;
+
+ if ( GetBrowserFlags( ) & EBBF_SMART_TAB_TRAVEL )
+ {
+ if ( bHasFocus // we got the focus
+ && ( _nGetFocusFlags & GETFOCUS_TAB ) // using the TAB key
+ )
+ {
+ long nRows = GetRowCount();
+ USHORT nCols = ColCount();
+
+ if ( ( nRows > 0 ) && ( nCols > 0 ) )
+ {
+ if ( _nGetFocusFlags & GETFOCUS_FORWARD )
+ {
+ if ( GetColumnId( 0 ) != 0 )
+ {
+ GoToRowColumnId( 0, GetColumnId( 0 ) );
+ }
+ else
+ { // the first column is the handle column -> not focussable
+ if ( nCols > 1 )
+ GoToRowColumnId( 0, GetColumnId( 1 ) );
+ }
+ }
+ else if ( _nGetFocusFlags & GETFOCUS_BACKWARD )
+ {
+ GoToRowColumnId( nRows - 1, GetColumnId( nCols -1 ) );
+ }
+ }
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+Rectangle EditBrowseBox::GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 _nIndex)
+{
+ Rectangle aRect;
+ if ( SeekRow(_nRow) )
+ {
+ CellController* pController = GetController(
+ _nRow, GetColumnId( sal::static_int_cast< USHORT >(_nColumnPos) ) );
+ if ( pController )
+ aRect = pController->GetWindow().GetCharacterBounds(_nIndex);
+ }
+ return aRect;
+}
+// -----------------------------------------------------------------------------
+sal_Int32 EditBrowseBox::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
+{
+ sal_Int32 nRet = -1;
+ if ( SeekRow(_nRow) )
+ {
+ CellController* pController = GetController(
+ _nRow, GetColumnId( sal::static_int_cast< USHORT >(_nColumnPos) ) );
+ if ( pController )
+ nRet = pController->GetWindow().GetIndexForPoint(_rPoint);
+ }
+ return nRet;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+} // namespace svt
+// -----------------------------------------------------------------------------
+
+
diff --git a/svtools/source/brwbox/editbrowseboximpl.hxx b/svtools/source/brwbox/editbrowseboximpl.hxx
new file mode 100644
index 000000000000..724da694b9c1
--- /dev/null
+++ b/svtools/source/brwbox/editbrowseboximpl.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 SVTOOLS_EDITBROWSEBOX_IMPL_HXX
+#define SVTOOLS_EDITBROWSEBOX_IMPL_HXX
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+namespace svt
+{
+ // impl class for the class EditBrowseBox
+ class EditBrowseBoxImpl
+ {
+ public:
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > m_xActiveCell;
+ sal_Bool m_bHiContrast;
+
+ void clearActiveCell();
+ };
+}
+#endif // SVTOOLS_EDITBROWSEBOX_IMPL_HXX
+
diff --git a/svtools/source/brwbox/makefile.mk b/svtools/source/brwbox/makefile.mk
new file mode 100644
index 000000000000..e195e0ef4859
--- /dev/null
+++ b/svtools/source/brwbox/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=svtools
+TARGET=browse
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES= editbrowsebox.src
+
+EXCEPTIONSFILES =\
+ $(SLO)$/editbrowsebox2.obj \
+ $(SLO)$/brwbox1.obj \
+ $(SLO)$/brwbox3.obj
+
+SLOFILES= \
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/ebbcontrols.obj \
+ $(SLO)$/editbrowsebox.obj \
+ $(SLO)$/brwbox2.obj \
+ $(SLO)$/brwhead.obj \
+ $(SLO)$/datwin.obj
+
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/config/accessibilityoptions.cxx b/svtools/source/config/accessibilityoptions.cxx
new file mode 100644
index 000000000000..b2d2c54232b0
--- /dev/null
+++ b/svtools/source/config/accessibilityoptions.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_svtools.hxx"
+
+#include <svtools/accessibilityoptions.hxx>
+#include "configitems/accessibilityoptions_const.hxx"
+
+#include <unotools/configmgr.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
+#include <com/sun/star/container/XNameAccess.hpp>
+#endif
+#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
+#include <comphelper/configurationhelper.hxx>
+#endif
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
+#include <unotools/processfactory.hxx>
+#endif
+#ifndef _SVT_LOGHELPER_HXX_
+#include <unotools/loghelper.hxx>
+#endif
+
+#include <svl/smplhint.hxx>
+
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/instance.hxx>
+
+#include <itemholder2.hxx>
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+namespace css = com::sun::star;
+
+#define HELP_TIP_TIMEOUT 0xffff // max. timeout setting to pretend a non-timeout
+
+
+// class SvtAccessibilityOptions_Impl ---------------------------------------------
+
+class SvtAccessibilityOptions_Impl
+{
+private:
+ css::uno::Reference< css::container::XNameAccess > m_xCfg;
+ sal_Bool bIsModified;
+
+public:
+ SvtAccessibilityOptions_Impl();
+ ~SvtAccessibilityOptions_Impl();
+
+ void SetVCLSettings();
+ sal_Bool GetAutoDetectSystemHC();
+ sal_Bool GetIsForPagePreviews() const;
+ sal_Bool GetIsHelpTipsDisappear() const;
+ sal_Bool GetIsAllowAnimatedGraphics() const;
+ sal_Bool GetIsAllowAnimatedText() const;
+ sal_Bool GetIsAutomaticFontColor() const;
+ sal_Bool GetIsSystemFont() const;
+ sal_Int16 GetHelpTipSeconds() const;
+ sal_Bool IsSelectionInReadonly() const;
+
+ void SetAutoDetectSystemHC(sal_Bool bSet);
+ void SetIsForPagePreviews(sal_Bool bSet);
+ void SetIsHelpTipsDisappear(sal_Bool bSet);
+ void SetIsAllowAnimatedGraphics(sal_Bool bSet);
+ void SetIsAllowAnimatedText(sal_Bool bSet);
+ void SetIsAutomaticFontColor(sal_Bool bSet);
+ void SetIsSystemFont(sal_Bool bSet);
+ void SetHelpTipSeconds(sal_Int16 nSet);
+ void SetSelectionInReadonly(sal_Bool bSet);
+
+ sal_Bool IsModified() const { return bIsModified; };
+};
+
+// initialization of static members --------------------------------------
+
+SvtAccessibilityOptions_Impl* volatile SvtAccessibilityOptions::sm_pSingleImplConfig =NULL;
+sal_Int32 volatile SvtAccessibilityOptions::sm_nAccessibilityRefCount(0);
+
+namespace
+{
+ struct SingletonMutex
+ : public rtl::Static< ::osl::Mutex, SingletonMutex > {};
+}
+
+// -----------------------------------------------------------------------
+// class SvtAccessibilityOptions_Impl ---------------------------------------------
+
+SvtAccessibilityOptions_Impl::SvtAccessibilityOptions_Impl()
+{
+ try
+ {
+ m_xCfg = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(
+ utl::getProcessServiceFactory(),
+ s_sAccessibility,
+ ::comphelper::ConfigurationHelper::E_STANDARD),
+ css::uno::UNO_QUERY);
+
+ bIsModified = sal_False;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ m_xCfg.clear();
+ LogHelper::logIt(ex);
+ }
+}
+
+SvtAccessibilityOptions_Impl::~SvtAccessibilityOptions_Impl()
+{
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvtAccessibilityOptions_Impl::GetAutoDetectSystemHC()
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sAutoDetectSystemHC) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::GetIsForPagePreviews() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsForPagePreviews) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+ return bRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::GetIsHelpTipsDisappear() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsHelpTipsDisappear) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::GetIsAllowAnimatedGraphics() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsAllowAnimatedGraphics) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::GetIsAllowAnimatedText() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsAllowAnimatedText) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::GetIsAutomaticFontColor() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsAutomaticFontColor) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::GetIsSystemFont() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsSystemFont) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Int16 SvtAccessibilityOptions_Impl::GetHelpTipSeconds() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Int16 nRet = 4;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sHelpTipSeconds) >>= nRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return nRet;
+}
+
+sal_Bool SvtAccessibilityOptions_Impl::IsSelectionInReadonly() const
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ if(xNode.is())
+ xNode->getPropertyValue(s_sIsSelectionInReadonly) >>= bRet;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+void SvtAccessibilityOptions_Impl::SetAutoDetectSystemHC(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sAutoDetectSystemHC)!=bSet)
+ {
+ xNode->setPropertyValue(s_sAutoDetectSystemHC, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetIsForPagePreviews(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsForPagePreviews)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsForPagePreviews, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetIsHelpTipsDisappear(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsHelpTipsDisappear)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsHelpTipsDisappear, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetIsAllowAnimatedGraphics(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsAllowAnimatedGraphics)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsAllowAnimatedGraphics, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetIsAllowAnimatedText(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsAllowAnimatedText)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsAllowAnimatedText, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetIsAutomaticFontColor(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsAutomaticFontColor)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsAutomaticFontColor, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetIsSystemFont(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsSystemFont)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsSystemFont, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetHelpTipSeconds(sal_Int16 nSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sHelpTipSeconds)!=nSet)
+ {
+ xNode->setPropertyValue(s_sHelpTipSeconds, css::uno::makeAny(nSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetSelectionInReadonly(sal_Bool bSet)
+{
+ css::uno::Reference< css::beans::XPropertySet > xNode(m_xCfg, css::uno::UNO_QUERY);
+
+ try
+ {
+ if(xNode.is() && xNode->getPropertyValue(s_sIsSelectionInReadonly)!=bSet)
+ {
+ xNode->setPropertyValue(s_sIsSelectionInReadonly, css::uno::makeAny(bSet));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+
+ bIsModified = sal_True;
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtAccessibilityOptions_Impl::SetVCLSettings()
+{
+ AllSettings aAllSettings = Application::GetSettings();
+ HelpSettings aHelpSettings = aAllSettings.GetHelpSettings();
+ aHelpSettings.SetTipTimeout( GetIsHelpTipsDisappear() ? GetHelpTipSeconds() * 1000 : HELP_TIP_TIMEOUT);
+ aAllSettings.SetHelpSettings(aHelpSettings);
+ if(aAllSettings.GetStyleSettings().GetUseSystemUIFonts() != GetIsSystemFont() )
+ {
+ StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
+ aStyleSettings.SetUseSystemUIFonts( GetIsSystemFont() );
+ aAllSettings.SetStyleSettings(aStyleSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ }
+
+ Application::SetSettings(aAllSettings);
+}
+
+// -----------------------------------------------------------------------
+// class SvtAccessibilityOptions --------------------------------------------------
+
+SvtAccessibilityOptions::SvtAccessibilityOptions()
+{
+ {
+ ::osl::MutexGuard aGuard( SingletonMutex::get() );
+ if(!sm_pSingleImplConfig)
+ {
+ sm_pSingleImplConfig = new SvtAccessibilityOptions_Impl;
+ ItemHolder2::holdConfigItem(E_ACCESSIBILITYOPTIONS);
+ }
+ ++sm_nAccessibilityRefCount;
+ }
+ //StartListening( *sm_pSingleImplConfig, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+SvtAccessibilityOptions::~SvtAccessibilityOptions()
+{
+ //EndListening( *sm_pSingleImplConfig, TRUE );
+ ::osl::MutexGuard aGuard( SingletonMutex::get() );
+ if( !--sm_nAccessibilityRefCount )
+ {
+ //if( sm_pSingleImplConfig->IsModified() )
+ // sm_pSingleImplConfig->Commit();
+ DELETEZ( sm_pSingleImplConfig );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvtAccessibilityOptions::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ NotifyListeners(0);
+ if ( rHint.IsA(TYPE(SfxSimpleHint)) )
+ {
+ if ( ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_ACCESSIBILITY_CHANGED )
+ SetVCLSettings();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvtAccessibilityOptions::IsModified() const
+{
+ return sm_pSingleImplConfig->IsModified();
+}
+void SvtAccessibilityOptions::Commit()
+{
+ //sm_pSingleImplConfig->Commit();
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvtAccessibilityOptions::GetIsForDrawings() const
+{
+ DBG_ERROR( "SvtAccessibilityOptions::GetIsForDrawings: is obsolete!" );
+ return sal_False;
+}
+sal_Bool SvtAccessibilityOptions::GetIsForBorders() const
+{
+ DBG_ERROR( "SvtAccessibilityOptions::GetIsForBorders: is obsolete!" );
+ return sal_False;
+}
+sal_Bool SvtAccessibilityOptions::GetAutoDetectSystemHC() const
+{
+ return sm_pSingleImplConfig->GetAutoDetectSystemHC();
+}
+sal_Bool SvtAccessibilityOptions::GetIsForPagePreviews() const
+{
+ return sm_pSingleImplConfig->GetIsForPagePreviews();
+}
+sal_Bool SvtAccessibilityOptions::GetIsHelpTipsDisappear() const
+{
+ return sm_pSingleImplConfig->GetIsHelpTipsDisappear();
+}
+sal_Bool SvtAccessibilityOptions::GetIsAllowAnimatedGraphics() const
+{
+ return sm_pSingleImplConfig->GetIsAllowAnimatedGraphics();
+}
+sal_Bool SvtAccessibilityOptions::GetIsAllowAnimatedText() const
+{
+ return sm_pSingleImplConfig->GetIsAllowAnimatedText();
+}
+sal_Bool SvtAccessibilityOptions::GetIsAutomaticFontColor() const
+{
+ return sm_pSingleImplConfig->GetIsAutomaticFontColor();
+}
+sal_Bool SvtAccessibilityOptions::GetIsSystemFont() const
+{
+ return sm_pSingleImplConfig->GetIsSystemFont();
+}
+sal_Int16 SvtAccessibilityOptions::GetHelpTipSeconds() const
+{
+ return sm_pSingleImplConfig->GetHelpTipSeconds();
+}
+sal_Bool SvtAccessibilityOptions::IsSelectionInReadonly() const
+{
+ return sm_pSingleImplConfig->IsSelectionInReadonly();
+}
+
+// -----------------------------------------------------------------------
+void SvtAccessibilityOptions::SetAutoDetectSystemHC(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetAutoDetectSystemHC(bSet);
+}
+void SvtAccessibilityOptions::SetIsForPagePreviews(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetIsForPagePreviews(bSet);
+}
+void SvtAccessibilityOptions::SetIsHelpTipsDisappear(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetIsHelpTipsDisappear(bSet);
+}
+void SvtAccessibilityOptions::SetIsAllowAnimatedGraphics(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetIsAllowAnimatedGraphics(bSet);
+}
+void SvtAccessibilityOptions::SetIsAllowAnimatedText(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetIsAllowAnimatedText(bSet);
+}
+void SvtAccessibilityOptions::SetIsAutomaticFontColor(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetIsAutomaticFontColor(bSet);
+}
+void SvtAccessibilityOptions::SetIsSystemFont(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetIsSystemFont(bSet);
+}
+void SvtAccessibilityOptions::SetHelpTipSeconds(sal_Int16 nSet)
+{
+ sm_pSingleImplConfig->SetHelpTipSeconds(nSet);
+}
+void SvtAccessibilityOptions::SetSelectionInReadonly(sal_Bool bSet)
+{
+ sm_pSingleImplConfig->SetSelectionInReadonly(bSet);
+}
+
+void SvtAccessibilityOptions::SetVCLSettings()
+{
+ sm_pSingleImplConfig->SetVCLSettings();
+}
+// -----------------------------------------------------------------------
diff --git a/svtools/source/config/apearcfg.cxx b/svtools/source/config/apearcfg.cxx
new file mode 100644
index 000000000000..316e6ab34656
--- /dev/null
+++ b/svtools/source/config/apearcfg.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "apearcfg.hxx"
+#include "com/sun/star/uno/Any.hxx"
+
+#include "tools/debug.hxx"
+#include "vcl/settings.hxx"
+#include "vcl/svapp.hxx"
+#include <rtl/logfile.hxx>
+
+#define DEFAULT_LOOKNFEEL 0
+#define DEFAULT_DRAGMODE 2
+#define DEFAULT_SNAPMODE 0
+#define DEFAULT_SCALEFACTOR 100
+#define DEFAULT_AAMINHEIGHT 8
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+sal_Bool SvtTabAppearanceCfg::bInitialized = sal_False;
+
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+SvtTabAppearanceCfg::SvtTabAppearanceCfg()
+ :ConfigItem(OUString::createFromAscii("Office.Common/View"))
+ ,nLookNFeel ( DEFAULT_LOOKNFEEL )
+ ,nDragMode ( DEFAULT_DRAGMODE )
+ ,nScaleFactor ( DEFAULT_SCALEFACTOR )
+ ,nSnapMode ( DEFAULT_SNAPMODE )
+ ,nMiddleMouse ( MOUSE_MIDDLE_AUTOSCROLL )
+#if defined( UNX ) || defined ( FS_PRIV_DEBUG )
+ ,nAAMinPixelHeight ( DEFAULT_AAMINHEIGHT )
+#endif
+ ,bMenuMouseFollow(FALSE)
+ ,bSingleLineTabCtrl(FALSE)
+ ,bColoredTabCtrl(FALSE)
+#if defined( UNX ) || defined ( FS_PRIV_DEBUG )
+ ,bFontAntialiasing ( TRUE )
+#endif
+{
+ RTL_LOGFILE_CONTEXT(aLog, "svtools SvtTabAppearanceCfg::SvtTabAppearanceCfg()");
+
+ const Sequence<OUString>& rNames = GetPropertyNames();
+ Sequence<Any> aValues = GetProperties(rNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == rNames.getLength(), "GetProperties failed");
+
+ if(aValues.getLength() == rNames.getLength())
+ {
+ for(int nProp = 0; nProp < rNames.getLength(); ++nProp, ++pValues)
+ {
+ if(pValues->hasValue())
+ {
+ switch(nProp)
+ {
+ case 0: *pValues >>= nScaleFactor; break; //"FontScaling",
+ case 1: *pValues >>= nLookNFeel; break; //"LookAndFeel",
+ case 2: *pValues >>= nDragMode; break; //"Window/Drag",
+ case 3: bMenuMouseFollow = *(sal_Bool*)pValues->getValue(); break; //"Menu/FollowMouse",
+ case 4: bSingleLineTabCtrl = *(sal_Bool*)pValues->getValue(); break; //"Dialog/SingleLineTab",
+ case 5: bColoredTabCtrl = *(sal_Bool*)pValues->getValue(); break; //"Dialog/ColoredTab",
+ case 6: *pValues >>= nSnapMode; break; //"Dialog/MousePositioning",
+ case 7: *pValues >>= nMiddleMouse; break; //"Dialog/MiddleMouseButton",
+#if defined( UNX ) || defined ( FS_PRIV_DEBUG )
+ case 8: bFontAntialiasing = *(sal_Bool*)pValues->getValue(); break; // "FontAntialising/Enabled",
+ case 9: *pValues >>= nAAMinPixelHeight; break; // "FontAntialising/MinPixelHeight",
+#endif
+ }
+ }
+ }
+ }
+}
+/* -----------------------------22.05.01 11:53--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvtTabAppearanceCfg::~SvtTabAppearanceCfg( )
+{
+}
+/* -----------------------------22.05.01 11:54--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const Sequence<OUString>& SvtTabAppearanceCfg::GetPropertyNames()
+{
+ static Sequence<OUString> aNames;
+ if(!aNames.getLength())
+ {
+ static const sal_Char* aPropNames[] =
+ {
+ "FontScaling" // 0
+ ,"LookAndFeel" // 1
+ ,"Window/Drag" // 2
+ ,"Menu/FollowMouse" // 3
+ ,"Dialog/SingleLineTab" // 4
+ ,"Dialog/ColoredTab" // 5
+ ,"Dialog/MousePositioning" // 6
+ ,"Dialog/MiddleMouseButton" // 7
+#if defined( UNX ) || defined ( FS_PRIV_DEBUG )
+ ,"FontAntiAliasing/Enabled" // 8
+ ,"FontAntiAliasing/MinPixelHeight" // 9
+#endif
+ };
+ const int nCount = sizeof( aPropNames ) / sizeof( aPropNames[0] );
+ aNames.realloc(nCount);
+
+ const sal_Char** pAsciiNames = aPropNames;
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < nCount; ++i, ++pNames, ++pAsciiNames)
+ *pNames = OUString::createFromAscii( *pAsciiNames );
+ }
+ return aNames;
+}
+/* -----------------------------22.05.01 11:54--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SvtTabAppearanceCfg::Commit()
+{
+ const Sequence<OUString>& rNames = GetPropertyNames();
+ Sequence<Any> aValues(rNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ const Type& rType = ::getBooleanCppuType();
+ for(int nProp = 0; nProp < rNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case 0: pValues[nProp] <<= nScaleFactor; break; // "FontScaling",
+ case 1: pValues[nProp] <<= nLookNFeel; break; //"LookAndFeel",
+ case 2: pValues[nProp] <<= nDragMode; break; //"Window/Drag",
+ case 3: pValues[nProp].setValue(&bMenuMouseFollow, rType); break; //"Menu/FollowMouse",
+ case 4: pValues[nProp].setValue(&bSingleLineTabCtrl, rType); break; //"Dialog/SingleLineTab",
+ case 5: pValues[nProp].setValue(&bColoredTabCtrl, rType); break; //"Dialog/ColoredTab",
+ case 6: pValues[nProp] <<= nSnapMode; break; //"Dialog/MousePositioning",
+ case 7: pValues[nProp] <<= nMiddleMouse; break; //"Dialog/MiddleMouseButton",
+#if defined( UNX ) || defined ( FS_PRIV_DEBUG )
+ case 8: pValues[nProp].setValue(&bFontAntialiasing, rType); break; // "FontAntialising/Enabled",
+ case 9: pValues[nProp] <<= nAAMinPixelHeight; break; // "FontAntialising/MinPixelHeight",
+#endif
+ }
+ }
+ PutProperties(rNames, aValues);
+}
+
+void SvtTabAppearanceCfg::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
+{
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SvtTabAppearanceCfg::SetLookNFeel ( USHORT nSet )
+{
+ nLookNFeel = nSet;
+ SetModified();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SvtTabAppearanceCfg::SetDragMode ( USHORT nSet )
+{
+ nDragMode = nSet;
+ SetModified();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SvtTabAppearanceCfg::SetScaleFactor ( USHORT nSet )
+{
+ nScaleFactor = nSet;
+ SetModified();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SvtTabAppearanceCfg::SetSnapMode ( USHORT nSet )
+{
+ nSnapMode = nSet;
+ SetModified();
+}
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+void SvtTabAppearanceCfg::SetMiddleMouseButton ( USHORT nSet )
+{
+ nMiddleMouse = nSet;
+ SetModified();
+}
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SvtTabAppearanceCfg::SetApplicationDefaults ( Application* pApp )
+{
+ AllSettings hAppSettings = pApp->GetSettings();
+ StyleSettings hAppStyle = hAppSettings.GetStyleSettings();
+
+ // Look & Feel
+
+ // SetStandard...Styles() resets the UseSystemUIFonts flag,
+ // but we don't want to change it now, so save the flag before ...
+ BOOL bUseSystemUIFonts = hAppStyle.GetUseSystemUIFonts();
+
+ switch ( nLookNFeel )
+ {
+ case LookMotif:
+ hAppStyle.SetStandardUnixStyles(); break;
+
+ case LookOSTwo:
+ hAppStyle.SetStandardOS2Styles(); break;
+
+ case LookMacintosh:
+ hAppStyle.SetStandardMacStyles(); break;
+
+ case LookWindows:
+ hAppStyle.SetStandardWinStyles(); break;
+
+ case LookStardivision:
+ default:
+ hAppStyle.SetStandardStyles(); break;
+ }
+
+ // and set it here
+ hAppStyle.SetUseSystemUIFonts( bUseSystemUIFonts );
+
+ // Screen and ScreenFont Scaling
+
+ hAppStyle.SetScreenZoom( nScaleFactor );
+ hAppStyle.SetScreenFontZoom( nScaleFactor );
+
+#if defined( UNX ) || defined ( FS_PRIV_DEBUG )
+ // font anti aliasing
+ hAppStyle.SetAntialiasingMinPixelHeight( nAAMinPixelHeight );
+ hAppStyle.SetDisplayOptions( bFontAntialiasing ? 0 : DISPLAY_OPTION_AA_DISABLE );
+#endif
+
+ // Mouse Snap
+
+ MouseSettings hMouseSettings = hAppSettings.GetMouseSettings();
+ ULONG nMouseOptions = hMouseSettings.GetOptions();
+
+ nMouseOptions &= ! (MOUSE_OPTION_AUTOCENTERPOS | MOUSE_OPTION_AUTODEFBTNPOS);
+
+ switch ( nSnapMode )
+ {
+ case SnapToButton:
+ nMouseOptions |= MOUSE_OPTION_AUTODEFBTNPOS;
+ break;
+ case SnapToMiddle:
+ nMouseOptions |= MOUSE_OPTION_AUTOCENTERPOS;
+ break;
+ case NoSnap:
+ default:
+ break;
+ }
+ hMouseSettings.SetOptions(nMouseOptions);
+ hMouseSettings.SetMiddleButtonAction(nMiddleMouse);
+
+ // Merge and Publish Settings
+
+ ULONG nFollow = hMouseSettings.GetFollow();
+ if(bMenuMouseFollow)
+ nFollow |= MOUSE_FOLLOW_MENU;
+ else
+ nFollow &= ~MOUSE_FOLLOW_MENU;
+ hMouseSettings.SetFollow( nFollow );
+ sal_uInt16 nTabStyle = 0;
+ if(bSingleLineTabCtrl)
+ nTabStyle |= STYLE_TABCONTROL_SINGLELINE;
+
+ if(bColoredTabCtrl)
+ nTabStyle |= STYLE_TABCONTROL_COLOR;
+ hAppStyle.SetTabControlStyle(nTabStyle);
+
+
+ hAppSettings.SetMouseSettings( hMouseSettings );
+
+ hAppSettings.SetStyleSettings( hAppStyle );
+ pApp->MergeSystemSettings ( hAppSettings ); // Allow system-settings to apply
+ pApp->SystemSettingsChanging ( hAppSettings, NULL );// Allow overruling of system-settings
+ //is concerned with window drag
+
+ pApp->SetSettings ( hAppSettings );
+}
+
+
+
diff --git a/svtools/source/config/colorcfg.cxx b/svtools/source/config/colorcfg.cxx
new file mode 100644
index 000000000000..7a151d609e6e
--- /dev/null
+++ b/svtools/source/config/colorcfg.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_svtools.hxx"
+
+#include <svtools/colorcfg.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <tools/color.hxx>
+#include <tools/debug.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/configpathes.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <svl/poolitem.hxx> //Any2Bool
+#include <svl/smplhint.hxx>
+#include <vos/mutex.hxx>
+
+#include <itemholder2.hxx>
+
+ /* #100822# ----
+#include <vcl/wrkwin.hxx>
+ ------------- */
+#include <vcl/svapp.hxx>
+#include <vcl/event.hxx>
+#include <rtl/instance.hxx>
+
+//-----------------------------------------------------------------------------
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star;
+
+namespace svtools
+{
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+static const sal_Char cColor[] = "/Color";
+static const sal_Char cColorSchemes[] = "ColorSchemes/";
+sal_Int32 nColorRefCount_Impl = 0;
+namespace
+{
+ struct ColorMutex_Impl
+ : public rtl::Static< ::osl::Mutex, ColorMutex_Impl > {};
+}
+
+ColorConfig_Impl* ColorConfig::m_pImpl = NULL;
+
+/* -----------------------------16.01.01 15:36--------------------------------
+ ---------------------------------------------------------------------------*/
+class ColorConfig_Impl : public utl::ConfigItem
+{
+ ColorConfigValue m_aConfigValues[ColorConfigEntryCount];
+ sal_Bool m_bEditMode;
+ rtl::OUString m_sIsVisible;
+ rtl::OUString m_sLoadedScheme;
+
+ uno::Sequence< ::rtl::OUString> GetPropertyNames(const rtl::OUString& rScheme);
+public:
+ ColorConfig_Impl(sal_Bool bEditMode = sal_False);
+ virtual ~ColorConfig_Impl();
+
+ void Load(const rtl::OUString& rScheme);
+ void CommitCurrentSchemeName();
+ //changes the name of the current scheme but doesn't load it!
+ void SetCurrentSchemeName(const rtl::OUString& rSchemeName) {m_sLoadedScheme = rSchemeName;}
+ virtual void Commit();
+ virtual void Notify( const uno::Sequence<rtl::OUString>& aPropertyNames);
+
+ const ColorConfigValue& GetColorConfigValue(ColorConfigEntry eValue)
+ {return m_aConfigValues[eValue];}
+ void SetColorConfigValue(ColorConfigEntry eValue,
+ const ColorConfigValue& rValue );
+
+ const rtl::OUString& GetLoadedScheme() const {return m_sLoadedScheme;}
+
+ uno::Sequence< ::rtl::OUString> GetSchemeNames();
+
+ sal_Bool AddScheme(const rtl::OUString& rNode);
+ sal_Bool RemoveScheme(const rtl::OUString& rNode);
+ void SetModified(){ConfigItem::SetModified();}
+ void ClearModified(){ConfigItem::ClearModified();}
+ void SettingsChanged();
+
+ // #100822#
+ DECL_LINK( DataChangedEventListener, VclWindowEvent* );
+
+ void ImplUpdateApplicationSettings();
+};
+
+/* -----------------------------16.01.01 15:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< OUString> ColorConfig_Impl::GetPropertyNames(const rtl::OUString& rScheme)
+{
+ uno::Sequence<OUString> aNames(2 * ColorConfigEntryCount);
+ OUString* pNames = aNames.getArray();
+ struct ColorConfigEntryData_Impl
+ {
+ const sal_Char* cName;
+ sal_Int32 nLength;
+ rtl_TextEncoding eEncoding;
+ sal_Bool bCanBeVisible;
+ };
+ static const ColorConfigEntryData_Impl cNames[] =
+ {
+ { RTL_CONSTASCII_USTRINGPARAM("/DocColor") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/DocBoundaries") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/AppBackground") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/ObjectBoundaries"),sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/TableBoundaries") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/FontColor") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/Links") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/LinksVisited") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/Anchor") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/Spell") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SmartTags") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterTextGrid") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterFieldShadings"),sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterIdxShadings") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterDirectCursor") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterScriptIndicator") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterSectionBoundaries") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/WriterPageBreaks") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/HTMLSGML") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/HTMLComment") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/HTMLKeyword") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/HTMLUnknown") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcGrid") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreak"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreakManual"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreakAutomatic"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcDetective") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcDetectiveError") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcReference") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/CalcNotesBackground") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/DrawGrid") ,sal_True },
+ { RTL_CONSTASCII_USTRINGPARAM("/DrawDrawing") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/DrawFill") ,sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICIdentifier"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICComment") , sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICNumber") , sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICString") , sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICOperator") , sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICKeyword") , sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/BASICError"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLIdentifier"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLNumber"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLString"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLOperator"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLKeyword"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLParameter"), sal_False },
+ { RTL_CONSTASCII_USTRINGPARAM("/SQLComment"), sal_False }
+ };
+ int nIndex = 0;
+ OUString sColor = C2U(cColor);
+ OUString sBase(C2U(cColorSchemes));
+ sBase += utl::wrapConfigurationElementName(rScheme);
+ const int nCount = ColorConfigEntryCount;
+ for(sal_Int32 i = 0; i < 4 * nCount; i+= 4)
+ {
+ rtl::OUString sBaseName(sBase);
+ sal_Int32 nPos = i / 4;
+ sBaseName += OUString(cNames[nPos].cName, cNames[nPos].nLength, cNames[nPos].eEncoding);
+ pNames[nIndex] += sBaseName;
+ pNames[nIndex++] += sColor;
+ if(cNames[nPos].bCanBeVisible)
+ {
+ pNames[nIndex] += sBaseName;
+ pNames[nIndex++] += m_sIsVisible;
+ }
+ }
+ aNames.realloc(nIndex);
+ return aNames;
+}
+/* -----------------------------22.03.2002 14:37------------------------------
+
+ ---------------------------------------------------------------------------*/
+ColorConfig_Impl::ColorConfig_Impl(sal_Bool bEditMode) :
+ ConfigItem(C2U("Office.UI/ColorScheme")),
+ m_bEditMode(bEditMode),
+ m_sIsVisible(C2U("/IsVisible"))
+{
+ if(!m_bEditMode)
+ {
+ //try to register on the root node - if possible
+ uno::Sequence < ::rtl::OUString > aNames(1);
+ EnableNotification( aNames );
+ }
+ Load(::rtl::OUString());
+
+ ImplUpdateApplicationSettings();
+
+ // #100822#
+ ::Application::AddEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) );
+
+}
+/* -----------------------------25.03.2002 12:28------------------------------
+
+ ---------------------------------------------------------------------------*/
+ColorConfig_Impl::~ColorConfig_Impl()
+{
+ // #100822#
+ ::Application::RemoveEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) );
+}
+/* -----------------------------22.03.2002 14:38------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ColorConfig_Impl::Load(const rtl::OUString& rScheme)
+{
+ rtl::OUString sScheme(rScheme);
+ if(!sScheme.getLength())
+ {
+ //detect current scheme name
+ uno::Sequence < ::rtl::OUString > aCurrent(1);
+ aCurrent.getArray()[0] = C2U("CurrentColorScheme");
+ uno::Sequence< uno::Any > aCurrentVal = GetProperties( aCurrent );
+ aCurrentVal.getConstArray()[0] >>= sScheme;
+ }
+ m_sLoadedScheme = sScheme;
+ //
+ uno::Sequence < ::rtl::OUString > aColorNames = GetPropertyNames(sScheme);
+ uno::Sequence< uno::Any > aColors = GetProperties( aColorNames );
+ const uno::Any* pColors = aColors.getConstArray();
+ const ::rtl::OUString* pColorNames = aColorNames.getConstArray();
+ sal_Int32 nIndex = 0;
+ for(int i = 0; i < 2 * ColorConfigEntryCount && aColors.getLength() > nIndex; i+= 2)
+ {
+ if(pColors[nIndex].hasValue())
+ pColors[nIndex] >>= m_aConfigValues[i / 2].nColor;
+ else
+ m_aConfigValues[i/2].nColor = COL_AUTO;
+ nIndex++;
+ if(nIndex >= aColors.getLength())
+ break;
+ //test for visibility property
+ if(pColorNames[nIndex].match(m_sIsVisible, pColorNames[nIndex].getLength() - m_sIsVisible.getLength()))
+ m_aConfigValues[i / 2].bIsVisible = Any2Bool(pColors[nIndex++]);
+ }
+}
+/* -----------------------------22.03.2002 14:38------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ColorConfig_Impl::Notify( const uno::Sequence<OUString>& )
+{
+ //loading via notification always uses the default setting
+ Load(::rtl::OUString());
+ NotifyListeners(0);
+}
+/* -----------------------------22.03.2002 14:38------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ColorConfig_Impl::Commit()
+{
+ uno::Sequence < ::rtl::OUString > aColorNames = GetPropertyNames(m_sLoadedScheme);
+ uno::Sequence < beans::PropertyValue > aPropValues(aColorNames.getLength());
+ beans::PropertyValue* pPropValues = aPropValues.getArray();
+ const ::rtl::OUString* pColorNames = aColorNames.getConstArray();
+ sal_Int32 nIndex = 0;
+ const uno::Type& rBoolType = ::getBooleanCppuType();
+ for(int i = 0; i < 2 * ColorConfigEntryCount && aColorNames.getLength() > nIndex; i+= 2)
+ {
+ pPropValues[nIndex].Name = pColorNames[nIndex];
+ //save automatic colors as void value
+ if(COL_AUTO != sal::static_int_cast<ColorData>(m_aConfigValues[i/2].nColor))
+ pPropValues[nIndex].Value <<= m_aConfigValues[i/2].nColor;
+
+ nIndex++;
+ if(nIndex >= aColorNames.getLength())
+ break;
+ //test for visibility property
+ if(pColorNames[nIndex].match(m_sIsVisible, pColorNames[nIndex].getLength() - m_sIsVisible.getLength()))
+ {
+ pPropValues[nIndex].Name = pColorNames[nIndex];
+ pPropValues[nIndex].Value.setValue(&m_aConfigValues[i/2].bIsVisible, rBoolType);
+ nIndex++;
+ }
+ }
+ rtl::OUString sNode(C2U("ColorSchemes"));
+ SetSetProperties(sNode, aPropValues);
+
+ CommitCurrentSchemeName();
+}
+/* -----------------11.12.2002 10:42-----------------
+ *
+ * --------------------------------------------------*/
+void ColorConfig_Impl::CommitCurrentSchemeName()
+{
+ //save current scheme name
+ uno::Sequence < ::rtl::OUString > aCurrent(1);
+ aCurrent.getArray()[0] = C2U("CurrentColorScheme");
+ uno::Sequence< uno::Any > aCurrentVal(1);
+ aCurrentVal.getArray()[0] <<= m_sLoadedScheme;
+ PutProperties(aCurrent, aCurrentVal);
+}
+/* -----------------------------25.03.2002 12:19------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ColorConfig_Impl::SetColorConfigValue(ColorConfigEntry eValue, const ColorConfigValue& rValue )
+{
+ if(rValue != m_aConfigValues[eValue])
+ {
+ m_aConfigValues[eValue] = rValue;
+ SetModified();
+ }
+}
+/* -----------------------------25.03.2002 15:22------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< ::rtl::OUString> ColorConfig_Impl::GetSchemeNames()
+{
+ return GetNodeNames(C2U("ColorSchemes"));
+}
+/* -----------------------------09.04.2002 17:19------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ColorConfig_Impl::AddScheme(const rtl::OUString& rScheme)
+{
+ if(ConfigItem::AddNode(C2U("ColorSchemes"), rScheme))
+ {
+ m_sLoadedScheme = rScheme;
+ Commit();
+ return sal_True;
+ }
+ return sal_False;
+}
+/* -----------------------------09.04.2002 17:19------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ColorConfig_Impl::RemoveScheme(const rtl::OUString& rScheme)
+{
+ uno::Sequence< rtl::OUString > aElements(1);
+ aElements.getArray()[0] = rScheme;
+ return ClearNodeElements(C2U("ColorSchemes"), aElements);
+}
+/* -----------------------------2002/06/20 13:03------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ColorConfig_Impl::SettingsChanged()
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ ImplUpdateApplicationSettings();
+
+ NotifyListeners(0);
+}
+/* -----------------------------2002/08/16 12:07 -----------------------------
+ #100822#
+ --------------------------------------------------------------------------- */
+IMPL_LINK( ColorConfig_Impl, DataChangedEventListener, VclWindowEvent*, pEvent )
+{
+ if ( pEvent->GetId() == VCLEVENT_APPLICATION_DATACHANGED )
+ {
+ DataChangedEvent* pData = (DataChangedEvent*)(pEvent->GetData());
+ if ( (pData->GetType() == DATACHANGED_SETTINGS) &&
+ (pData->GetFlags() & SETTINGS_STYLE) )
+ {
+ SettingsChanged();
+ return 1L;
+ } else
+ return 0L;
+ } else
+ return 0L;
+}
+
+// ---------------------------------------------------------------------------
+
+/** updates the font color in the vcl window settings */
+void ColorConfig_Impl::ImplUpdateApplicationSettings()
+{
+ Application* pApp = GetpApp();
+ if( pApp )
+ {
+ AllSettings aSettings = pApp->GetSettings();
+ StyleSettings aStyleSettings( aSettings.GetStyleSettings() );
+
+ ColorConfigValue aRet = GetColorConfigValue(svtools::FONTCOLOR);
+ if(COL_AUTO == sal::static_int_cast<ColorData>(aRet.nColor))
+ aRet.nColor = ColorConfig::GetDefaultColor(svtools::FONTCOLOR).GetColor();
+
+ Color aFontColor(aRet.nColor);
+
+ if( aStyleSettings.GetFontColor() != aFontColor )
+ {
+ aStyleSettings.SetFontColor( aFontColor );
+
+ aSettings.SetStyleSettings( aStyleSettings );
+ pApp->SetSettings( aSettings );
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+ColorConfig::ColorConfig()
+{
+ ::osl::MutexGuard aGuard( ColorMutex_Impl::get() );
+ if ( !m_pImpl )
+ {
+ m_pImpl = new ColorConfig_Impl;
+ ItemHolder2::holdConfigItem(E_COLORCFG);
+ }
+ ++nColorRefCount_Impl;
+ m_pImpl->AddListener(this);
+}
+/* -----------------------------16.01.01 15:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ColorConfig::~ColorConfig()
+{
+ ::osl::MutexGuard aGuard( ColorMutex_Impl::get() );
+ m_pImpl->RemoveListener(this);
+ if(!--nColorRefCount_Impl)
+ {
+ delete m_pImpl;
+ m_pImpl = 0;
+ }
+}
+/* -----------------------------11.04.2002 11:49------------------------------
+
+ ---------------------------------------------------------------------------*/
+Color ColorConfig::GetDefaultColor(ColorConfigEntry eEntry)
+{
+ static const sal_Int32 aAutoColors[] =
+ {
+ 0, // DOCCOLOR
+ 0xc0c0c0, // DOCBOUNDARIES
+ 0x808080, // APPBACKGROUND
+ 0xc0c0c0, // OBJECTBOUNDARIES
+ 0xc0c0c0, // TABLEBOUNDARIES
+ 0, // FONTCOLOR
+ 0xcc, // LINKS
+ 0x80, // LINKSVISITED
+ 0, // ANCHOR
+ 0xff0000, // SPELL
+ COL_LIGHTMAGENTA,// SMARTTAGS
+ 0xc0c0c0, // WRITERTEXTGRID
+ 0xc0c0c0, // WRITERFIELDSHADIN
+ 0xc0c0c0, // WRITERIDXSHADINGS
+ 0, // WRITERDIRECTCURSOR
+ COL_GREEN, //WRITERSCRIPTINDICATOR
+ 0xc0c0c0, //WRITERSECTIONBOUNDARIES
+ COL_BLUE, //WRITERPAGEBREAKS,
+ COL_LIGHTBLUE, // HTMLSGML
+ COL_LIGHTGREEN, // HTMLCOMMENT
+ COL_LIGHTRED, // HTMLKEYWORD
+ COL_GRAY, // HTMLUNKNOWN
+ COL_LIGHTGRAY, // CALCGRID
+ COL_BLUE, //CALCPAGEBREAK
+ 0x2300dc, //CALCPAGEBREAKMANUAL
+ COL_GRAY, //CALCPAGEBREAKAUTOMATIC
+ COL_LIGHTBLUE, // CALCDETECTIVE
+ COL_LIGHTRED, // CALCDETECTIVEERROR
+ COL_LIGHTRED, // CALCREFERENCE
+ 0xffffc0, // CALCNOTESBACKGROUND
+ 0xc0c0c0, // DRAWGRID
+ 0, // DRAWDRAWING
+ 0xb8ff, // DRAWFILL
+ COL_GREEN, // BASICIDENTIFIER,
+ COL_GRAY,// BASICCOMMENT ,
+ COL_LIGHTRED,// BASICNUMBER ,
+ COL_LIGHTRED,// BASICSTRING ,
+ COL_BLUE, // BASICOPERATOR ,
+ COL_BLUE, // BASICKEYWORD ,
+ COL_RED, //BASICERROR
+ 0x009900, // SQLIDENTIFIER
+ 0x000000, // SQLNUMBER
+ 0xCE7B00, // SQLSTRING
+ 0x000000, // SQLOPERATOR
+ 0x0000E6, // SQLKEYWORD
+ 0x259D9D, // SQLPARAMTER
+ 0x969696,// SQLCOMMENT
+ };
+ Color aRet;
+ switch(eEntry)
+ {
+ case DOCCOLOR :
+ aRet = Application::GetSettings().GetStyleSettings().GetWindowColor();
+ break;
+
+ case APPBACKGROUND :
+ aRet = Application::GetSettings().GetStyleSettings().GetWorkspaceColor();
+ break;
+
+ case SPELL :
+ case DRAWDRAWING :
+ case SMARTTAGS :
+ {
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ aRet = rStyleSettings.GetHighContrastMode() ?
+ rStyleSettings.GetDialogTextColor().GetColor() : aAutoColors[eEntry];
+ }
+ break;
+
+ case DRAWFILL :
+ aRet = /*rStyleSettings.GetHighContrastMode() ?
+ rStyleSettings.OutlineMode??? : */ aAutoColors[eEntry];
+ break;
+
+ case FONTCOLOR :
+ aRet = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
+ break;
+
+ case LINKS :
+ aRet = Application::GetSettings().GetStyleSettings().GetLinkColor();
+ break;
+
+ case LINKSVISITED :
+ aRet = Application::GetSettings().GetStyleSettings().GetVisitedLinkColor();
+ break;
+
+ default:
+ aRet = aAutoColors[eEntry];
+ }
+ return aRet;
+}
+/* -----------------------------11.04.2002 11:49------------------------------
+
+ ---------------------------------------------------------------------------*/
+ColorConfigValue ColorConfig::GetColorValue(ColorConfigEntry eEntry, sal_Bool bSmart)const
+{
+ ColorConfigValue aRet = m_pImpl->GetColorConfigValue(eEntry);
+ if(bSmart)
+ {
+ if(COL_AUTO == sal::static_int_cast<ColorData>(aRet.nColor))
+ aRet.nColor = ColorConfig::GetDefaultColor(eEntry).GetColor();
+ //#103495# don't allow grey between 40% and 60% as application background
+ const UINT8 nRed = COLORDATA_RED( aRet.nColor);
+ if(eEntry == APPBACKGROUND &&
+ (nRed == COLORDATA_GREEN( aRet.nColor)) &&
+ (nRed == COLORDATA_BLUE( aRet.nColor)) &&
+ nRed > 102 && nRed < 153 )
+ {
+ aRet.nColor = RGB_COLORDATA(153, 153, 153);
+ }
+ }
+
+ return aRet;
+}
+/* -----------------------------25.03.2002 12:01------------------------------
+
+ ---------------------------------------------------------------------------*/
+EditableColorConfig::EditableColorConfig() :
+ m_pImpl(new ColorConfig_Impl),
+ m_bModified(sal_False)
+{
+ m_pImpl->BlockBroadcasts(TRUE);
+}
+/*-- 25.03.2002 12:03:08---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+EditableColorConfig::~EditableColorConfig()
+{
+ m_pImpl->BlockBroadcasts(FALSE);
+ if(m_bModified)
+ m_pImpl->SetModified();
+ if(m_pImpl->IsModified())
+ m_pImpl->Commit();
+ delete m_pImpl;
+}
+
+/*-- 25.03.2002 12:03:15---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Sequence< ::rtl::OUString > EditableColorConfig::GetSchemeNames() const
+{
+ return m_pImpl->GetSchemeNames();
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditableColorConfig::DeleteScheme(const ::rtl::OUString& rScheme )
+{
+ m_pImpl->RemoveScheme(rScheme);
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditableColorConfig::AddScheme(const ::rtl::OUString& rScheme )
+{
+ m_pImpl->AddScheme(rScheme);
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Bool EditableColorConfig::LoadScheme(const ::rtl::OUString& rScheme )
+{
+ if(m_bModified)
+ m_pImpl->SetModified();
+ if(m_pImpl->IsModified())
+ m_pImpl->Commit();
+ m_bModified = sal_False;
+ m_pImpl->Load(rScheme);
+ //the name of the loaded scheme has to be committed separately
+ m_pImpl->CommitCurrentSchemeName();
+ return sal_True;
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+const ::rtl::OUString& EditableColorConfig::GetCurrentSchemeName()const
+{
+ return m_pImpl->GetLoadedScheme();
+}
+/* -----------------11.12.2002 10:56-----------------
+ * changes the name of the current scheme but doesn't load it!
+ * --------------------------------------------------*/
+void EditableColorConfig::SetCurrentSchemeName(const ::rtl::OUString& rScheme)
+{
+ m_pImpl->SetCurrentSchemeName(rScheme);
+ m_pImpl->CommitCurrentSchemeName();
+}
+/*-- 25.03.2002 12:03:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+const ColorConfigValue& EditableColorConfig::GetColorValue(
+ ColorConfigEntry eEntry)const
+{
+ return m_pImpl->GetColorConfigValue(eEntry);
+}
+/*-- 25.03.2002 12:03:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditableColorConfig::SetColorValue(
+ ColorConfigEntry eEntry, const ColorConfigValue& rValue)
+{
+ m_pImpl->SetColorConfigValue(eEntry, rValue);
+ m_pImpl->ClearModified();
+ m_bModified = sal_True;
+}
+/* -----------------------------10.04.2002 13:22------------------------------
+
+ ---------------------------------------------------------------------------*/
+void EditableColorConfig::SetModified()
+{
+ m_bModified = sal_True;
+}
+/* -----------------15.10.2002 14:51-----------------
+ *
+ * --------------------------------------------------*/
+void EditableColorConfig::Commit()
+{
+ if(m_bModified)
+ m_pImpl->SetModified();
+ if(m_pImpl->IsModified())
+ m_pImpl->Commit();
+ m_bModified = sal_False;
+}
+// -----------------------------------------------------------------------------
+void EditableColorConfig::DisableBroadcast()
+{
+ m_pImpl->BlockBroadcasts(TRUE);
+}
+// -----------------------------------------------------------------------------
+void EditableColorConfig::EnableBroadcast()
+{
+ m_pImpl->BlockBroadcasts(FALSE);
+}
+// -----------------------------------------------------------------------------
+
+}//namespace svtools
diff --git a/svtools/source/config/extcolorcfg.cxx b/svtools/source/config/extcolorcfg.cxx
new file mode 100644
index 000000000000..993025b22884
--- /dev/null
+++ b/svtools/source/config/extcolorcfg.cxx
@@ -0,0 +1,827 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "extcolorcfg.hxx"
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <tools/color.hxx>
+#include <tools/debug.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/configpathes.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <svl/poolitem.hxx> //Any2Bool
+#include <svl/smplhint.hxx>
+#include <vos/mutex.hxx>
+
+ /* #100822# ----
+#include <vcl/wrkwin.hxx>
+ ------------- */
+#include <vcl/svapp.hxx>
+#include <vcl/event.hxx>
+#include <rtl/instance.hxx>
+#include <rtl/strbuf.hxx>
+#include <comphelper/stl_types.hxx>
+
+
+//-----------------------------------------------------------------------------
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star;
+
+namespace svtools
+{
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+sal_Int32 nExtendedColorRefCount_Impl = 0;
+namespace
+{
+ struct ColorMutex_Impl
+ : public rtl::Static< ::osl::Mutex, ColorMutex_Impl > {};
+}
+
+ExtendedColorConfig_Impl* ExtendedColorConfig::m_pImpl = NULL;
+
+/* -----------------------------16.01.01 15:36--------------------------------
+ ---------------------------------------------------------------------------*/
+class ExtendedColorConfig_Impl : public utl::ConfigItem, public SfxBroadcaster
+{
+ DECLARE_STL_USTRINGACCESS_MAP( ::rtl::OUString, TDisplayNames);
+ DECLARE_STL_USTRINGACCESS_MAP(ExtendedColorConfigValue,TConfigValues);
+ typedef ::std::vector<TConfigValues::iterator> TMapPos;
+ typedef ::std::pair< TConfigValues, TMapPos > TComponentMapping;
+ DECLARE_STL_USTRINGACCESS_MAP(TComponentMapping,TComponents);
+ TComponents m_aConfigValues;
+ TDisplayNames m_aComponentDisplayNames;
+ ::std::vector<TComponents::iterator> m_aConfigValuesPos;
+
+ sal_Bool m_bEditMode;
+ rtl::OUString m_sLoadedScheme;
+ sal_Bool m_bIsBroadcastEnabled;
+ static sal_Bool m_bLockBroadcast;
+ static sal_Bool m_bBroadcastWhenUnlocked;
+
+ uno::Sequence< ::rtl::OUString> GetPropertyNames(const rtl::OUString& rScheme);
+ void FillComponentColors(uno::Sequence < ::rtl::OUString >& _rComponents,const TDisplayNames& _rDisplayNames);
+public:
+ ExtendedColorConfig_Impl(sal_Bool bEditMode = sal_False);
+ virtual ~ExtendedColorConfig_Impl();
+
+ void Load(const rtl::OUString& rScheme);
+ void CommitCurrentSchemeName();
+ //changes the name of the current scheme but doesn't load it!
+ void SetCurrentSchemeName(const rtl::OUString& rSchemeName) {m_sLoadedScheme = rSchemeName;}
+ sal_Bool ExistsScheme(const ::rtl::OUString& _sSchemeName);
+ virtual void Commit();
+ virtual void Notify( const uno::Sequence<rtl::OUString>& aPropertyNames);
+
+ sal_Int32 GetComponentCount() const;
+ ::rtl::OUString GetComponentName(sal_uInt32 _nPos) const;
+ ::rtl::OUString GetComponentDisplayName(const ::rtl::OUString& _sComponentName) const;
+ sal_Int32 GetComponentColorCount(const ::rtl::OUString& _sName) const;
+ ExtendedColorConfigValue GetComponentColorConfigValue(const ::rtl::OUString& _sName,sal_uInt32 _nPos) const;
+
+ ExtendedColorConfigValue GetColorConfigValue(const ::rtl::OUString& _sComponentName,const ::rtl::OUString& _sName)
+ {
+ TComponents::iterator aFind = m_aConfigValues.find(_sComponentName);
+ if ( aFind != m_aConfigValues.end() )
+ {
+ TConfigValues::iterator aFind2 = aFind->second.first.find(_sName);
+ if ( aFind2 != aFind->second.first.end() )
+ return aFind2->second;
+ }
+#if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage( "Could find the required config:\n" );
+ aMessage.append( "component: " );
+ aMessage.append( ::rtl::OUStringToOString( _sComponentName, RTL_TEXTENCODING_UTF8 ) );
+ aMessage.append( "\nname: " );
+ aMessage.append( ::rtl::OUStringToOString( _sName, RTL_TEXTENCODING_UTF8 ) );
+ OSL_ENSURE( 0, aMessage.makeStringAndClear().getStr() );
+#endif
+ return ExtendedColorConfigValue();
+ }
+ void SetColorConfigValue(const ::rtl::OUString& _sName,
+ const ExtendedColorConfigValue& rValue );
+
+ const rtl::OUString& GetLoadedScheme() const {return m_sLoadedScheme;}
+
+ uno::Sequence< ::rtl::OUString> GetSchemeNames();
+
+ sal_Bool AddScheme(const rtl::OUString& rNode);
+ sal_Bool RemoveScheme(const rtl::OUString& rNode);
+ void SetModified(){ConfigItem::SetModified();}
+ void ClearModified(){ConfigItem::ClearModified();}
+ void SettingsChanged();
+
+ static void DisableBroadcast();
+ static void EnableBroadcast();
+ static sal_Bool IsEnableBroadcast();
+
+ static void LockBroadcast();
+ static void UnlockBroadcast();
+
+ // #100822#
+ DECL_LINK( DataChangedEventListener, VclWindowEvent* );
+};
+
+/* -----------------------------16.01.01 15:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< OUString> ExtendedColorConfig_Impl::GetPropertyNames(const rtl::OUString& rScheme)
+{
+ uno::Sequence< OUString> aNames(GetNodeNames(rScheme));
+ ::rtl::OUString* pIter = aNames.getArray();
+ ::rtl::OUString* pEnd = pIter + aNames.getLength();
+ ::rtl::OUString sSep(RTL_CONSTASCII_USTRINGPARAM("/"));
+ for(;pIter != pEnd;++pIter)
+ {
+ *pIter = rScheme + sSep + *pIter;
+ }
+ return aNames;
+}
+// -----------------------------------------------------------------------------
+sal_Int32 ExtendedColorConfig_Impl::GetComponentCount() const
+{
+ return m_aConfigValues.size();
+}
+// -----------------------------------------------------------------------------
+sal_Int32 ExtendedColorConfig_Impl::GetComponentColorCount(const ::rtl::OUString& _sName) const
+{
+ sal_Int32 nSize = 0;
+ TComponents::const_iterator aFind = m_aConfigValues.find(_sName);
+ if ( aFind != m_aConfigValues.end() )
+ {
+ nSize = aFind->second.first.size();
+ }
+ return nSize;
+}
+// -----------------------------------------------------------------------------
+ExtendedColorConfigValue ExtendedColorConfig_Impl::GetComponentColorConfigValue(const ::rtl::OUString& _sName,sal_uInt32 _nPos) const
+{
+ TComponents::const_iterator aFind = m_aConfigValues.find(_sName);
+ if ( aFind != m_aConfigValues.end() )
+ {
+ if ( _nPos < aFind->second.second.size() )
+ {
+ return aFind->second.second[_nPos]->second;
+ }
+ }
+ return ExtendedColorConfigValue();
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ExtendedColorConfig_Impl::GetComponentDisplayName(const ::rtl::OUString& _sComponentName) const
+{
+ ::rtl::OUString sRet;
+ TDisplayNames::const_iterator aFind = m_aComponentDisplayNames.find(_sComponentName);
+ if ( aFind != m_aComponentDisplayNames.end() )
+ sRet = aFind->second;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ExtendedColorConfig_Impl::GetComponentName(sal_uInt32 _nPos) const
+{
+ ::rtl::OUString sRet;
+ if ( _nPos < m_aConfigValuesPos.size() )
+ sRet = m_aConfigValuesPos[_nPos]->first;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+/* -----------------------------22.03.2002 14:37------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ExtendedColorConfig_Impl::m_bLockBroadcast = sal_False;
+sal_Bool ExtendedColorConfig_Impl::m_bBroadcastWhenUnlocked = sal_False;
+ExtendedColorConfig_Impl::ExtendedColorConfig_Impl(sal_Bool bEditMode) :
+ ConfigItem(C2U("Office.ExtendedColorScheme")),
+ m_bEditMode(bEditMode),
+ m_bIsBroadcastEnabled(sal_True)
+{
+ if(!m_bEditMode)
+ {
+ //try to register on the root node - if possible
+ uno::Sequence < ::rtl::OUString > aNames(1);
+ EnableNotification( aNames );
+ }
+ Load(::rtl::OUString());
+
+ // #100822#
+ ::Application::AddEventListener( LINK(this, ExtendedColorConfig_Impl, DataChangedEventListener) );
+
+}
+/* -----------------------------25.03.2002 12:28------------------------------
+
+ ---------------------------------------------------------------------------*/
+ExtendedColorConfig_Impl::~ExtendedColorConfig_Impl()
+{
+ // #100822#
+ ::Application::RemoveEventListener( LINK(this, ExtendedColorConfig_Impl, DataChangedEventListener) );
+}
+// -----------------------------------------------------------------------------
+void ExtendedColorConfig_Impl::DisableBroadcast()
+{
+ if ( ExtendedColorConfig::m_pImpl )
+ ExtendedColorConfig::m_pImpl->m_bIsBroadcastEnabled = sal_False;
+}
+// -----------------------------------------------------------------------------
+void ExtendedColorConfig_Impl::EnableBroadcast()
+{
+ if ( ExtendedColorConfig::m_pImpl )
+ ExtendedColorConfig::m_pImpl->m_bIsBroadcastEnabled = sal_True;
+}
+// -----------------------------------------------------------------------------
+sal_Bool ExtendedColorConfig_Impl::IsEnableBroadcast()
+{
+ return ExtendedColorConfig::m_pImpl ? ExtendedColorConfig::m_pImpl->m_bIsBroadcastEnabled : sal_False;
+}
+/* -----------------------------22.03.2002 14:38------------------------------
+
+ ---------------------------------------------------------------------------*/
+void lcl_addString(uno::Sequence < ::rtl::OUString >& _rSeq,const ::rtl::OUString& _sAdd)
+{
+ ::rtl::OUString* pIter = _rSeq.getArray();
+ ::rtl::OUString* pEnd = pIter + _rSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ *pIter += _sAdd;
+}
+// -----------------------------------------------------------------------------
+void ExtendedColorConfig_Impl::Load(const rtl::OUString& rScheme)
+{
+ m_aComponentDisplayNames.clear();
+ m_aConfigValuesPos.clear();
+ m_aConfigValues.clear();
+
+ // fill display names
+ TDisplayNames aDisplayNameMap;
+ ::rtl::OUString sEntryNames(RTL_CONSTASCII_USTRINGPARAM("EntryNames"));
+ uno::Sequence < ::rtl::OUString > aComponentNames = GetPropertyNames(sEntryNames);
+ ::rtl::OUString sDisplayName(RTL_CONSTASCII_USTRINGPARAM("/DisplayName"));
+ ::rtl::OUString* pIter = aComponentNames.getArray();
+ ::rtl::OUString* pEnd = pIter + aComponentNames.getLength();
+ for(sal_Int32 i = 0;pIter != pEnd;++pIter,++i)
+ {
+ uno::Sequence < ::rtl::OUString > aComponentDisplayNames(1);
+ aComponentDisplayNames[0] = *pIter;
+ aComponentDisplayNames[0] += sDisplayName;
+ uno::Sequence< uno::Any > aComponentDisplayNamesValue = GetProperties( aComponentDisplayNames );
+ ::rtl::OUString sComponentDisplayName;
+ if ( aComponentDisplayNamesValue.getLength() && (aComponentDisplayNamesValue[0] >>= sComponentDisplayName) )
+ {
+ sal_Int32 nIndex = 0;
+ m_aComponentDisplayNames.insert(TDisplayNames::value_type(pIter->getToken(1,'/',nIndex),sComponentDisplayName));
+ }
+
+ *pIter += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/Entries"));
+ uno::Sequence < ::rtl::OUString > aDisplayNames = GetPropertyNames(*pIter);
+ lcl_addString(aDisplayNames,sDisplayName);
+
+ uno::Sequence< uno::Any > aDisplayNamesValue = GetProperties( aDisplayNames );
+
+ const ::rtl::OUString* pDispIter = aDisplayNames.getConstArray();
+ const ::rtl::OUString* pDispEnd = pDispIter + aDisplayNames.getLength();
+ for(sal_Int32 j = 0;pDispIter != pDispEnd;++pDispIter,++j)
+ {
+ sal_Int32 nIndex = 0;
+ pDispIter->getToken(0,'/',nIndex);
+ ::rtl::OUString sName = pDispIter->copy(nIndex);
+ sName = sName.copy(0,sName.lastIndexOf(sDisplayName));
+ ::rtl::OUString sCurrentDisplayName;
+ aDisplayNamesValue[j] >>= sCurrentDisplayName;
+ aDisplayNameMap.insert(TDisplayNames::value_type(sName,sCurrentDisplayName));
+ }
+ }
+
+ // load color settings
+ rtl::OUString sScheme(rScheme);
+
+ if(!sScheme.getLength())
+ {
+ //detect current scheme name
+ uno::Sequence < ::rtl::OUString > aCurrent(1);
+ aCurrent.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ExtendedColorScheme/CurrentColorScheme"));
+ uno::Sequence< uno::Any > aCurrentVal = GetProperties( aCurrent );
+ aCurrentVal.getConstArray()[0] >>= sScheme;
+ } // if(!sScheme.getLength())
+
+ m_sLoadedScheme = sScheme;
+ ::rtl::OUString sBase(RTL_CONSTASCII_USTRINGPARAM("ExtendedColorScheme/ColorSchemes/"));
+ sBase += sScheme;
+
+ sal_Bool bFound = ExistsScheme(sScheme);
+ if ( bFound )
+ {
+ aComponentNames = GetPropertyNames(sBase);
+ FillComponentColors(aComponentNames,aDisplayNameMap);
+ } // if ( bFound )
+
+ if ( !m_sLoadedScheme.getLength() )
+ m_sLoadedScheme = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("default"));
+
+ if ( !sScheme.equalsAscii("default") )
+ {
+ ::rtl::OUString sDefault(RTL_CONSTASCII_USTRINGPARAM("default"));
+ if ( ExistsScheme(sDefault) )
+ {
+ ::rtl::OUString sBaseDefault(RTL_CONSTASCII_USTRINGPARAM("ExtendedColorScheme/ColorSchemes/default"));
+ aComponentNames = GetPropertyNames(sBaseDefault);
+ FillComponentColors(aComponentNames,aDisplayNameMap);
+ }
+ } // if ( !sScheme.equalsAscii("default") )
+ if ( !bFound && sScheme.getLength() )
+ {
+ AddScheme(sScheme);
+ CommitCurrentSchemeName();
+ }
+}
+// -----------------------------------------------------------------------------
+void ExtendedColorConfig_Impl::FillComponentColors(uno::Sequence < ::rtl::OUString >& _rComponents,const TDisplayNames& _rDisplayNames)
+{
+ const ::rtl::OUString sColorEntries(RTL_CONSTASCII_USTRINGPARAM("/Entries"));
+ ::rtl::OUString* pIter = _rComponents.getArray();
+ ::rtl::OUString* pEnd = pIter + _rComponents.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ ::rtl::OUString sComponentName = pIter->copy(pIter->lastIndexOf('/')+1);
+ if ( m_aConfigValues.find(sComponentName) == m_aConfigValues.end() )
+ {
+ ::rtl::OUString sEntry = *pIter;
+ sEntry += sColorEntries;
+
+ uno::Sequence < ::rtl::OUString > aColorNames = GetPropertyNames(sEntry);
+ uno::Sequence < ::rtl::OUString > aDefaultColorNames = aColorNames;
+
+ const ::rtl::OUString sColor(RTL_CONSTASCII_USTRINGPARAM("/Color"));
+ const ::rtl::OUString sDefaultColor(RTL_CONSTASCII_USTRINGPARAM("/DefaultColor"));
+ lcl_addString(aColorNames,sColor);
+ lcl_addString(aDefaultColorNames,sDefaultColor);
+ uno::Sequence< uno::Any > aColors = GetProperties( aColorNames );
+ const uno::Any* pColors = aColors.getConstArray();
+
+ uno::Sequence< uno::Any > aDefaultColors = GetProperties( aDefaultColorNames );
+ bool bDefaultColorFound = aDefaultColors.getLength() != 0;
+ const uno::Any* pDefaultColors = aDefaultColors.getConstArray();
+
+ ::rtl::OUString* pColorIter = aColorNames.getArray();
+ ::rtl::OUString* pColorEnd = pColorIter + aColorNames.getLength();
+
+ m_aConfigValuesPos.push_back(m_aConfigValues.insert(TComponents::value_type(sComponentName,TComponentMapping(TConfigValues(),TMapPos()))).first);
+ TConfigValues& aConfigValues = (*m_aConfigValuesPos.rbegin())->second.first;
+ TMapPos& aConfigValuesPos = (*m_aConfigValuesPos.rbegin())->second.second;
+ for(int i = 0; pColorIter != pColorEnd; ++pColorIter ,++i)
+ {
+ if ( aConfigValues.find(*pColorIter) == aConfigValues.end() )
+ {
+ sal_Int32 nIndex = 0;
+ pColorIter->getToken(2,'/',nIndex);
+ ::rtl::OUString sName(pColorIter->copy(nIndex)),sDisplayName;
+ ::rtl::OUString sTemp = sName.copy(0,sName.lastIndexOf(sColor));
+
+ TDisplayNames::const_iterator aFind = _rDisplayNames.find(sTemp);
+ nIndex = 0;
+ sName = sName.getToken(2,'/',nIndex);
+ OSL_ENSURE(aFind != _rDisplayNames.end(),"DisplayName is not in EntryNames config list!");
+ if ( aFind != _rDisplayNames.end() )
+ sDisplayName = aFind->second;
+
+ OSL_ENSURE(pColors[i].hasValue(),"Color config entry has NIL as color value set!");
+ OSL_ENSURE(pDefaultColors[i].hasValue(),"Color config entry has NIL as color value set!");
+ sal_Int32 nColor = 0,nDefaultColor = 0;
+ pColors[i] >>= nColor;
+ if ( bDefaultColorFound )
+ pDefaultColors[i] >>= nDefaultColor;
+ else
+ nDefaultColor = nColor;
+ ExtendedColorConfigValue aValue(sName,sDisplayName,nColor,nDefaultColor);
+ aConfigValuesPos.push_back(aConfigValues.insert(TConfigValues::value_type(sName,aValue)).first);
+ }
+ } // for(int i = 0; pColorIter != pColorEnd; ++pColorIter ,++i)
+ }
+ }
+}
+/* -----------------------------22.03.2002 14:38------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ExtendedColorConfig_Impl::Notify( const uno::Sequence<OUString>& /*rPropertyNames*/)
+{
+ //loading via notification always uses the default setting
+ Load(::rtl::OUString());
+
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ if(m_bLockBroadcast)
+ {
+ m_bBroadcastWhenUnlocked = sal_True;
+ }
+ else
+ Broadcast(SfxSimpleHint(SFX_HINT_COLORS_CHANGED));
+}
+/* -----------------------------22.03.2002 14:38------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ExtendedColorConfig_Impl::Commit()
+{
+ if ( !m_sLoadedScheme.getLength() )
+ return;
+ const ::rtl::OUString sColorEntries(RTL_CONSTASCII_USTRINGPARAM("Entries"));
+ const ::rtl::OUString sColor(RTL_CONSTASCII_USTRINGPARAM("/Color"));
+ const ::rtl::OUString sDefaultColor(RTL_CONSTASCII_USTRINGPARAM("/DefaultColor"));
+ ::rtl::OUString sBase(RTL_CONSTASCII_USTRINGPARAM("ExtendedColorScheme/ColorSchemes/"));
+ const ::rtl::OUString s_sSep(RTL_CONSTASCII_USTRINGPARAM("/"));
+ sBase += m_sLoadedScheme;
+
+ TComponents::iterator aIter = m_aConfigValues.begin();
+ TComponents::iterator aEnd = m_aConfigValues.end();
+ for( ;aIter != aEnd;++aIter )
+ {
+ ::rtl::OUString sEntry = aIter->first;
+ sEntry += sColorEntries;
+
+ if ( ConfigItem::AddNode(sBase, aIter->first) )
+ {
+ rtl::OUString sNode = sBase;
+ sNode += s_sSep;
+ sNode += aIter->first;
+ //ConfigItem::AddNode(sNode, sColorEntries);
+ sNode += s_sSep;
+ sNode += sColorEntries;
+
+ uno::Sequence < beans::PropertyValue > aPropValues(aIter->second.first.size());
+ beans::PropertyValue* pPropValues = aPropValues.getArray();
+ TConfigValues::iterator aConIter = aIter->second.first.begin();
+ TConfigValues::iterator aConEnd = aIter->second.first.end();
+ for (; aConIter != aConEnd; ++aConIter,++pPropValues)
+ {
+ pPropValues->Name = sNode + s_sSep + aConIter->first;
+ ConfigItem::AddNode(sNode, aConIter->first);
+ pPropValues->Name += sColor;
+ pPropValues->Value <<= aConIter->second.getColor();
+ // the default color will never be changed
+ }
+ ::rtl::OUString s(RTL_CONSTASCII_USTRINGPARAM("ExtendedColorScheme/ColorSchemes"));
+ SetSetProperties(s, aPropValues);
+ }
+ }
+
+ CommitCurrentSchemeName();
+}
+/* -----------------11.12.2002 10:42-----------------
+ *
+ * --------------------------------------------------*/
+void ExtendedColorConfig_Impl::CommitCurrentSchemeName()
+{
+ //save current scheme name
+ uno::Sequence < ::rtl::OUString > aCurrent(1);
+ aCurrent.getArray()[0] = C2U("ExtendedColorScheme/CurrentColorScheme");
+ uno::Sequence< uno::Any > aCurrentVal(1);
+ aCurrentVal.getArray()[0] <<= m_sLoadedScheme;
+ PutProperties(aCurrent, aCurrentVal);
+}
+// -----------------------------------------------------------------------------
+sal_Bool ExtendedColorConfig_Impl::ExistsScheme(const ::rtl::OUString& _sSchemeName)
+{
+ ::rtl::OUString sBase(RTL_CONSTASCII_USTRINGPARAM("ExtendedColorScheme/ColorSchemes"));
+
+ uno::Sequence < ::rtl::OUString > aComponentNames = GetPropertyNames(sBase);
+ sBase += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + _sSchemeName;
+ const ::rtl::OUString* pCompIter = aComponentNames.getConstArray();
+ const ::rtl::OUString* pCompEnd = pCompIter + aComponentNames.getLength();
+ for(;pCompIter != pCompEnd && *pCompIter != sBase;++pCompIter)
+ ;
+ return pCompIter != pCompEnd;
+}
+// -----------------------------------------------------------------------------
+/* -----------------------------25.03.2002 12:19------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ExtendedColorConfig_Impl::SetColorConfigValue(const ::rtl::OUString& _sName, const ExtendedColorConfigValue& rValue )
+{
+ TComponents::iterator aFind = m_aConfigValues.find(_sName);
+ if ( aFind != m_aConfigValues.end() )
+ {
+ TConfigValues::iterator aFind2 = aFind->second.first.find(rValue.getName());
+ if ( aFind2 != aFind->second.first.end() )
+ aFind2->second = rValue;
+ SetModified();
+ }
+}
+/* -----------------------------25.03.2002 15:22------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< ::rtl::OUString> ExtendedColorConfig_Impl::GetSchemeNames()
+{
+ return GetNodeNames(C2U("ExtendedColorScheme/ColorSchemes"));
+}
+/* -----------------------------09.04.2002 17:19------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ExtendedColorConfig_Impl::AddScheme(const rtl::OUString& rScheme)
+{
+ if(ConfigItem::AddNode(C2U("ExtendedColorScheme/ColorSchemes"), rScheme))
+ {
+ m_sLoadedScheme = rScheme;
+ Commit();
+ return sal_True;
+ }
+ return sal_False;
+}
+/* -----------------------------09.04.2002 17:19------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ExtendedColorConfig_Impl::RemoveScheme(const rtl::OUString& rScheme)
+{
+ uno::Sequence< rtl::OUString > aElements(1);
+ aElements.getArray()[0] = rScheme;
+ return ClearNodeElements(C2U("ExtendedColorScheme/ColorSchemes"), aElements);
+}
+/* -----------------------------2002/06/20 13:03------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ExtendedColorConfig_Impl::SettingsChanged()
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ Broadcast( SfxSimpleHint( SFX_HINT_COLORS_CHANGED ) );
+}
+/* -----------------11.12.2002 09:21-----------------
+ *
+ * --------------------------------------------------*/
+void ExtendedColorConfig_Impl::LockBroadcast()
+{
+ m_bLockBroadcast = sal_True;
+}
+/* -----------------11.12.2002 09:21-----------------
+ *
+ * --------------------------------------------------*/
+void ExtendedColorConfig_Impl::UnlockBroadcast()
+{
+ if ( m_bBroadcastWhenUnlocked )
+ {
+ m_bBroadcastWhenUnlocked = ExtendedColorConfig::m_pImpl != NULL;
+ if ( m_bBroadcastWhenUnlocked )
+ {
+ if ( ExtendedColorConfig::m_pImpl->IsEnableBroadcast() )
+ {
+ m_bBroadcastWhenUnlocked = sal_False;
+ ExtendedColorConfig::m_pImpl->Broadcast(SfxSimpleHint(SFX_HINT_COLORS_CHANGED));
+ }
+ }
+ }
+ m_bLockBroadcast = sal_False;
+}
+/* -----------------------------2002/08/16 12:07 -----------------------------
+ #100822#
+ --------------------------------------------------------------------------- */
+IMPL_LINK( ExtendedColorConfig_Impl, DataChangedEventListener, VclWindowEvent*, pEvent )
+{
+ if ( pEvent->GetId() == VCLEVENT_APPLICATION_DATACHANGED )
+ {
+ DataChangedEvent* pData = (DataChangedEvent*)(pEvent->GetData());
+ if ( (pData->GetType() == DATACHANGED_SETTINGS) &&
+ (pData->GetFlags() & SETTINGS_STYLE) )
+ {
+ SettingsChanged();
+ return 1L;
+ } else
+ return 0L;
+ } else
+ return 0L;
+}
+
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+
+ExtendedColorConfig::ExtendedColorConfig()
+{
+ ::osl::MutexGuard aGuard( ColorMutex_Impl::get() );
+ if ( !m_pImpl )
+ m_pImpl = new ExtendedColorConfig_Impl;
+ ++nExtendedColorRefCount_Impl;
+ StartListening( *m_pImpl);
+}
+/* -----------------------------16.01.01 15:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ExtendedColorConfig::~ExtendedColorConfig()
+{
+ ::osl::MutexGuard aGuard( ColorMutex_Impl::get() );
+ EndListening( *m_pImpl);
+ if(!--nExtendedColorRefCount_Impl)
+ {
+ delete m_pImpl;
+ m_pImpl = 0;
+ }
+}
+/* -----------------------------11.04.2002 11:49------------------------------
+
+ ---------------------------------------------------------------------------*/
+ExtendedColorConfigValue ExtendedColorConfig::GetColorValue(const ::rtl::OUString& _sComponentName,const ::rtl::OUString& _sName)const
+{
+ return m_pImpl->GetColorConfigValue(_sComponentName,_sName);
+}
+// -----------------------------------------------------------------------------
+sal_Int32 ExtendedColorConfig::GetComponentCount() const
+{
+ return m_pImpl->GetComponentCount();
+}
+// -----------------------------------------------------------------------------
+sal_Int32 ExtendedColorConfig::GetComponentColorCount(const ::rtl::OUString& _sName) const
+{
+ return m_pImpl->GetComponentColorCount(_sName);
+}
+// -----------------------------------------------------------------------------
+ExtendedColorConfigValue ExtendedColorConfig::GetComponentColorConfigValue(const ::rtl::OUString& _sName,sal_uInt32 _nPos) const
+{
+ return m_pImpl->GetComponentColorConfigValue(_sName,_nPos);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ExtendedColorConfig::GetComponentName(sal_uInt32 _nPos) const
+{
+ return m_pImpl->GetComponentName(_nPos);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ExtendedColorConfig::GetComponentDisplayName(const ::rtl::OUString& _sComponentName) const
+{
+ return m_pImpl->GetComponentDisplayName(_sComponentName);
+}
+// -----------------------------------------------------------------------------
+/* -----------------------------12.04.2002 09:25------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ExtendedColorConfig::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ Broadcast( rHint );
+}
+/* -----------------------------25.03.2002 12:01------------------------------
+
+ ---------------------------------------------------------------------------*/
+EditableExtendedColorConfig::EditableExtendedColorConfig() :
+ m_pImpl(new ExtendedColorConfig_Impl),
+ m_bModified(sal_False)
+{
+ m_pImpl->LockBroadcast();
+}
+/*-- 25.03.2002 12:03:08---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+EditableExtendedColorConfig::~EditableExtendedColorConfig()
+{
+ m_pImpl->UnlockBroadcast();
+ if(m_bModified)
+ m_pImpl->SetModified();
+ if(m_pImpl->IsModified())
+ m_pImpl->Commit();
+ delete m_pImpl;
+}
+
+/*-- 25.03.2002 12:03:15---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Sequence< ::rtl::OUString > EditableExtendedColorConfig::GetSchemeNames() const
+{
+ return m_pImpl->GetSchemeNames();
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditableExtendedColorConfig::DeleteScheme(const ::rtl::OUString& rScheme )
+{
+ m_pImpl->RemoveScheme(rScheme);
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditableExtendedColorConfig::AddScheme(const ::rtl::OUString& rScheme )
+{
+ m_pImpl->AddScheme(rScheme);
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Bool EditableExtendedColorConfig::LoadScheme(const ::rtl::OUString& rScheme )
+{
+ if(m_bModified)
+ m_pImpl->SetModified();
+ if(m_pImpl->IsModified())
+ m_pImpl->Commit();
+ m_bModified = sal_False;
+ m_pImpl->Load(rScheme);
+ //the name of the loaded scheme has to be committed separately
+ m_pImpl->CommitCurrentSchemeName();
+ return sal_True;
+}
+/*-- 25.03.2002 12:03:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+const ::rtl::OUString& EditableExtendedColorConfig::GetCurrentSchemeName()const
+{
+ return m_pImpl->GetLoadedScheme();
+}
+/* -----------------11.12.2002 10:56-----------------
+ * changes the name of the current scheme but doesn't load it!
+ * --------------------------------------------------*/
+void EditableExtendedColorConfig::SetCurrentSchemeName(const ::rtl::OUString& rScheme)
+{
+ m_pImpl->SetCurrentSchemeName(rScheme);
+ m_pImpl->CommitCurrentSchemeName();
+}
+/*-- 25.03.2002 12:03:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+ExtendedColorConfigValue EditableExtendedColorConfig::GetColorValue(const ::rtl::OUString& _sComponentName,
+ const ::rtl::OUString& _sName)const
+{
+ return m_pImpl->GetColorConfigValue(_sComponentName,_sName);
+}
+/*-- 25.03.2002 12:03:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditableExtendedColorConfig::SetColorValue(
+ const ::rtl::OUString& _sName, const ExtendedColorConfigValue& rValue)
+{
+ m_pImpl->SetColorConfigValue(_sName, rValue);
+ m_pImpl->ClearModified();
+ m_bModified = sal_True;
+}
+/* -----------------------------10.04.2002 13:22------------------------------
+
+ ---------------------------------------------------------------------------*/
+void EditableExtendedColorConfig::SetModified()
+{
+ m_bModified = sal_True;
+}
+/* -----------------15.10.2002 14:51-----------------
+ *
+ * --------------------------------------------------*/
+void EditableExtendedColorConfig::Commit()
+{
+ if(m_bModified)
+ m_pImpl->SetModified();
+ if(m_pImpl->IsModified())
+ m_pImpl->Commit();
+ m_bModified = sal_False;
+}
+// -----------------------------------------------------------------------------
+void EditableExtendedColorConfig::DisableBroadcast()
+{
+ m_pImpl->DisableBroadcast();
+}
+// -----------------------------------------------------------------------------
+void EditableExtendedColorConfig::EnableBroadcast()
+{
+ m_pImpl->EnableBroadcast();
+}
+// -----------------------------------------------------------------------------
+sal_Int32 EditableExtendedColorConfig::GetComponentCount() const
+{
+ return m_pImpl->GetComponentCount();
+}
+// -----------------------------------------------------------------------------
+sal_Int32 EditableExtendedColorConfig::GetComponentColorCount(const ::rtl::OUString& _sName) const
+{
+ return m_pImpl->GetComponentColorCount(_sName);
+}
+// -----------------------------------------------------------------------------
+ExtendedColorConfigValue EditableExtendedColorConfig::GetComponentColorConfigValue(const ::rtl::OUString& _sName,sal_uInt32 _nPos) const
+{
+ return m_pImpl->GetComponentColorConfigValue(_sName,_nPos);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString EditableExtendedColorConfig::GetComponentName(sal_uInt32 _nPos) const
+{
+ return m_pImpl->GetComponentName(_nPos);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString EditableExtendedColorConfig::GetComponentDisplayName(const ::rtl::OUString& _sComponentName) const
+{
+ return m_pImpl->GetComponentDisplayName(_sComponentName);
+}
+}//namespace svtools
diff --git a/svtools/source/config/fontsubstconfig.cxx b/svtools/source/config/fontsubstconfig.cxx
new file mode 100644
index 000000000000..7bcbc1e4be82
--- /dev/null
+++ b/svtools/source/config/fontsubstconfig.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_svtools.hxx"
+
+#include "fontsubstconfig.hxx"
+#include <svl/svarray.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/debug.hxx>
+
+#include <vcl/outdev.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+
+const sal_Char cReplacement[] = "Replacement";
+const sal_Char cFontPairs[] = "FontPairs";
+
+const sal_Char cReplaceFont[] = "ReplaceFont";
+const sal_Char cSubstituteFont[]= "SubstituteFont";
+const sal_Char cOnScreenOnly[] = "OnScreenOnly";
+const sal_Char cAlways[] = "Always";
+
+//-----------------------------------------------------------------------------
+typedef SubstitutionStruct* SubstitutionStructPtr;
+SV_DECL_PTRARR_DEL(SubstitutionStructArr, SubstitutionStructPtr, 2, 2)
+SV_IMPL_PTRARR(SubstitutionStructArr, SubstitutionStructPtr);
+//-----------------------------------------------------------------------------
+struct SvtFontSubstConfig_Impl
+{
+ SubstitutionStructArr aSubstArr;
+};
+/* -----------------------------18.01.01 12:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvtFontSubstConfig::SvtFontSubstConfig() :
+ ConfigItem(C2U("Office.Common/Font/Substitution")),
+ bIsEnabled(sal_False),
+ pImpl(new SvtFontSubstConfig_Impl)
+{
+ RTL_LOGFILE_CONTEXT(aLog, "svtools SvtFontSubstConfig::SvtFontSubstConfig()");
+
+ Sequence<OUString> aNames(1);
+ aNames.getArray()[0] = C2U(cReplacement);
+ Sequence<Any> aValues = GetProperties(aNames);
+ DBG_ASSERT(aValues.getConstArray()[0].hasValue(), "no value available");
+ if(aValues.getConstArray()[0].hasValue())
+ bIsEnabled = *(sal_Bool*)aValues.getConstArray()[0].getValue();
+
+ OUString sPropPrefix(C2U(cFontPairs));
+ Sequence<OUString> aNodeNames = GetNodeNames(sPropPrefix, CONFIG_NAME_LOCAL_PATH);
+ const OUString* pNodeNames = aNodeNames.getConstArray();
+ Sequence<OUString> aPropNames(aNodeNames.getLength() * 4);
+ OUString* pNames = aPropNames.getArray();
+ sal_Int32 nName = 0;
+ sPropPrefix += C2U("/");
+ sal_Int32 nNode;
+ for(nNode = 0; nNode < aNodeNames.getLength(); nNode++)
+ {
+ OUString sStart(sPropPrefix);
+ sStart += pNodeNames[nNode];
+ sStart += C2U("/");
+ pNames[nName] = sStart; pNames[nName++] += C2U(cReplaceFont);
+ pNames[nName] = sStart; pNames[nName++] += C2U(cSubstituteFont);
+ pNames[nName] = sStart; pNames[nName++] += C2U(cAlways);
+ pNames[nName] = sStart; pNames[nName++] += C2U(cOnScreenOnly);
+ }
+ Sequence<Any> aNodeValues = GetProperties(aPropNames);
+ const Any* pNodeValues = aNodeValues.getConstArray();
+ nName = 0;
+ for(nNode = 0; nNode < aNodeNames.getLength(); nNode++)
+ {
+ SubstitutionStructPtr pInsert = new SubstitutionStruct;
+ pNodeValues[nName++] >>= pInsert->sFont;
+ pNodeValues[nName++] >>= pInsert->sReplaceBy;
+ pInsert->bReplaceAlways = *(sal_Bool*)pNodeValues[nName++].getValue();
+ pInsert->bReplaceOnScreenOnly = *(sal_Bool*)pNodeValues[nName++].getValue();
+ pImpl->aSubstArr.Insert(pInsert, pImpl->aSubstArr.Count());
+ }
+}
+/* -----------------------------18.01.01 12:06--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvtFontSubstConfig::~SvtFontSubstConfig()
+{
+ delete pImpl;
+}
+/*-- 18.01.01 12:08:00---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvtFontSubstConfig::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
+{
+}
+
+void SvtFontSubstConfig::Commit()
+{
+ Sequence<OUString> aNames(1);
+ aNames.getArray()[0] = C2U(cReplacement);
+ Sequence<Any> aValues(1);
+ aValues.getArray()[0].setValue(&bIsEnabled, ::getBooleanCppuType());
+ PutProperties(aNames, aValues);
+
+ OUString sNode(C2U(cFontPairs));
+ if(!pImpl->aSubstArr.Count())
+ ClearNodeSet(sNode);
+ else
+ {
+ Sequence<PropertyValue> aSetValues(4 * pImpl->aSubstArr.Count());
+ PropertyValue* pSetValues = aSetValues.getArray();
+ sal_Int32 nSetValue = 0;
+
+ const OUString sReplaceFont(C2U(cReplaceFont));
+ const OUString sSubstituteFont(C2U(cSubstituteFont));
+ const OUString sAlways(C2U(cAlways));
+ const OUString sOnScreenOnly(C2U(cOnScreenOnly));
+
+ const uno::Type& rBoolType = ::getBooleanCppuType();
+ for(sal_uInt16 i = 0; i < pImpl->aSubstArr.Count(); i++)
+ {
+ OUString sPrefix(sNode);
+ sPrefix += C2U("/_");
+ sPrefix += OUString::valueOf((sal_Int32)i);
+ sPrefix += C2U("/");
+
+ SubstitutionStructPtr pSubst = pImpl->aSubstArr[i];
+ pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sReplaceFont;
+ pSetValues[nSetValue++].Value <<= pSubst->sFont;
+ pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sSubstituteFont;
+ pSetValues[nSetValue++].Value <<= pSubst->sReplaceBy;
+ pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sAlways;
+ pSetValues[nSetValue++].Value.setValue(&pSubst->bReplaceAlways, rBoolType);
+ pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sOnScreenOnly;
+ pSetValues[nSetValue++].Value.setValue(&pSubst->bReplaceOnScreenOnly, rBoolType);
+ }
+ ReplaceSetProperties(sNode, aSetValues);
+ }
+}
+/*-- 18.01.01 12:08:00---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Int32 SvtFontSubstConfig::SubstitutionCount() const
+{
+ return pImpl->aSubstArr.Count();
+}
+/*-- 18.01.01 12:08:00---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvtFontSubstConfig::ClearSubstitutions()
+{
+ pImpl->aSubstArr.DeleteAndDestroy(0, pImpl->aSubstArr.Count());
+}
+/*-- 18.01.01 12:08:00---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+const SubstitutionStruct* SvtFontSubstConfig::GetSubstitution(sal_Int32 nPos)
+{
+ DBG_ASSERT(nPos >= 0 && nPos < pImpl->aSubstArr.Count(), "illegal array index");
+ if(nPos >= 0 && nPos < pImpl->aSubstArr.Count())
+ return pImpl->aSubstArr[(sal_uInt16)nPos];
+ return 0;
+}
+/*-- 18.01.01 12:08:01---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvtFontSubstConfig::AddSubstitution(const SubstitutionStruct& rToAdd)
+{
+ SubstitutionStructPtr pInsert = new SubstitutionStruct(rToAdd);
+ pImpl->aSubstArr.Insert(pInsert, pImpl->aSubstArr.Count());
+}
+
+void SvtFontSubstConfig::Apply()
+{
+ OutputDevice::BeginFontSubstitution();
+
+ // Alte Substitution entfernen
+ sal_uInt16 nOldCount = OutputDevice::GetFontSubstituteCount();
+
+ while (nOldCount)
+ OutputDevice::RemoveFontSubstitute(--nOldCount);
+
+ // Neue Substitution einlesen
+ sal_Int32 nCount = IsEnabled() ? SubstitutionCount() : 0;
+
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ sal_uInt16 nFlags = 0;
+ const SubstitutionStruct* pSubs = GetSubstitution(i);
+ if(pSubs->bReplaceAlways)
+ nFlags |= FONT_SUBSTITUTE_ALWAYS;
+ if(pSubs->bReplaceOnScreenOnly)
+ nFlags |= FONT_SUBSTITUTE_SCREENONLY;
+ OutputDevice::AddFontSubstitute( String(pSubs->sFont), String(pSubs->sReplaceBy), nFlags );
+ }
+
+ OutputDevice::EndFontSubstitution();
+}
diff --git a/svtools/source/config/helpopt.cxx b/svtools/source/config/helpopt.cxx
new file mode 100644
index 000000000000..091bf50c4787
--- /dev/null
+++ b/svtools/source/config/helpopt.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/helpopt.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <vcl/help.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/stl_types.hxx>
+
+#include <rtl/logfile.hxx>
+#include "itemholder2.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star;
+
+static SvtHelpOptions_Impl* pOptions = NULL;
+static sal_Int32 nRefCount = 0;
+
+#define EXTENDEDHELP 0
+#define HELPTIPS 1
+#define AGENT_ENABLED 2
+#define AGENT_TIMEOUT 3
+#define AGENT_RETRYLIMIT 4
+#define LOCALE 5
+#define SYSTEM 6
+#define STYLESHEET 7
+
+class SvtHelpOptions_Impl : public utl::ConfigItem
+{
+ IdList* pList;
+ sal_Int32 nHelpAgentTimeoutPeriod;
+ sal_Int32 nHelpAgentRetryLimit;
+ sal_Bool bExtendedHelp;
+ sal_Bool bHelpTips;
+ sal_Bool bHelpAgentEnabled;
+ sal_Bool bWelcomeScreen;
+ String aLocale;
+ String aSystem;
+ String sHelpStyleSheet;
+
+ DECLARE_STL_USTRINGACCESS_MAP( sal_Int32, MapString2Int );
+ MapString2Int aURLIgnoreCounters;
+ ::osl::Mutex aIgnoreCounterSafety;
+
+ Sequence< OUString > GetPropertyNames();
+
+public:
+ SvtHelpOptions_Impl();
+
+ virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
+ void Load( const ::com::sun::star::uno::Sequence< ::rtl::OUString>& aPropertyNames);
+ virtual void Commit();
+
+ void SetExtendedHelp( sal_Bool b ) { bExtendedHelp= b; SetModified(); }
+ sal_Bool IsExtendedHelp() const { return bExtendedHelp; }
+ void SetHelpTips( sal_Bool b ) { bHelpTips = b; SetModified(); }
+ sal_Bool IsHelpTips() const { return bHelpTips; }
+
+ void SetHelpAgentEnabled( sal_Bool b ) { bHelpAgentEnabled = b; SetModified(); }
+ sal_Bool IsHelpAgentEnabled() const { return bHelpAgentEnabled; }
+ void SetHelpAgentTimeoutPeriod( sal_Int32 _nSeconds ) { nHelpAgentTimeoutPeriod = _nSeconds; SetModified(); }
+ sal_Int32 GetHelpAgentTimeoutPeriod( ) const { return nHelpAgentTimeoutPeriod; }
+ void SetHelpAgentRetryLimit( sal_Int32 _nTrials ) { nHelpAgentRetryLimit = _nTrials; SetModified(); }
+ sal_Int32 GetHelpAgentRetryLimit( ) const { return nHelpAgentRetryLimit; }
+
+ sal_Int32 getAgentIgnoreURLCounter( const ::rtl::OUString& _rURL );
+ void decAgentIgnoreURLCounter( const ::rtl::OUString& _rURL );
+ void resetAgentIgnoreURLCounter( const ::rtl::OUString& _rURL );
+ void resetAgentIgnoreURLCounter();
+
+ void SetWelcomeScreen( sal_Bool b ) { bWelcomeScreen = b; SetModified(); }
+ sal_Bool IsWelcomeScreen() const { return bWelcomeScreen; }
+ IdList* GetPIStarterList() { return pList; }
+ void AddToPIStarterList( sal_Int32 nId );
+ void RemoveFromPIStarterList( sal_Int32 nId );
+ String GetLocale() const { return aLocale; }
+ String GetSystem() const { return aSystem; }
+
+ const String& GetHelpStyleSheet()const{return sHelpStyleSheet;}
+ void SetHelpStyleSheet(const String& rStyleSheet){sHelpStyleSheet = rStyleSheet; SetModified();}
+
+ static ::osl::Mutex & getInitMutex();
+
+protected:
+ void implLoadURLCounters();
+ void implSaveURLCounters();
+ // to be called with aIgnoreCounterSafety locked
+ void implGetURLCounters( Sequence< ::rtl::OUString >& _rNodeNames, Sequence< Any >& _rURLs, Sequence< Any >& _rCounter );
+};
+
+Sequence< OUString > SvtHelpOptions_Impl::GetPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "ExtendedTip",
+ "Tip",
+ "HelpAgent/Enabled",
+ "HelpAgent/Timeout",
+ "HelpAgent/RetryLimit",
+ "Locale",
+ "System",
+ "HelpStyleSheet",
+// "HowTo/Show"
+ };
+
+ const int nCount = sizeof( aPropNames ) / sizeof( const char* );
+ Sequence< OUString > aNames( nCount );
+ OUString* pNames = aNames.getArray();
+ for ( int i = 0; i < nCount; i++ )
+ pNames[i] = OUString::createFromAscii( aPropNames[i] );
+
+ return aNames;
+}
+
+::osl::Mutex & SvtHelpOptions_Impl::getInitMutex()
+{
+ static ::osl::Mutex *pMutex = 0;
+
+ if( ! pMutex )
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ if( ! pMutex )
+ {
+ static ::osl::Mutex mutex;
+ pMutex = &mutex;
+ }
+ }
+ return *pMutex;
+}
+
+
+// -----------------------------------------------------------------------
+
+SvtHelpOptions_Impl::SvtHelpOptions_Impl()
+ : ConfigItem( OUString::createFromAscii("Office.Common/Help") )
+ , pList( 0 )
+ , bExtendedHelp( sal_False )
+ , bHelpTips( sal_True )
+ , bHelpAgentEnabled( sal_False )
+ , bWelcomeScreen( sal_False )
+{
+ Sequence< OUString > aNames = GetPropertyNames();
+ Load( aNames );
+ EnableNotification( aNames );
+ implLoadURLCounters();
+}
+
+// -----------------------------------------------------------------------
+static int lcl_MapPropertyName( const ::rtl::OUString rCompare,
+ const uno::Sequence< ::rtl::OUString>& aInternalPropertyNames)
+{
+ for(int nProp = 0; nProp < aInternalPropertyNames.getLength(); ++nProp)
+ {
+ if( aInternalPropertyNames[nProp] == rCompare )
+ return nProp;
+ }
+ return -1;
+}
+
+void SvtHelpOptions_Impl::Load(const uno::Sequence< ::rtl::OUString>& rPropertyNames)
+{
+ const uno::Sequence< ::rtl::OUString> aInternalPropertyNames( GetPropertyNames());
+ Sequence< Any > aValues = GetProperties( rPropertyNames );
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" );
+ if ( aValues.getLength() == rPropertyNames.getLength() )
+ {
+ for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
+ {
+ DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" );
+ if ( pValues[nProp].hasValue() )
+ {
+ sal_Bool bTmp = sal_Bool();
+ ::rtl::OUString aTmpStr;
+ sal_Int32 nTmpInt = 0;
+ if ( pValues[nProp] >>= bTmp )
+ {
+ switch ( lcl_MapPropertyName(rPropertyNames[nProp], aInternalPropertyNames) )
+ {
+ case EXTENDEDHELP :
+ bExtendedHelp = bTmp;
+ break;
+ case HELPTIPS :
+ bHelpTips = bTmp;
+ break;
+ case AGENT_ENABLED :
+ bHelpAgentEnabled = bTmp;
+ break;
+ default:
+ DBG_ERRORFILE( "Wrong Member!" );
+ break;
+ }
+ }
+ else if ( pValues[nProp] >>= aTmpStr )
+ {
+ switch ( nProp )
+ {
+ case LOCALE:
+ aLocale = aTmpStr;
+ break;
+
+ case SYSTEM:
+ aSystem = aTmpStr;
+ break;
+ case STYLESHEET :
+ sHelpStyleSheet = aTmpStr;
+ break;
+ default:
+ DBG_ERRORFILE( "Wrong Member!" );
+ break;
+ }
+ }
+ else if ( pValues[nProp] >>= nTmpInt )
+ {
+ switch ( nProp )
+ {
+ case AGENT_TIMEOUT:
+ nHelpAgentTimeoutPeriod = nTmpInt;
+ break;
+
+ case AGENT_RETRYLIMIT:
+ nHelpAgentRetryLimit = nTmpInt;
+ break;
+
+ default:
+ DBG_ERRORFILE( "Wrong Member!" );
+ break;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "Wrong Type!" );
+ }
+ }
+ }
+ if ( IsHelpTips() != Help::IsQuickHelpEnabled() )
+ IsHelpTips() ? Help::EnableQuickHelp() : Help::DisableQuickHelp();
+ if ( IsExtendedHelp() != Help::IsBalloonHelpEnabled() )
+ IsExtendedHelp() ? Help::EnableBalloonHelp() : Help::DisableBalloonHelp();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::implGetURLCounters( Sequence< ::rtl::OUString >& _rNodeNames, Sequence< Any >& _rURLs, Sequence< Any >& _rCounters )
+{
+ // the ignore counters for the help agent URLs
+ const ::rtl::OUString sIgnoreListNodePath = ::rtl::OUString::createFromAscii("HelpAgent/IgnoreList");
+ const ::rtl::OUString sPathSeparator = ::rtl::OUString::createFromAscii("/");
+ const ::rtl::OUString sURLLocalPath = ::rtl::OUString::createFromAscii("/Name");
+ const ::rtl::OUString sCounterLocalPath = ::rtl::OUString::createFromAscii("/Counter");
+
+ // get the names of all the nodes containing ignore counters
+ // collect the node names we have to ask
+ // first get the node names of all children of HelpAgent/IgnoreList
+ _rNodeNames = GetNodeNames(sIgnoreListNodePath);
+ const ::rtl::OUString* pIgnoredURLsNodes = _rNodeNames.getConstArray();
+ const ::rtl::OUString* pIgnoredURLsNodesEnd = pIgnoredURLsNodes + _rNodeNames.getLength();
+
+ // then assemble the two lists (of node paths) for the URLs and the counters
+ Sequence< ::rtl::OUString > aIgnoredURLs(_rNodeNames.getLength());
+ Sequence< ::rtl::OUString > aIgnoredURLsCounter(_rNodeNames.getLength());
+ ::rtl::OUString* pIgnoredURLs = aIgnoredURLs.getArray();
+ ::rtl::OUString* pIgnoredURLsCounter = aIgnoredURLsCounter.getArray();
+ for (;pIgnoredURLsNodes != pIgnoredURLsNodesEnd; ++pIgnoredURLsNodes, ++pIgnoredURLs, ++pIgnoredURLsCounter)
+ {
+ ::rtl::OUString sLocalURLAccess = sIgnoreListNodePath;
+ sLocalURLAccess += sPathSeparator;
+ sLocalURLAccess += *pIgnoredURLsNodes;
+
+ // the path to the URL of this specific entry
+ *pIgnoredURLs = sLocalURLAccess;
+ *pIgnoredURLs += sURLLocalPath;
+
+ // the path of the counter for that URL
+ *pIgnoredURLsCounter = sLocalURLAccess;
+ *pIgnoredURLsCounter += sCounterLocalPath;
+ }
+
+ // now collect the values
+ _rURLs = GetProperties(aIgnoredURLs);
+ _rCounters = GetProperties(aIgnoredURLsCounter);
+
+ sal_Int32 nURLs = _rURLs.getLength();
+ sal_Int32 nCounters = _rCounters.getLength();
+ DBG_ASSERT(nURLs == nCounters, "SvtHelpOptions_Impl::implGetURLCounters: inconsistence while retrieving the visited URLs!");
+
+ // normalize in case something went wrong
+ sal_Int32 nKnownURLs = nURLs < nCounters ? nURLs : nCounters;
+ if (nURLs < nCounters)
+ {
+ _rCounters.realloc(nKnownURLs);
+ _rNodeNames.realloc(nKnownURLs);
+ }
+ else if (nURLs > nCounters)
+ {
+ _rURLs.realloc(nKnownURLs);
+ _rNodeNames.realloc(nKnownURLs);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::implSaveURLCounters()
+{
+ ::osl::MutexGuard aGuard(aIgnoreCounterSafety);
+
+ const ::rtl::OUString sIgnoreListNodePath = ::rtl::OUString::createFromAscii("HelpAgent/IgnoreList");
+ const ::rtl::OUString sPathSeparator = ::rtl::OUString::createFromAscii("/");
+ const ::rtl::OUString sURLLocalPath = ::rtl::OUString::createFromAscii("/Name");
+ const ::rtl::OUString sCounterLocalPath = ::rtl::OUString::createFromAscii("/Counter");
+
+ // get the current URL/counter pairs (as they're persistent at the moment)
+ Sequence< ::rtl::OUString > aNodeNames;
+ Sequence< Any > aURLs;
+ Sequence< Any > aCounters;
+
+ implGetURLCounters(aNodeNames, aURLs, aCounters);
+ sal_Int32 nKnownURLs = aURLs.getLength();
+
+ const ::rtl::OUString* pNodeNames = aNodeNames.getConstArray();
+ const Any* pURLs = aURLs.getConstArray();
+ const Any* pCounters = aCounters.getConstArray();
+
+ // check which of them must be deleted/modified
+ Sequence< ::rtl::OUString > aDeleteFromConfig(nKnownURLs); // names of nodes to be deleted
+ ::rtl::OUString* pDeleteFromConfig = aDeleteFromConfig.getArray();
+ ::std::set< ::rtl::OUString > aAlreadyPresent; // URLs currently persistent
+
+ // for modifying already existent nodes
+ Sequence< ::rtl::OUString > aNewCounterNodePaths(nKnownURLs);
+ Sequence< Any > aNewCounterValues(nKnownURLs);
+ ::rtl::OUString* pNewCounterNodePaths = aNewCounterNodePaths.getArray();
+ Any* pNewCounterValues = aNewCounterValues.getArray();
+
+ // temporaries needed inside the loop
+ ::rtl::OUString sCurrentURL, sCurrentURLNodeName;
+
+ for (sal_Int32 i=0; i<nKnownURLs; ++i, ++pNodeNames, ++pURLs, ++pCounters)
+ {
+ if (!((*pURLs) >>= sCurrentURL))
+ continue;
+
+ ConstMapString2IntIterator aThisURLNewCounter = aURLIgnoreCounters.find(sCurrentURL);
+ if (aURLIgnoreCounters.end() == aThisURLNewCounter)
+ { // we do not know anything about this URL anymore.
+ // -> have to removed it from the configuration later on
+ *pDeleteFromConfig = *pNodeNames;
+ ++pDeleteFromConfig;
+ }
+ else
+ { // we know this URL
+ sCurrentURLNodeName = sIgnoreListNodePath;
+ sCurrentURLNodeName += sPathSeparator;
+ sCurrentURLNodeName += *pNodeNames;
+
+ // -> remember this (so we don't need to add a new node for this URL later on)
+ aAlreadyPresent.insert(sCurrentURL);
+
+ sal_Int32 nThisURLPersistentCounter = 0;
+ (*pCounters) >>= nThisURLPersistentCounter;
+
+ if (aThisURLNewCounter->second != nThisURLPersistentCounter)
+ { // the counter changed
+ // -> remember the path and the new counter for the adjustment below
+ *pNewCounterNodePaths = sCurrentURLNodeName;
+ *pNewCounterNodePaths += sCounterLocalPath;
+ ++pNewCounterNodePaths;
+
+ (*pNewCounterValues) <<= aThisURLNewCounter->second;
+ ++pNewCounterValues;
+ }
+ }
+ }
+
+ // delete the nodes which are flagged so ...
+ aDeleteFromConfig.realloc(pDeleteFromConfig - aDeleteFromConfig.getArray());
+ if (0 != aDeleteFromConfig.getLength())
+ {
+ ClearNodeElements(sIgnoreListNodePath, aDeleteFromConfig);
+ }
+
+ // modify the nodes which need to be
+ aNewCounterNodePaths.realloc(pNewCounterNodePaths - aNewCounterNodePaths.getArray());
+ aNewCounterValues.realloc(pNewCounterValues - aNewCounterValues.getArray());
+ if (0 != aNewCounterNodePaths.getLength())
+ {
+ PutProperties(aNewCounterNodePaths, aNewCounterValues);
+ }
+
+ // and for the new ones ...
+ ::rtl::OUString sNewNodeName;
+ Sequence< ::rtl::OUString > aNewCounterDataNodeNames(2);
+ Sequence< Any > aNewCounterDataValues(2);
+ const ::rtl::OUString sNodeNameBase = ::rtl::OUString::createFromAscii("URL");
+ for ( ConstMapString2IntIterator aCollectNew = aURLIgnoreCounters.begin();
+ aCollectNew != aURLIgnoreCounters.end();
+ ++aCollectNew
+ )
+ {
+ if (aAlreadyPresent.end() == aAlreadyPresent.find(aCollectNew->first))
+ { // this URL is not persistent, yet
+ // -> add a new node
+ sNewNodeName = sNodeNameBase;
+ if (!getUniqueSetElementName(sIgnoreListNodePath, sNewNodeName))
+ {
+ DBG_ERRORFILE( "SvtHelpOptions_Impl::implSaveURLCounters: could not get a free name!" );
+ continue;
+ }
+ AddNode(sIgnoreListNodePath, sNewNodeName);
+
+ // and set the URL/counter pair
+ aNewCounterDataNodeNames[0] = sIgnoreListNodePath;
+ aNewCounterDataNodeNames[0] += sPathSeparator;
+ aNewCounterDataNodeNames[0] += sNewNodeName;
+ aNewCounterDataNodeNames[0] += sURLLocalPath;
+ aNewCounterDataValues[0] <<= aCollectNew->first;
+
+ aNewCounterDataNodeNames[1] = sIgnoreListNodePath;
+ aNewCounterDataNodeNames[1] += sPathSeparator;
+ aNewCounterDataNodeNames[1] += sNewNodeName;
+ aNewCounterDataNodeNames[1] += sCounterLocalPath;
+ aNewCounterDataValues[1] <<= aCollectNew->second;
+
+ PutProperties(aNewCounterDataNodeNames, aNewCounterDataValues);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::implLoadURLCounters()
+{
+ ::osl::MutexGuard aGuard(aIgnoreCounterSafety);
+
+ Sequence< ::rtl::OUString > aNodeNames;
+ Sequence< Any > aURLs;
+ Sequence< Any > aCounters;
+
+ implGetURLCounters(aNodeNames, aURLs, aCounters);
+ sal_Int32 nKnownURLs = aURLs.getLength();
+
+ const Any* pURLs = aURLs.getConstArray();
+ const Any* pCounters = aCounters.getConstArray();
+
+ ::rtl::OUString sCurrentURL;
+ sal_Int32 nCurrentCounter;
+ for (sal_Int32 i=0; i<nKnownURLs; ++i, ++pURLs, ++pCounters)
+ {
+ (*pURLs) >>= sCurrentURL;
+ nCurrentCounter = 0;
+ (*pCounters) >>= nCurrentCounter;
+ aURLIgnoreCounters[sCurrentURL] = nCurrentCounter;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::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 EXTENDEDHELP :
+ pValues[nProp] <<= bExtendedHelp;
+ break;
+
+ case HELPTIPS :
+ pValues[nProp] <<= bHelpTips;
+ break;
+
+ case AGENT_ENABLED :
+ pValues[nProp] <<= bHelpAgentEnabled;
+ break;
+
+ case AGENT_TIMEOUT:
+ pValues[nProp] <<= nHelpAgentTimeoutPeriod;
+ break;
+
+ case AGENT_RETRYLIMIT:
+ pValues[nProp] <<= nHelpAgentRetryLimit;
+ break;
+
+ case LOCALE:
+ pValues[nProp] <<= ::rtl::OUString(aLocale);
+ break;
+
+ case SYSTEM:
+ pValues[nProp] <<= ::rtl::OUString(aSystem);
+ break;
+ case STYLESHEET :
+ pValues[nProp] <<= ::rtl::OUString(sHelpStyleSheet);
+ break;
+
+ }
+ }
+
+ PutProperties( aNames, aValues );
+
+ implSaveURLCounters();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::Notify( const Sequence<rtl::OUString>& aPropertyNames )
+{
+ Load( aPropertyNames );
+}
+
+SvtHelpOptions::SvtHelpOptions()
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( SvtHelpOptions_Impl::getInitMutex() );
+ ++nRefCount;
+ if ( !pOptions )
+ {
+ RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtHelpOptions_Impl::ctor()");
+ pOptions = new SvtHelpOptions_Impl;
+
+ ItemHolder2::holdConfigItem(E_HELPOPTIONS);
+ }
+ pImp = pOptions;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 SvtHelpOptions_Impl::getAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
+{
+ ::osl::MutexGuard aGuard(aIgnoreCounterSafety);
+ ConstMapString2IntIterator aMapPos = aURLIgnoreCounters.find(_rURL);
+ if (aURLIgnoreCounters.end() == aMapPos)
+ return GetHelpAgentRetryLimit();
+ return aMapPos->second;
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::decAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
+{
+ ::osl::MutexGuard aGuard(aIgnoreCounterSafety);
+ MapString2IntIterator aMapPos = aURLIgnoreCounters.find(_rURL);
+ if (aURLIgnoreCounters.end() == aMapPos)
+ { // nothing known about this URL 'til now
+ sal_Int32 nLimit = GetHelpAgentRetryLimit();
+ sal_Int32 nIgnoreAgain = nLimit > 0 ? nLimit - 1 : 0;
+ aURLIgnoreCounters[_rURL] = nIgnoreAgain;
+ }
+ else
+ {
+ sal_Int32& rCounter = aMapPos->second;
+ if (rCounter)
+ --rCounter;
+ }
+ SetModified();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::resetAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
+{
+ ::osl::MutexGuard aGuard(aIgnoreCounterSafety);
+ MapString2IntIterator aMapPos = aURLIgnoreCounters.find(_rURL);
+ if (aURLIgnoreCounters.end() != aMapPos)
+ {
+ aURLIgnoreCounters.erase(aMapPos);
+ SetModified();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions_Impl::resetAgentIgnoreURLCounter()
+{
+ ::osl::MutexGuard aGuard(aIgnoreCounterSafety);
+ aURLIgnoreCounters.clear();
+ SetModified();
+}
+
+// -----------------------------------------------------------------------
+
+SvtHelpOptions::~SvtHelpOptions()
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( SvtHelpOptions_Impl::getInitMutex() );
+ if ( !--nRefCount )
+ {
+ if ( pOptions->IsModified() )
+ pOptions->Commit();
+ DELETEZ( pOptions );
+ }
+}
+
+void SvtHelpOptions::SetExtendedHelp( sal_Bool b )
+{
+ pImp->SetExtendedHelp( b );
+}
+
+sal_Bool SvtHelpOptions::IsExtendedHelp() const
+{
+ return pImp->IsExtendedHelp();
+}
+
+void SvtHelpOptions::SetHelpTips( sal_Bool b )
+{
+ pImp->SetHelpTips( b );
+}
+
+sal_Bool SvtHelpOptions::IsHelpTips() const
+{
+ return pImp->IsHelpTips();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::SetHelpAgentRetryLimit( sal_Int32 _nTrials )
+{
+ pImp->SetHelpAgentRetryLimit( _nTrials );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 SvtHelpOptions::GetHelpAgentRetryLimit( ) const
+{
+ return pImp->GetHelpAgentRetryLimit( );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::SetHelpAgentTimeoutPeriod( sal_Int32 _nSeconds )
+{
+ pImp->SetHelpAgentTimeoutPeriod( _nSeconds );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 SvtHelpOptions::GetHelpAgentTimeoutPeriod( ) const
+{
+ return pImp->GetHelpAgentTimeoutPeriod( );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::SetHelpAgentAutoStartMode( sal_Bool b )
+{
+ pImp->SetHelpAgentEnabled( b );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvtHelpOptions::IsHelpAgentAutoStartMode() const
+{
+ return pImp->IsHelpAgentEnabled();
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 SvtHelpOptions::getAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
+{
+ return pImp->getAgentIgnoreURLCounter( _rURL );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::decAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
+{
+ pImp->decAgentIgnoreURLCounter( _rURL );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::resetAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
+{
+ pImp->resetAgentIgnoreURLCounter( _rURL );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::resetAgentIgnoreURLCounter()
+{
+ pImp->resetAgentIgnoreURLCounter();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtHelpOptions::SetWelcomeScreen( sal_Bool b )
+{
+ pImp->SetWelcomeScreen( b );
+}
+
+sal_Bool SvtHelpOptions::IsWelcomeScreen() const
+{
+ return pImp->IsWelcomeScreen();
+}
+
+IdList* SvtHelpOptions::GetPIStarterList()
+{
+ return pImp->GetPIStarterList();
+}
+
+void SvtHelpOptions::AddToPIStarterList( sal_Int32 )
+{
+}
+
+void SvtHelpOptions::RemoveFromPIStarterList( sal_Int32 )
+{
+}
+
+String SvtHelpOptions::GetLocale() const
+{
+ return pImp->GetLocale();
+}
+
+String SvtHelpOptions::GetSystem() const
+{
+ return pImp->GetSystem();
+}
+
+const String& SvtHelpOptions::GetHelpStyleSheet()const
+{
+ return pImp->GetHelpStyleSheet();
+}
+
+void SvtHelpOptions::SetHelpStyleSheet(const String& rStyleSheet)
+{
+ pImp->SetHelpStyleSheet(rStyleSheet);
+}
+
diff --git a/svtools/source/config/htmlcfg.cxx b/svtools/source/config/htmlcfg.cxx
new file mode 100644
index 000000000000..b8a9660ee8dc
--- /dev/null
+++ b/svtools/source/config/htmlcfg.cxx
@@ -0,0 +1,523 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/htmlcfg.hxx>
+#include <svtools/parhtml.hxx>
+#include <unotools/syslocale.hxx>
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/link.hxx>
+
+// -----------------------------------------------------------------------
+#define HTMLCFG_UNKNOWN_TAGS 0x01
+//#define HTMLCFG_STYLE_SHEETS 0x02
+//#define HTMLCFG_NETSCAPE3 0x04
+#define HTMLCFG_STAR_BASIC 0x08
+#define HTMLCFG_LOCAL_GRF 0x10
+#define HTMLCFG_PRINT_LAYOUT_EXTENSION 0x20
+#define HTMLCFG_IGNORE_FONT_FAMILY 0x40
+#define HTMLCFG_IS_BASIC_WARNING 0x80
+#define HTMLCFG_NUMBERS_ENGLISH_US 0x100
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+static SvxHtmlOptions* pOptions = 0;
+
+DECLARE_LIST( LinkList, Link * )
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+/* -----------------------------23.11.00 11:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+struct HtmlOptions_Impl
+{
+ LinkList aList;
+ sal_Int32 nFlags;
+ sal_Int32 nExportMode;
+ sal_Int32 aFontSizeArr[HTML_FONT_COUNT];
+ sal_Int32 eEncoding;
+ sal_Bool bIsEncodingDefault;
+
+ HtmlOptions_Impl() :
+ nFlags(HTMLCFG_LOCAL_GRF|HTMLCFG_IS_BASIC_WARNING),
+ nExportMode(HTML_CFG_NS40),
+ eEncoding( gsl_getSystemTextEncoding() ),
+ bIsEncodingDefault(sal_True)
+ {
+ aFontSizeArr[0] = HTMLFONTSZ1_DFLT;
+ aFontSizeArr[1] = HTMLFONTSZ2_DFLT;
+ aFontSizeArr[2] = HTMLFONTSZ3_DFLT;
+ aFontSizeArr[3] = HTMLFONTSZ4_DFLT;
+ aFontSizeArr[4] = HTMLFONTSZ5_DFLT;
+ aFontSizeArr[5] = HTMLFONTSZ6_DFLT;
+ aFontSizeArr[6] = HTMLFONTSZ7_DFLT;
+ }
+};
+
+/* -----------------------------23.11.00 11:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const Sequence<OUString>& SvxHtmlOptions::GetPropertyNames()
+{
+ static Sequence<OUString> aNames;
+ if(!aNames.getLength())
+ {
+ static const char* aPropNames[] =
+ {
+ "Import/UnknownTag", // 0
+ "Import/FontSetting", // 1
+ "Import/FontSize/Size_1", // 2
+ "Import/FontSize/Size_2", // 3
+ "Import/FontSize/Size_3", // 4
+ "Import/FontSize/Size_4", // 5
+ "Import/FontSize/Size_5", // 6
+ "Import/FontSize/Size_6", // 7
+ "Import/FontSize/Size_7", // 8
+ "Export/Browser", // 9
+ "Export/Basic", // 0
+ "Export/PrintLayout", // 11
+ "Export/LocalGraphic", // 12
+ "Export/Warning", // 13
+ "Export/Encoding", // 14
+ "Import/NumbersEnglishUS" // 15
+ };
+ const int nCount = sizeof(aPropNames) / sizeof(aPropNames[0]);
+ aNames.realloc(nCount);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < nCount; i++)
+ pNames[i] = C2U(aPropNames[i]);
+ }
+ return aNames;
+}
+// -----------------------------------------------------------------------
+SvxHtmlOptions::SvxHtmlOptions() :
+ ConfigItem(C2U("Office.Common/Filter/HTML"))
+{
+ pImp = new HtmlOptions_Impl;
+ Load( GetPropertyNames() );
+}
+
+// -----------------------------------------------------------------------
+SvxHtmlOptions::~SvxHtmlOptions()
+{
+ delete pImp;
+}
+
+void SvxHtmlOptions::Load( const Sequence< OUString >& aNames )
+{
+ Sequence<Any> aValues = GetProperties(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ pImp->nFlags = 0;
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case 0:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_UNKNOWN_TAGS;
+ break;//"Import/UnknownTag",
+ case 1:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_IGNORE_FONT_FAMILY;
+ break;//"Import/FontSetting",
+ case 2: pValues[nProp] >>= pImp->aFontSizeArr[0]; break;//"Import/FontSize/Size_1",
+ case 3: pValues[nProp] >>= pImp->aFontSizeArr[1]; break;//"Import/FontSize/Size_2",
+ case 4: pValues[nProp] >>= pImp->aFontSizeArr[2]; break;//"Import/FontSize/Size_3",
+ case 5: pValues[nProp] >>= pImp->aFontSizeArr[3]; break;//"Import/FontSize/Size_4",
+ case 6: pValues[nProp] >>= pImp->aFontSizeArr[4]; break;//"Import/FontSize/Size_5",
+ case 7: pValues[nProp] >>= pImp->aFontSizeArr[5]; break;//"Import/FontSize/Size_6",
+ case 8: pValues[nProp] >>= pImp->aFontSizeArr[6]; break;//"Import/FontSize/Size_7",
+ case 9://"Export/Browser",
+ {
+ sal_Int32 nExpMode = 0;
+// pValues[nProp] >>= pImp->nExportMode;
+ pValues[nProp] >>= nExpMode;
+ switch( nExpMode )
+ {
+ case 0: nExpMode = HTML_CFG_HTML32; break;
+ case 1: nExpMode = HTML_CFG_MSIE_40; break;
+// case 2: nExpMode = HTML_CFG_NS30; break; depricated
+ case 3: nExpMode = HTML_CFG_WRITER; break;
+ case 4: nExpMode = HTML_CFG_NS40; break;
+ case 5: nExpMode = HTML_CFG_MSIE_40_OLD;break;
+ default: nExpMode = HTML_CFG_NS40; break;
+ }
+
+ pImp->nExportMode = nExpMode;
+ }
+ break;
+ case 10:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_STAR_BASIC;
+ break;//"Export/Basic",
+ case 11:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_PRINT_LAYOUT_EXTENSION;
+ break;//"Export/PrintLayout",
+ case 12:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_LOCAL_GRF;
+ break;//"Export/LocalGraphic",
+ case 13:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_IS_BASIC_WARNING;
+ break;//"Export/Warning"
+
+ case 14: pValues[nProp] >>= pImp->eEncoding;
+ pImp->bIsEncodingDefault = sal_False;
+ break;//"Export/Encoding"
+
+ case 15:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ pImp->nFlags |= HTMLCFG_NUMBERS_ENGLISH_US;
+ break;//"Import/NumbersEnglishUS"
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvxHtmlOptions::Commit()
+{
+ const Sequence<OUString>& aNames = GetPropertyNames();
+
+// const OUString* pNames = aNames.getConstArray();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+// const Type& rType = ::getBooleanCppuType();
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ sal_Bool bSet = sal_False;
+ switch(nProp)
+ {
+ case 0: bSet = 0 != (pImp->nFlags & HTMLCFG_UNKNOWN_TAGS);break;//"Import/UnknownTag",
+ case 1: bSet = 0 != (pImp->nFlags & HTMLCFG_IGNORE_FONT_FAMILY);break;//"Import/FontSetting",
+ case 2: pValues[nProp] <<= pImp->aFontSizeArr[0];break;//"Import/FontSize/Size_1",
+ case 3: pValues[nProp] <<= pImp->aFontSizeArr[1];break;//"Import/FontSize/Size_2",
+ case 4: pValues[nProp] <<= pImp->aFontSizeArr[2];break;//"Import/FontSize/Size_3",
+ case 5: pValues[nProp] <<= pImp->aFontSizeArr[3];break;//"Import/FontSize/Size_4",
+ case 6: pValues[nProp] <<= pImp->aFontSizeArr[4];break;//"Import/FontSize/Size_5",
+ case 7: pValues[nProp] <<= pImp->aFontSizeArr[5];break;//"Import/FontSize/Size_6",
+ case 8: pValues[nProp] <<= pImp->aFontSizeArr[6];break;//"Import/FontSize/Size_7",
+ case 9: //"Export/Browser",
+ {
+ sal_Int32 nExpMode = pImp->nExportMode;
+
+ switch( nExpMode )
+ {
+ case HTML_CFG_HTML32: nExpMode = 0; break;
+ case HTML_CFG_MSIE_40: nExpMode = 1; break;
+// case HTML_CFG_NS30: nExpMode = 2; break; depricated
+ case HTML_CFG_WRITER: nExpMode = 3; break;
+ case HTML_CFG_NS40: nExpMode = 4; break;
+ case HTML_CFG_MSIE_40_OLD: nExpMode = 5; break;
+ default: nExpMode = 4; break; // NS40
+ }
+
+ pValues[nProp] <<= nExpMode;
+ break;
+ }
+ case 10: bSet = 0 != (pImp->nFlags & HTMLCFG_STAR_BASIC);break;//"Export/Basic",
+ case 11: bSet = 0 != (pImp->nFlags & HTMLCFG_PRINT_LAYOUT_EXTENSION);break;//"Export/PrintLayout",
+ case 12: bSet = 0 != (pImp->nFlags & HTMLCFG_LOCAL_GRF);break;//"Export/LocalGraphic",
+ case 13: bSet = 0 != (pImp->nFlags & HTMLCFG_IS_BASIC_WARNING);break;//"Export/Warning"
+ case 14:
+ if(!pImp->bIsEncodingDefault)
+ pValues[nProp] <<= pImp->eEncoding;
+ break;//"Export/Encoding",
+ case 15: bSet = 0 != (pImp->nFlags & HTMLCFG_NUMBERS_ENGLISH_US);break;//"Import/NumbersEnglishUS"
+ }
+ if(nProp < 2 || ( nProp > 9 && nProp < 14 ) || nProp == 15)
+ pValues[nProp].setValue(&bSet, ::getCppuBooleanType());
+ }
+ PutProperties(aNames, aValues);
+}
+
+void SvxHtmlOptions::AddListenerLink( const Link& rLink )
+{
+ pImp->aList.Insert( new Link( rLink ) );
+}
+
+void SvxHtmlOptions::RemoveListenerLink( const Link& rLink )
+{
+ for ( USHORT n=0; n<pImp->aList.Count(); n++ )
+ {
+ if ( (*pImp->aList.GetObject(n) ) == rLink )
+ {
+ delete pImp->aList.Remove(n);
+ break;
+ }
+ }
+}
+
+void SvxHtmlOptions::CallListeners()
+{
+ for ( USHORT n = 0; n < pImp->aList.Count(); ++n )
+ pImp->aList.GetObject(n)->Call( this );
+}
+
+
+void SvxHtmlOptions::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
+{
+ Load( GetPropertyNames() );
+ CallListeners();
+}
+
+// -----------------------------------------------------------------------
+USHORT SvxHtmlOptions::GetFontSize(USHORT nPos) const
+{
+ if(nPos < HTML_FONT_COUNT)
+ return (USHORT)pImp->aFontSizeArr[nPos];
+ return 0;
+}
+// -----------------------------------------------------------------------
+void SvxHtmlOptions::SetFontSize(USHORT nPos, USHORT nSize)
+{
+ if(nPos < HTML_FONT_COUNT)
+ {
+ pImp->aFontSizeArr[nPos] = nSize;
+ SetModified();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+
+BOOL SvxHtmlOptions::IsImportUnknown() const
+{
+ return 0 != (pImp->nFlags & HTMLCFG_UNKNOWN_TAGS) ;
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxHtmlOptions::SetImportUnknown(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_UNKNOWN_TAGS;
+ else
+ pImp->nFlags &= ~HTMLCFG_UNKNOWN_TAGS;
+ SetModified();
+}
+
+// -----------------------------------------------------------------------
+
+
+USHORT SvxHtmlOptions::GetExportMode() const
+{
+ return (USHORT)pImp->nExportMode;
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxHtmlOptions::SetExportMode(USHORT nSet)
+{
+ if(nSet <= HTML_CFG_MAX )
+ {
+ pImp->nExportMode = nSet;
+ SetModified();
+ CallListeners();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+
+BOOL SvxHtmlOptions::IsStarBasic() const
+{
+ return 0 != (pImp->nFlags & HTMLCFG_STAR_BASIC) ;
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxHtmlOptions::SetStarBasic(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_STAR_BASIC;
+ else
+ pImp->nFlags &= ~HTMLCFG_STAR_BASIC;
+ SetModified();
+}
+
+/*-----------------14.02.97 08.34-------------------
+
+--------------------------------------------------*/
+
+BOOL SvxHtmlOptions::IsSaveGraphicsLocal() const
+{
+ return 0 != (pImp->nFlags & HTMLCFG_LOCAL_GRF) ;
+}
+/*-----------------14.02.97 08.34-------------------
+
+--------------------------------------------------*/
+void SvxHtmlOptions::SetSaveGraphicsLocal(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_LOCAL_GRF;
+ else
+ pImp->nFlags &= ~HTMLCFG_LOCAL_GRF;
+ SetModified();
+}
+
+/*-----------------10/21/97 08:34am-----------------
+
+--------------------------------------------------*/
+
+BOOL SvxHtmlOptions::IsPrintLayoutExtension() const
+{
+ BOOL bRet = 0 != (pImp->nFlags & HTMLCFG_PRINT_LAYOUT_EXTENSION);
+ switch( pImp->nExportMode )
+ {
+ case HTML_CFG_MSIE_40:
+ case HTML_CFG_NS40 :
+ case HTML_CFG_WRITER :
+ break;
+ default:
+ bRet = FALSE;
+ }
+ return bRet;
+}
+/*-----------------10/21/97 08:34am-----------------
+
+--------------------------------------------------*/
+void SvxHtmlOptions::SetPrintLayoutExtension(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_PRINT_LAYOUT_EXTENSION;
+ else
+ pImp->nFlags &= ~HTMLCFG_PRINT_LAYOUT_EXTENSION;
+ SetModified();
+}
+
+/*-----------------10.07.98 10.02-------------------
+
+--------------------------------------------------*/
+
+BOOL SvxHtmlOptions::IsIgnoreFontFamily() const
+{
+ return 0 != (pImp->nFlags & HTMLCFG_IGNORE_FONT_FAMILY) ;
+}
+/*-----------------10.07.98 10.02-------------------
+
+--------------------------------------------------*/
+void SvxHtmlOptions::SetIgnoreFontFamily(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_IGNORE_FONT_FAMILY;
+ else
+ pImp->nFlags &= ~HTMLCFG_IGNORE_FONT_FAMILY;
+ SetModified();
+}
+/* -----------------05.02.99 09:03-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxHtmlOptions::IsStarBasicWarning() const
+{
+ return 0 != (pImp->nFlags & HTMLCFG_IS_BASIC_WARNING) ;
+}
+/* -----------------05.02.99 09:03-------------------
+ *
+ * --------------------------------------------------*/
+void SvxHtmlOptions::SetStarBasicWarning(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_IS_BASIC_WARNING;
+ else
+ pImp->nFlags &= ~HTMLCFG_IS_BASIC_WARNING;
+ SetModified();
+}
+
+/*-----------------19.02.2001 18:40-----------------
+ *
+ * --------------------------------------------------*/
+rtl_TextEncoding SvxHtmlOptions::GetTextEncoding() const
+{
+ rtl_TextEncoding eRet;
+ if(pImp->bIsEncodingDefault)
+ eRet = SvtSysLocale::GetBestMimeEncoding();
+ else
+ eRet = (rtl_TextEncoding)pImp->eEncoding;
+ return eRet;
+}
+
+/*-----------------19.02.2001 18:40-----------------
+ *
+ * --------------------------------------------------*/
+void SvxHtmlOptions::SetTextEncoding( rtl_TextEncoding eEnc )
+{
+ pImp->eEncoding = eEnc;
+ pImp->bIsEncodingDefault = sal_False;
+ SetModified();
+}
+/* -----------------------------15.08.2001 12:01------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool SvxHtmlOptions::IsDefaultTextEncoding() const
+{
+ return pImp->bIsEncodingDefault;
+}
+
+SvxHtmlOptions* SvxHtmlOptions::Get()
+{
+ if ( !pOptions )
+ pOptions = new SvxHtmlOptions;
+ return pOptions;
+}
+
+
+/* ---------------------- 2006-06-07T21:02+0200 ---------------------- */
+BOOL SvxHtmlOptions::IsNumbersEnglishUS() const
+{
+ return 0 != (pImp->nFlags & HTMLCFG_NUMBERS_ENGLISH_US) ;
+}
+
+
+/* ---------------------- 2006-06-07T21:02+0200 ---------------------- */
+void SvxHtmlOptions::SetNumbersEnglishUS(BOOL bSet)
+{
+ if(bSet)
+ pImp->nFlags |= HTMLCFG_NUMBERS_ENGLISH_US;
+ else
+ pImp->nFlags &= ~HTMLCFG_NUMBERS_ENGLISH_US;
+ SetModified();
+}
diff --git a/svtools/source/config/itemholder2.cxx b/svtools/source/config/itemholder2.cxx
new file mode 100644
index 000000000000..8e971a1629bf
--- /dev/null
+++ b/svtools/source/config/itemholder2.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "itemholder2.hxx"
+
+//-----------------------------------------------
+// includes
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <svtools/accessibilityoptions.hxx>
+#include <apearcfg.hxx>
+#include <svtools/menuoptions.hxx>
+#include <svtools/colorcfg.hxx>
+#include <fontsubstconfig.hxx>
+#include <svtools/helpopt.hxx>
+#include <svtools/printoptions.hxx>
+#include <unotools/options.hxx>
+#include <svtools/miscopt.hxx>
+
+
+#include <tools/debug.hxx>
+
+//-----------------------------------------------
+// namespaces
+
+namespace css = ::com::sun::star;
+
+//-----------------------------------------------
+// declarations
+
+//-----------------------------------------------
+ItemHolder2::ItemHolder2()
+ : ItemHolderMutexBase()
+{
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+ css::uno::Reference< css::lang::XComponent > xCfg(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")),
+ css::uno::UNO_QUERY);
+ if (xCfg.is())
+ xCfg->addEventListener(static_cast< css::lang::XEventListener* >(this));
+ }
+// #i37892 got errorhandling from ConfigManager::GetConfigurationProvider()
+ catch(css::uno::RuntimeException& rREx)
+ {
+ throw rREx;
+ }
+#ifdef DBG_UTIL
+ catch(css::uno::Exception& rEx)
+ {
+ static sal_Bool bMessage = sal_True;
+ if(bMessage)
+ {
+ bMessage = sal_False;
+ ::rtl::OString sMsg("CreateInstance with arguments exception: ");
+ sMsg += ::rtl::OString(rEx.Message.getStr(),
+ rEx.Message.getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ DBG_ERROR(sMsg.getStr());
+ }
+ }
+#else
+ catch(css::uno::Exception&){}
+#endif
+}
+
+//-----------------------------------------------
+ItemHolder2::~ItemHolder2()
+{
+ impl_releaseAllItems();
+}
+
+//-----------------------------------------------
+void ItemHolder2::holdConfigItem(EItem eItem)
+{
+ static ItemHolder2* pHolder = new ItemHolder2();
+ pHolder->impl_addItem(eItem);
+}
+
+//-----------------------------------------------
+void SAL_CALL ItemHolder2::disposing(const css::lang::EventObject&)
+ throw(css::uno::RuntimeException)
+{
+ impl_releaseAllItems();
+}
+
+//-----------------------------------------------
+void ItemHolder2::impl_addItem(EItem eItem)
+{
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ TItems::const_iterator pIt;
+ for ( pIt = m_lItems.begin();
+ pIt != m_lItems.end() ;
+ ++pIt )
+ {
+ const TItemInfo& rInfo = *pIt;
+ if (rInfo.eItem == eItem)
+ return;
+ }
+
+ TItemInfo aNewItem;
+ aNewItem.eItem = eItem;
+ impl_newItem(aNewItem);
+ if (aNewItem.pItem)
+ m_lItems.push_back(aNewItem);
+}
+
+//-----------------------------------------------
+void ItemHolder2::impl_releaseAllItems()
+{
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ TItems::iterator pIt;
+ for ( pIt = m_lItems.begin();
+ pIt != m_lItems.end() ;
+ ++pIt )
+ {
+ TItemInfo& rInfo = *pIt;
+ impl_deleteItem(rInfo);
+ }
+ m_lItems.clear();
+}
+
+//-----------------------------------------------
+void ItemHolder2::impl_newItem(TItemInfo& rItem)
+{
+ switch(rItem.eItem)
+ {
+ case E_ACCESSIBILITYOPTIONS :
+ rItem.pItem = new SvtAccessibilityOptions();
+ break;
+
+ case E_APEARCFG :
+// no ref count rItem.pItem = new SvtTabAppearanceCfg();
+ break;
+
+ case E_COLORCFG :
+ rItem.pItem = new ::svtools::ColorConfig();
+ break;
+
+ case E_FONTSUBSTCONFIG :
+// no ref count rItem.pItem = new SvtFontSubstConfig();
+ break;
+
+ case E_HELPOPTIONS :
+ rItem.pItem = new SvtHelpOptions();
+ break;
+
+ case E_MENUOPTIONS :
+ rItem.pItem = new SvtMenuOptions();
+ break;
+
+ case E_PRINTOPTIONS :
+ rItem.pItem = new SvtPrinterOptions();
+ break;
+
+ case E_PRINTFILEOPTIONS :
+ rItem.pItem = new SvtPrintFileOptions();
+ break;
+
+ case E_MISCOPTIONS :
+ rItem.pItem = new SvtMiscOptions();
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+//-----------------------------------------------
+void ItemHolder2::impl_deleteItem(TItemInfo& rItem)
+{
+ if (rItem.pItem)
+ {
+ delete rItem.pItem;
+ rItem.pItem = 0;
+ }
+}
diff --git a/svtools/source/config/itemholder2.hxx b/svtools/source/config/itemholder2.hxx
new file mode 100644
index 000000000000..9314021b5750
--- /dev/null
+++ b/svtools/source/config/itemholder2.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 INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_
+#define INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_
+
+//-----------------------------------------------
+// includes
+
+#include <unotools/itemholderbase.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/lang/XEventListener.hpp>
+
+//-----------------------------------------------
+// namespaces
+
+#ifdef css
+#error "Cant use css as namespace alias."
+#else
+#define css ::com::sun::star
+#endif
+
+//-----------------------------------------------
+// definitions
+
+class ItemHolder2 : private ItemHolderMutexBase
+ , public ::cppu::WeakImplHelper1< css::lang::XEventListener >
+{
+ //...........................................
+ // member
+ private:
+
+ TItems m_lItems;
+
+ //...........................................
+ // c++ interface
+ public:
+
+ ItemHolder2();
+ virtual ~ItemHolder2();
+ static void holdConfigItem(EItem eItem);
+
+ //...........................................
+ // uno interface
+ public:
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //...........................................
+ // helper
+ private:
+
+ void impl_addItem(EItem eItem);
+ void impl_releaseAllItems();
+ void impl_newItem(TItemInfo& rItem);
+ void impl_deleteItem(TItemInfo& rItem);
+};
+
+//-----------------------------------------------
+// namespaces
+
+#undef css
+
+#endif // INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_
diff --git a/svtools/source/config/makefile.mk b/svtools/source/config/makefile.mk
new file mode 100644
index 000000000000..d3ba43de68ef
--- /dev/null
+++ b/svtools/source/config/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=svtools
+TARGET=config
+
+ENABLE_EXCEPTIONS := TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/accessibilityoptions.obj \
+ $(SLO)$/apearcfg.obj \
+ $(SLO)$/colorcfg.obj \
+ $(SLO)$/extcolorcfg.obj \
+ $(SLO)$/fontsubstconfig.obj \
+ $(SLO)$/helpopt.obj \
+ $(SLO)$/htmlcfg.obj \
+ $(SLO)$/itemholder2.obj \
+ $(SLO)$/menuoptions.obj \
+ $(SLO)$/miscopt.obj \
+ $(SLO)$/optionsdrawinglayer.obj \
+ $(SLO)$/printoptions.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/config/menuoptions.cxx b/svtools/source/config/menuoptions.cxx
new file mode 100644
index 000000000000..70d9d1623ef2
--- /dev/null
+++ b/svtools/source/config/menuoptions.cxx
@@ -0,0 +1,561 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#ifndef GCC
+#endif
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <svtools/menuoptions.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/logfile.hxx>
+#include "itemholder2.hxx"
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::utl ;
+using namespace ::rtl ;
+using namespace ::osl ;
+using namespace ::com::sun::star::uno ;
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define ROOTNODE_MENU OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/View/Menu" ))
+#define DEFAULT_DONTHIDEDISABLEDENTRIES sal_False
+#define DEFAULT_FOLLOWMOUSE sal_True
+#define DEFAULT_MENUICONS 2
+
+#define PROPERTYNAME_DONTHIDEDISABLEDENTRIES OUString(RTL_CONSTASCII_USTRINGPARAM("DontHideDisabledEntry" ))
+#define PROPERTYNAME_FOLLOWMOUSE OUString(RTL_CONSTASCII_USTRINGPARAM("FollowMouse" ))
+#define PROPERTYNAME_SHOWICONSINMENUES OUString(RTL_CONSTASCII_USTRINGPARAM("ShowIconsInMenues" ))
+#define PROPERTYNAME_SYSTEMICONSINMENUES OUString(RTL_CONSTASCII_USTRINGPARAM("IsSystemIconsInMenus" ))
+
+#define PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES 0
+#define PROPERTYHANDLE_FOLLOWMOUSE 1
+#define PROPERTYHANDLE_SHOWICONSINMENUES 2
+#define PROPERTYHANDLE_SYSTEMICONSINMENUES 3
+
+#define PROPERTYCOUNT 4
+
+#include <tools/link.hxx>
+#include <tools/list.hxx>
+DECLARE_LIST( LinkList, Link * )
+
+//_________________________________________________________________________________________________________________
+// private declarations!
+//_________________________________________________________________________________________________________________
+
+class SvtMenuOptions_Impl : public ConfigItem
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // private member
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+ LinkList aList;
+ sal_Bool m_bDontHideDisabledEntries ; /// cache "DontHideDisabledEntries" of Menu section
+ sal_Bool m_bFollowMouse ; /// cache "FollowMouse" of Menu section
+ sal_Int16 m_nMenuIcons ; /// cache "MenuIcons" of Menu section
+
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ public:
+
+ //---------------------------------------------------------------------------------------------------------
+ // constructor / destructor
+ //---------------------------------------------------------------------------------------------------------
+
+ SvtMenuOptions_Impl();
+ ~SvtMenuOptions_Impl();
+
+ void AddListenerLink( const Link& rLink );
+ void RemoveListenerLink( const Link& rLink );
+
+ //---------------------------------------------------------------------------------------------------------
+ // overloaded methods of baseclass
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short called for notify of configmanager
+ @descr These method is called from the ConfigManager before application ends or from the
+ PropertyChangeListener if the sub tree broadcasts changes. You must update your
+ internal values.
+
+ @seealso baseclass ConfigItem
+
+ @param "seqPropertyNames" is the list of properties which should be updated.
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Notify( const Sequence< OUString >& seqPropertyNames );
+
+ /*-****************************************************************************************************//**
+ @short write changes to configuration
+ @descr These method writes the changed values into the sub tree
+ and should always called in our destructor to guarantee consistency of config data.
+
+ @seealso baseclass ConfigItem
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Commit();
+
+ //---------------------------------------------------------------------------------------------------------
+ // public interface
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short access method to get internal values
+ @descr These method give us a chance to regulate acces to ouer internal values.
+ It's not used in the moment - but it's possible for the feature!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ sal_Bool IsEntryHidingEnabled() const
+ { return m_bDontHideDisabledEntries; }
+
+ sal_Bool IsFollowMouseEnabled() const
+ { return m_bFollowMouse; }
+
+ sal_Int16 GetMenuIconsState() const
+ { return m_nMenuIcons; }
+
+ void SetEntryHidingState ( sal_Bool bState )
+ {
+ m_bDontHideDisabledEntries = bState;
+ SetModified();
+ for ( USHORT n=0; n<aList.Count(); n++ )
+ aList.GetObject(n)->Call( this );
+ Commit();
+ }
+
+ void SetFollowMouseState ( sal_Bool bState )
+ {
+ m_bFollowMouse = bState;
+ SetModified();
+ for ( USHORT n=0; n<aList.Count(); n++ )
+ aList.GetObject(n)->Call( this );
+ Commit();
+ }
+
+ void SetMenuIconsState ( sal_Int16 bState )
+ {
+ m_nMenuIcons = bState;
+ SetModified();
+ for ( USHORT n=0; n<aList.Count(); n++ )
+ aList.GetObject(n)->Call( this );
+ Commit();
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+
+ /*-****************************************************************************************************//**
+ @short return list of fix key names of ouer configuration management which represent oue module tree
+ @descr These methods return a static const list of key names. We need it to get needed values from our
+ configuration management.
+
+ @seealso -
+
+ @param -
+ @return A list of needed configuration keys is returned.
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ static Sequence< OUString > impl_GetPropertyNames();
+};
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtMenuOptions_Impl::SvtMenuOptions_Impl()
+ // Init baseclasses first
+ : ConfigItem ( ROOTNODE_MENU )
+ // Init member then.
+ , m_bDontHideDisabledEntries ( DEFAULT_DONTHIDEDISABLEDENTRIES )
+ , m_bFollowMouse ( DEFAULT_FOLLOWMOUSE )
+ , m_nMenuIcons ( DEFAULT_MENUICONS )
+{
+ // Use our static list of configuration keys to get his values.
+ Sequence< OUString > seqNames = impl_GetPropertyNames();
+ Sequence< Any > seqValues = GetProperties( seqNames ) ;
+
+ // Safe impossible cases.
+ // We need values from ALL configuration keys.
+ // Follow assignment use order of values in relation to our list of key names!
+ DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
+
+ sal_Bool bMenuIcons = true;
+ sal_Bool bSystemMenuIcons = true;
+
+ // Copy values from list in right order to ouer internal member.
+ sal_Int32 nPropertyCount = seqValues.getLength() ;
+ sal_Int32 nProperty = 0 ;
+ for( nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ // Safe impossible cases.
+ // Check any for valid value.
+ DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nInvalid property value for property detected!\n" );
+ switch( nProperty )
+ {
+ case PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES : {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\DontHideDisabledEntry\"?" );
+ seqValues[nProperty] >>= m_bDontHideDisabledEntries;
+ }
+ break;
+
+ case PROPERTYHANDLE_FOLLOWMOUSE : {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\FollowMouse\"?" );
+ seqValues[nProperty] >>= m_bFollowMouse;
+ }
+ break;
+ case PROPERTYHANDLE_SHOWICONSINMENUES : {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\ShowIconsInMenues\"?" );
+ seqValues[nProperty] >>= bMenuIcons;
+ }
+ break;
+ case PROPERTYHANDLE_SYSTEMICONSINMENUES : {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\IsSystemIconsInMenus\"?" );
+ seqValues[nProperty] >>= bSystemMenuIcons;
+ }
+ break;
+ }
+ }
+
+ m_nMenuIcons = bSystemMenuIcons ? 2 : bMenuIcons;
+
+ EnableNotification( seqNames );
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtMenuOptions_Impl::~SvtMenuOptions_Impl()
+{
+ // Flush data to configuration!
+ // User has no chance to do that.
+ if( IsModified() == sal_True )
+ {
+ Commit();
+ }
+
+ for ( USHORT n=0; n<aList.Count(); )
+ delete aList.Remove(n);
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMenuOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames )
+{
+ // Use given list of updated properties to get his values from configuration directly!
+ Sequence< Any > seqValues = GetProperties( seqPropertyNames );
+ // Safe impossible cases.
+ // We need values from ALL notified configuration keys.
+ DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtMenuOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
+
+ sal_Bool bMenuIcons = true;
+ sal_Bool bSystemMenuIcons = true;
+
+ // Step over list of property names and get right value from coreesponding value list to set it on internal members!
+ sal_Int32 nCount = seqPropertyNames.getLength();
+ for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
+ {
+ if( seqPropertyNames[nProperty] == PROPERTYNAME_DONTHIDEDISABLEDENTRIES )
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\View\\Menu\\DontHideDisabledEntry\"?" );
+ seqValues[nProperty] >>= m_bDontHideDisabledEntries;
+ }
+ else if( seqPropertyNames[nProperty] == PROPERTYNAME_FOLLOWMOUSE )
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\View\\Menu\\FollowMouse\"?" );
+ seqValues[nProperty] >>= m_bFollowMouse;
+ }
+ else if( seqPropertyNames[nProperty] == PROPERTYNAME_SHOWICONSINMENUES )
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\ShowIconsInMenues\"?" );
+ seqValues[nProperty] >>= bMenuIcons;
+ }
+ else if( seqPropertyNames[nProperty] == PROPERTYNAME_SYSTEMICONSINMENUES )
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\IsSystemIconsInMenus\"?" );
+ seqValues[nProperty] >>= bSystemMenuIcons;
+ }
+
+ #if OSL_DEBUG_LEVEL > 1
+ else DBG_ASSERT( sal_False, "SvtMenuOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" );
+ #endif
+ }
+
+ m_nMenuIcons = bSystemMenuIcons ? 2 : bMenuIcons;
+
+ for ( USHORT n=0; n<aList.Count(); n++ )
+ aList.GetObject(n)->Call( this );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMenuOptions_Impl::Commit()
+{
+ // Get names of supported properties, create a list for values and copy current values to it.
+ Sequence< OUString > seqNames = impl_GetPropertyNames();
+ sal_Int32 nCount = seqNames.getLength();
+ Sequence< Any > seqValues ( nCount );
+ for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
+ {
+ switch( nProperty )
+ {
+ case PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES : {
+ seqValues[nProperty] <<= m_bDontHideDisabledEntries;
+ }
+ break;
+
+ case PROPERTYHANDLE_FOLLOWMOUSE : {
+ seqValues[nProperty] <<= m_bFollowMouse;
+ }
+ break;
+ //Output cache of current setting as possibly modified by System Theme for older version
+ case PROPERTYHANDLE_SHOWICONSINMENUES : {
+ seqValues[nProperty] <<=(sal_Bool)(Application::GetSettings().GetStyleSettings().GetUseImagesInMenus());
+ }
+ break;
+ case PROPERTYHANDLE_SYSTEMICONSINMENUES : {
+ seqValues[nProperty] <<= (m_nMenuIcons == 2 ? sal_True : sal_False) ;
+ }
+ break;
+ }
+ }
+ // Set properties in configuration.
+ PutProperties( seqNames, seqValues );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< OUString > SvtMenuOptions_Impl::impl_GetPropertyNames()
+{
+ // Build static list of configuration key names.
+ static const OUString pProperties[] =
+ {
+ PROPERTYNAME_DONTHIDEDISABLEDENTRIES ,
+ PROPERTYNAME_FOLLOWMOUSE ,
+ PROPERTYNAME_SHOWICONSINMENUES ,
+ PROPERTYNAME_SYSTEMICONSINMENUES
+ };
+ // Initialize return sequence with these list ...
+ static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
+ // ... and return it.
+ return seqPropertyNames;
+}
+
+void SvtMenuOptions_Impl::AddListenerLink( const Link& rLink )
+{
+ aList.Insert( new Link( rLink ) );
+}
+
+void SvtMenuOptions_Impl::RemoveListenerLink( const Link& rLink )
+{
+ for ( USHORT n=0; n<aList.Count(); n++ )
+ {
+ if ( (*aList.GetObject(n) ) == rLink )
+ {
+ delete aList.Remove(n);
+ break;
+ }
+ }
+}
+
+//*****************************************************************************************************************
+// initialize static member
+// DON'T DO IT IN YOUR HEADER!
+// see definition for further informations
+//*****************************************************************************************************************
+SvtMenuOptions_Impl* SvtMenuOptions::m_pDataContainer = NULL ;
+sal_Int32 SvtMenuOptions::m_nRefCount = 0 ;
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtMenuOptions::SvtMenuOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already!
+ if( m_pDataContainer == NULL )
+ {
+ RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtMenuOptions_Impl::ctor()");
+ m_pDataContainer = new SvtMenuOptions_Impl();
+
+ ItemHolder2::holdConfigItem(E_MENUOPTIONS);
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtMenuOptions::~SvtMenuOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pDataContainer;
+ m_pDataContainer = NULL;
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool SvtMenuOptions::IsEntryHidingEnabled() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsEntryHidingEnabled();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool SvtMenuOptions::IsFollowMouseEnabled() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsFollowMouseEnabled();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMenuOptions::SetEntryHidingState( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetEntryHidingState( bState );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMenuOptions::SetFollowMouseState( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetFollowMouseState( bState );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Int16 SvtMenuOptions::GetMenuIconsState() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMenuIconsState();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMenuOptions::SetMenuIconsState( sal_Int16 bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMenuIconsState( bState );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Mutex& SvtMenuOptions::GetOwnStaticMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+
+void SvtMenuOptions::AddListenerLink( const Link& rLink )
+{
+ m_pDataContainer->AddListenerLink( rLink );
+}
+
+void SvtMenuOptions::RemoveListenerLink( const Link& rLink )
+{
+ m_pDataContainer->RemoveListenerLink( rLink );
+}
diff --git a/svtools/source/config/miscopt.cxx b/svtools/source/config/miscopt.cxx
new file mode 100644
index 000000000000..7b04b56104e0
--- /dev/null
+++ b/svtools/source/config/miscopt.cxx
@@ -0,0 +1,831 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <svtools/miscopt.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/link.hxx>
+#include <tools/list.hxx>
+#include <tools/wldcrd.hxx>
+#include <tools/urlobj.hxx>
+
+#include <rtl/logfile.hxx>
+#include "itemholder2.hxx"
+
+#include <imgdef.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::utl ;
+using namespace ::rtl ;
+using namespace ::osl ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star;
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define ASCII_STR(s) OUString( RTL_CONSTASCII_USTRINGPARAM(s) )
+#define ROOTNODE_MISC ASCII_STR("Office.Common/Misc")
+#define DEFAULT_PLUGINSENABLED sal_True;
+
+#define PROPERTYNAME_PLUGINSENABLED ASCII_STR("PluginsEnabled")
+#define PROPERTYHANDLE_PLUGINSENABLED 0
+#define PROPERTYNAME_SYMBOLSET ASCII_STR("SymbolSet")
+#define PROPERTYHANDLE_SYMBOLSET 1
+#define PROPERTYNAME_TOOLBOXSTYLE ASCII_STR("ToolboxStyle")
+#define PROPERTYHANDLE_TOOLBOXSTYLE 2
+#define PROPERTYNAME_USESYSTEMFILEDIALOG ASCII_STR("UseSystemFileDialog")
+#define PROPERTYHANDLE_USESYSTEMFILEDIALOG 3
+#define PROPERTYNAME_SYMBOLSTYLE ASCII_STR("SymbolStyle")
+#define PROPERTYHANDLE_SYMBOLSTYLE 4
+#define PROPERTYNAME_USESYSTEMPRINTDIALOG ASCII_STR("UseSystemPrintDialog")
+#define PROPERTYHANDLE_USESYSTEMPRINTDIALOG 5
+
+#define PROPERTYCOUNT 6
+
+#define VCL_TOOLBOX_STYLE_FLAT ((USHORT)0x0004) // from <vcl/toolbox.hxx>
+
+DECLARE_LIST( LinkList, Link * )
+
+//_________________________________________________________________________________________________________________
+// private declarations!
+//_________________________________________________________________________________________________________________
+
+class SvtMiscOptions_Impl : public ConfigItem
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // private member
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+ LinkList aList;
+ sal_Bool m_bUseSystemFileDialog;
+ sal_Bool m_bIsUseSystemFileDialogRO;
+ sal_Bool m_bPluginsEnabled;
+ sal_Bool m_bIsPluginsEnabledRO;
+ sal_Int16 m_nSymbolsSize;
+ sal_Bool m_bIsSymbolsSizeRO;
+ sal_Bool m_bIsSymbolsStyleRO;
+ sal_Int16 m_nToolboxStyle;
+ sal_Bool m_bIsToolboxStyleRO;
+ sal_Bool m_bUseSystemPrintDialog;
+ sal_Bool m_bIsUseSystemPrintDialogRO;
+
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ public:
+
+ //---------------------------------------------------------------------------------------------------------
+ // constructor / destructor
+ //---------------------------------------------------------------------------------------------------------
+
+ SvtMiscOptions_Impl();
+ ~SvtMiscOptions_Impl();
+
+ //---------------------------------------------------------------------------------------------------------
+ // overloaded methods of baseclass
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short called for notify of configmanager
+ @descr These method is called from the ConfigManager before application ends or from the
+ PropertyChangeListener if the sub tree broadcasts changes. You must update your
+ internal values.
+
+ @seealso baseclass ConfigItem
+
+ @param "seqPropertyNames" is the list of properties which should be updated.
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Notify( const Sequence< OUString >& seqPropertyNames );
+
+ /** loads required data from the configuration. It's called in the constructor to
+ read all entries and form ::Notify to re-read changed settings
+
+ */
+ void Load( const Sequence< OUString >& rPropertyNames );
+
+ /*-****************************************************************************************************//**
+ @short write changes to configuration
+ @descr These method writes the changed values into the sub tree
+ and should always called in our destructor to guarantee consistency of config data.
+
+ @seealso baseclass ConfigItem
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Commit();
+
+ //---------------------------------------------------------------------------------------------------------
+ // public interface
+ //---------------------------------------------------------------------------------------------------------
+
+ inline sal_Bool UseSystemFileDialog() const
+ { return m_bUseSystemFileDialog; }
+
+ inline void SetUseSystemFileDialog( sal_Bool bSet )
+ { m_bUseSystemFileDialog = bSet; SetModified(); }
+
+ inline sal_Bool IsUseSystemFileDialogReadOnly() const
+ { return m_bIsUseSystemFileDialogRO; }
+
+ inline sal_Bool IsPluginsEnabled() const
+ { return m_bPluginsEnabled; }
+
+ void SetPluginsEnabled( sal_Bool bEnable );
+
+ inline sal_Bool IsPluginsEnabledReadOnly() const
+ { return m_bIsPluginsEnabledRO; }
+
+ inline sal_Int16 GetSymbolsSize()
+ { return m_nSymbolsSize; }
+
+ void SetSymbolsSize( sal_Int16 nSet );
+
+ inline sal_Bool IsGetSymbolsSizeReadOnly()
+ { return m_bIsSymbolsSizeRO; }
+
+ sal_Int16 GetSymbolsStyle() const;
+ ::rtl::OUString GetSymbolsStyleName() const;
+ sal_Int16 GetCurrentSymbolsStyle() const;
+
+ inline void SetSymbolsStyle( sal_Int16 nSet )
+ { ImplSetSymbolsStyle( true, nSet, ::rtl::OUString() ); }
+
+ inline void SetSymbolsStyleName( ::rtl::OUString &rName )
+ { ImplSetSymbolsStyle( false, 0, rName ); }
+
+ inline sal_Bool IsGetSymbolsStyleReadOnly()
+ { return m_bIsSymbolsStyleRO; }
+
+ // translate to VCL settings ( "0" = 3D, "1" = FLAT )
+ inline sal_Int16 GetToolboxStyle()
+ { return m_nToolboxStyle ? VCL_TOOLBOX_STYLE_FLAT : 0; }
+
+ // translate from VCL settings
+ void SetToolboxStyle( sal_Int16 nStyle, bool _bSetModified );
+
+ inline sal_Bool IsGetToolboxStyleReadOnly()
+ { return m_bIsToolboxStyleRO; }
+
+ inline sal_Bool UseSystemPrintDialog() const
+ { return m_bUseSystemPrintDialog; }
+
+ inline void SetUseSystemPrintDialog( sal_Bool bSet )
+ { m_bUseSystemPrintDialog = bSet; SetModified(); }
+
+ inline sal_Bool IsUseSystemPrintDialogReadOnly() const
+ { return m_bIsUseSystemPrintDialogRO; }
+
+ void AddListenerLink( const Link& rLink );
+ void RemoveListenerLink( const Link& rLink );
+ void CallListeners();
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+
+ /*-****************************************************************************************************//**
+ @short return list of key names of ouer configuration management which represent oue module tree
+ @descr These methods return a static const list of key names. We need it to get needed values from our
+ configuration management.
+
+ @seealso -
+
+ @param -
+ @return A list of needed configuration keys is returned.
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ static Sequence< OUString > GetPropertyNames();
+
+ protected:
+ void ImplSetSymbolsStyle( bool bValue, sal_Int16 nSet, const ::rtl::OUString &rName );
+};
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtMiscOptions_Impl::SvtMiscOptions_Impl()
+ // Init baseclasses first
+ : ConfigItem( ROOTNODE_MISC )
+
+ , m_bUseSystemFileDialog( sal_False )
+ , m_bIsUseSystemFileDialogRO( sal_False )
+ , m_bPluginsEnabled( sal_False )
+ , m_bIsPluginsEnabledRO( sal_False )
+ , m_nSymbolsSize( 0 )
+ , m_bIsSymbolsSizeRO( sal_False )
+ , m_bIsSymbolsStyleRO( sal_False )
+ , m_nToolboxStyle( 1 )
+ , m_bIsToolboxStyleRO( sal_False )
+ , m_bUseSystemPrintDialog( sal_False )
+ , m_bIsUseSystemPrintDialogRO( sal_False )
+
+{
+ // Use our static list of configuration keys to get his values.
+ Sequence< OUString > seqNames = GetPropertyNames ( );
+ Load( seqNames );
+ Sequence< Any > seqValues = GetProperties ( seqNames );
+ Sequence< sal_Bool > seqRO = GetReadOnlyStates ( seqNames );
+
+ // Safe impossible cases.
+ // We need values from ALL configuration keys.
+ // Follow assignment use order of values in relation to our list of key names!
+ DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtMiscOptions_Impl::SvtMiscOptions_Impl()\nI miss some values of configuration keys!\n" );
+
+ // Copy values from list in right order to ouer internal member.
+ sal_Int32 nPropertyCount = seqValues.getLength();
+ for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ // Safe impossible cases.
+ // Check any for valid value.
+ DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtSecurityOptions_Impl::SvtSecurityOptions_Impl()\nInvalid property value detected!\n" );
+ switch( nProperty )
+ {
+ case PROPERTYHANDLE_PLUGINSENABLED :
+ {
+ if( !(seqValues[nProperty] >>= m_bPluginsEnabled) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\PluginsEnabled\"!" );
+ }
+ m_bIsPluginsEnabledRO = seqRO[nProperty];
+ break;
+ }
+
+ case PROPERTYHANDLE_SYMBOLSET :
+ {
+ if( !(seqValues[nProperty] >>= m_nSymbolsSize) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\SymbolSet\"!" );
+ }
+ m_bIsSymbolsSizeRO = seqRO[nProperty];
+ break;
+ }
+
+ case PROPERTYHANDLE_TOOLBOXSTYLE :
+ {
+ if( !(seqValues[nProperty] >>= m_nToolboxStyle) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\ToolboxStyle\"!" );
+ }
+ m_bIsToolboxStyleRO = seqRO[nProperty];
+ break;
+ }
+
+ case PROPERTYHANDLE_USESYSTEMFILEDIALOG :
+ {
+ if( !(seqValues[nProperty] >>= m_bUseSystemFileDialog) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\UseSystemFileDialog\"!" );
+ }
+ m_bIsUseSystemFileDialogRO = seqRO[nProperty];
+ break;
+ }
+
+ case PROPERTYHANDLE_USESYSTEMPRINTDIALOG :
+ {
+ if( !(seqValues[nProperty] >>= m_bUseSystemPrintDialog) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\UseSystemPrintDialog\"!" );
+ }
+ m_bIsUseSystemPrintDialogRO = seqRO[nProperty];
+ break;
+ }
+
+ case PROPERTYHANDLE_SYMBOLSTYLE :
+ {
+ ::rtl::OUString aSymbolsStyle;
+ if( seqValues[nProperty] >>= aSymbolsStyle )
+ SetSymbolsStyleName( aSymbolsStyle );
+ else
+ {
+ DBG_ERROR("Wrong type of \"Misc\\SymbolStyle\"!" );
+ }
+ m_bIsSymbolsStyleRO = seqRO[nProperty];
+ break;
+ }
+ }
+ }
+
+ // Enable notification mechanism of ouer baseclass.
+ // We need it to get information about changes outside these class on ouer used configuration keys!
+ EnableNotification( seqNames );
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtMiscOptions_Impl::~SvtMiscOptions_Impl()
+{
+ // We must save our current values .. if user forget it!
+ if( IsModified() == sal_True )
+ {
+ Commit();
+ }
+
+ for ( USHORT n=0; n<aList.Count(); )
+ delete aList.Remove(n);
+}
+
+/*-- 25.02.2005 13:22:04---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+static int lcl_MapPropertyName( const ::rtl::OUString rCompare,
+ const uno::Sequence< ::rtl::OUString>& aInternalPropertyNames)
+{
+ for(int nProp = 0; nProp < aInternalPropertyNames.getLength(); ++nProp)
+ {
+ if( aInternalPropertyNames[nProp] == rCompare )
+ return nProp;
+ }
+ return -1;
+}
+
+void SvtMiscOptions_Impl::Load( const Sequence< OUString >& rPropertyNames )
+{
+ const uno::Sequence< ::rtl::OUString> aInternalPropertyNames( GetPropertyNames());
+ Sequence< Any > seqValues = GetProperties( rPropertyNames );
+
+ // Safe impossible cases.
+ // We need values from ALL configuration keys.
+ // Follow assignment use order of values in relation to our list of key names!
+ DBG_ASSERT( !(rPropertyNames.getLength()!=seqValues.getLength()), "SvtSecurityOptions_Impl::SvtSecurityOptions_Impl()\nI miss some values of configuration keys!\n" );
+
+ // Copy values from list in right order to ouer internal member.
+ sal_Int32 nPropertyCount = seqValues.getLength();
+ for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ // Safe impossible cases.
+ // Check any for valid value.
+ DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtSecurityOptions_Impl::SvtSecurityOptions_Impl()\nInvalid property value detected!\n" );
+ switch( lcl_MapPropertyName(rPropertyNames[nProperty], aInternalPropertyNames) )
+ {
+ case PROPERTYHANDLE_PLUGINSENABLED : {
+ if( !(seqValues[nProperty] >>= m_bPluginsEnabled) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\PluginsEnabled\"!" );
+ }
+ }
+ break;
+ case PROPERTYHANDLE_SYMBOLSET : {
+ if( !(seqValues[nProperty] >>= m_nSymbolsSize) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\SymbolSet\"!" );
+ }
+ }
+ break;
+ case PROPERTYHANDLE_TOOLBOXSTYLE : {
+ if( !(seqValues[nProperty] >>= m_nToolboxStyle) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\ToolboxStyle\"!" );
+ }
+ }
+ break;
+ case PROPERTYHANDLE_USESYSTEMFILEDIALOG : {
+ if( !(seqValues[nProperty] >>= m_bUseSystemFileDialog) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\UseSystemFileDialog\"!" );
+ }
+ }
+ break;
+ case PROPERTYHANDLE_USESYSTEMPRINTDIALOG : {
+ if( !(seqValues[nProperty] >>= m_bUseSystemPrintDialog) )
+ {
+ DBG_ERROR("Wrong type of \"Misc\\UseSystemPrintDialog\"!" );
+ }
+ }
+ break;
+ case PROPERTYHANDLE_SYMBOLSTYLE : {
+ ::rtl::OUString aSymbolsStyle;
+ if( seqValues[nProperty] >>= aSymbolsStyle )
+ SetSymbolsStyleName( aSymbolsStyle );
+ else
+ {
+ DBG_ERROR("Wrong type of \"Misc\\SymbolStyle\"!" );
+ }
+ }
+ break;
+ }
+ }
+}
+
+void SvtMiscOptions_Impl::AddListenerLink( const Link& rLink )
+{
+ aList.Insert( new Link( rLink ) );
+}
+
+void SvtMiscOptions_Impl::RemoveListenerLink( const Link& rLink )
+{
+ for ( USHORT n=0; n<aList.Count(); n++ )
+ {
+ if ( (*aList.GetObject(n) ) == rLink )
+ {
+ delete aList.Remove(n);
+ break;
+ }
+ }
+}
+
+void SvtMiscOptions_Impl::CallListeners()
+{
+ for ( USHORT n = 0; n < aList.Count(); ++n )
+ aList.GetObject(n)->Call( this );
+}
+
+void SvtMiscOptions_Impl::SetToolboxStyle( sal_Int16 nStyle, bool _bSetModified )
+{
+ m_nToolboxStyle = nStyle ? 1 : 0;
+ if ( _bSetModified )
+ SetModified();
+ CallListeners();
+}
+
+void SvtMiscOptions_Impl::SetSymbolsSize( sal_Int16 nSet )
+{
+ m_nSymbolsSize = nSet;
+ SetModified();
+ CallListeners();
+}
+
+sal_Int16 SvtMiscOptions_Impl::GetSymbolsStyle() const
+{
+ return (sal_Int16)Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+}
+
+::rtl::OUString SvtMiscOptions_Impl::GetSymbolsStyleName() const
+{
+ return Application::GetSettings().GetStyleSettings().GetSymbolsStyleName();
+}
+
+sal_Int16 SvtMiscOptions_Impl::GetCurrentSymbolsStyle() const
+{
+ return (sal_Int16)Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyle();
+}
+
+void SvtMiscOptions_Impl::ImplSetSymbolsStyle( bool bValue, sal_Int16 nSet, const ::rtl::OUString &rName )
+{
+ if ( ( bValue && ( nSet != GetSymbolsStyle() ) ) ||
+ ( !bValue && ( rName != GetSymbolsStyleName() ) ) )
+ {
+ AllSettings aAllSettings = Application::GetSettings();
+ StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
+
+ if ( bValue )
+ aStyleSettings.SetSymbolsStyle( nSet );
+ else
+ aStyleSettings.SetSymbolsStyleName( rName );
+
+ aAllSettings.SetStyleSettings(aStyleSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+
+ SetModified();
+ CallListeners();
+ }
+}
+
+void SvtMiscOptions_Impl::SetPluginsEnabled( sal_Bool bEnable )
+{
+ m_bPluginsEnabled = bEnable;
+ SetModified();
+ CallListeners();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMiscOptions_Impl::Notify( const Sequence< OUString >& rPropertyNames )
+{
+ Load( rPropertyNames );
+ CallListeners();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtMiscOptions_Impl::Commit()
+{
+ // Get names of supported properties, create a list for values and copy current values to it.
+ Sequence< OUString > seqNames = GetPropertyNames ();
+ sal_Int32 nCount = seqNames.getLength();
+ Sequence< Any > seqValues ( nCount );
+ for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
+ {
+ switch( nProperty )
+ {
+ case PROPERTYHANDLE_PLUGINSENABLED :
+ {
+ if ( !m_bIsPluginsEnabledRO )
+ seqValues[nProperty] <<= m_bPluginsEnabled;
+ break;
+ }
+
+ case PROPERTYHANDLE_SYMBOLSET :
+ {
+ if ( !m_bIsSymbolsSizeRO )
+ seqValues[nProperty] <<= m_nSymbolsSize;
+ break;
+ }
+
+ case PROPERTYHANDLE_TOOLBOXSTYLE :
+ {
+ if ( !m_bIsToolboxStyleRO )
+ seqValues[nProperty] <<= m_nToolboxStyle;
+ break;
+ }
+
+ case PROPERTYHANDLE_USESYSTEMFILEDIALOG :
+ {
+ if ( !m_bIsUseSystemFileDialogRO )
+ seqValues[nProperty] <<= m_bUseSystemFileDialog;
+ break;
+ }
+
+ case PROPERTYHANDLE_SYMBOLSTYLE :
+ {
+ if ( !m_bIsSymbolsStyleRO )
+ seqValues[nProperty] <<= GetSymbolsStyleName();
+ break;
+ }
+
+ case PROPERTYHANDLE_USESYSTEMPRINTDIALOG :
+ {
+ if ( !m_bIsUseSystemPrintDialogRO )
+ seqValues[nProperty] <<= m_bUseSystemPrintDialog;
+ break;
+ }
+ }
+ }
+ // Set properties in configuration.
+ PutProperties( seqNames, seqValues );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< OUString > SvtMiscOptions_Impl::GetPropertyNames()
+{
+ // Build static list of configuration key names.
+ static const OUString pProperties[] =
+ {
+ PROPERTYNAME_PLUGINSENABLED,
+ PROPERTYNAME_SYMBOLSET,
+ PROPERTYNAME_TOOLBOXSTYLE,
+ PROPERTYNAME_USESYSTEMFILEDIALOG,
+ PROPERTYNAME_SYMBOLSTYLE,
+ PROPERTYNAME_USESYSTEMPRINTDIALOG
+ };
+
+ // Initialize return sequence with these list ...
+ static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
+ // ... and return it.
+ return seqPropertyNames;
+}
+
+//*****************************************************************************************************************
+// initialize static member
+// DON'T DO IT IN YOUR HEADER!
+// see definition for further informations
+//*****************************************************************************************************************
+SvtMiscOptions_Impl* SvtMiscOptions::m_pDataContainer = NULL ;
+sal_Int32 SvtMiscOptions::m_nRefCount = 0 ;
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtMiscOptions::SvtMiscOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetInitMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already exist!
+ if( m_pDataContainer == NULL )
+ {
+ RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtMiscOptions_Impl::ctor()");
+ m_pDataContainer = new SvtMiscOptions_Impl;
+ ItemHolder2::holdConfigItem(E_MISCOPTIONS);
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtMiscOptions::~SvtMiscOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetInitMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pDataContainer;
+ m_pDataContainer = NULL;
+ }
+}
+
+sal_Bool SvtMiscOptions::UseSystemFileDialog() const
+{
+ return m_pDataContainer->UseSystemFileDialog();
+}
+
+void SvtMiscOptions::SetUseSystemFileDialog( sal_Bool bEnable )
+{
+ m_pDataContainer->SetUseSystemFileDialog( bEnable );
+}
+
+sal_Bool SvtMiscOptions::IsUseSystemFileDialogReadOnly() const
+{
+ return m_pDataContainer->IsUseSystemFileDialogReadOnly();
+}
+
+sal_Bool SvtMiscOptions::IsPluginsEnabled() const
+{
+ return m_pDataContainer->IsPluginsEnabled();
+}
+
+void SvtMiscOptions::SetPluginsEnabled( sal_Bool bEnable )
+{
+ m_pDataContainer->SetPluginsEnabled( bEnable );
+}
+
+sal_Bool SvtMiscOptions::IsPluginsEnabledReadOnly() const
+{
+ return m_pDataContainer->IsPluginsEnabledReadOnly();
+}
+
+sal_Int16 SvtMiscOptions::GetSymbolsSize() const
+{
+ return m_pDataContainer->GetSymbolsSize();
+}
+
+void SvtMiscOptions::SetSymbolsSize( sal_Int16 nSet )
+{
+ m_pDataContainer->SetSymbolsSize( nSet );
+}
+
+sal_Int16 SvtMiscOptions::GetCurrentSymbolsSize() const
+{
+ sal_Int16 eOptSymbolsSize = m_pDataContainer->GetSymbolsSize();
+
+ if ( eOptSymbolsSize == SFX_SYMBOLS_SIZE_AUTO )
+ {
+ // Use system settings, we have to retrieve the toolbar icon size from the
+ // Application class
+ ULONG nStyleIconSize = Application::GetSettings().GetStyleSettings().GetToolbarIconSize();
+ if ( nStyleIconSize == STYLE_TOOLBAR_ICONSIZE_LARGE )
+ eOptSymbolsSize = SFX_SYMBOLS_SIZE_LARGE;
+ else
+ eOptSymbolsSize = SFX_SYMBOLS_SIZE_SMALL;
+ }
+
+ return eOptSymbolsSize;
+}
+
+bool SvtMiscOptions::AreCurrentSymbolsLarge() const
+{
+ return ( GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE );
+}
+
+sal_Bool SvtMiscOptions::IsGetSymbolsSizeReadOnly() const
+{
+ return m_pDataContainer->IsGetSymbolsSizeReadOnly();
+}
+
+sal_Int16 SvtMiscOptions::GetSymbolsStyle() const
+{
+ return m_pDataContainer->GetSymbolsStyle();
+}
+
+sal_Int16 SvtMiscOptions::GetCurrentSymbolsStyle() const
+{
+ return m_pDataContainer->GetCurrentSymbolsStyle();
+}
+
+OUString SvtMiscOptions::GetCurrentSymbolsStyleName() const
+{
+ return Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+}
+
+void SvtMiscOptions::SetSymbolsStyle( sal_Int16 nSet )
+{
+ m_pDataContainer->SetSymbolsStyle( nSet );
+}
+
+sal_Bool SvtMiscOptions::IsGetSymbolsStyleReadOnly() const
+{
+ return m_pDataContainer->IsGetSymbolsStyleReadOnly();
+}
+
+sal_Int16 SvtMiscOptions::GetToolboxStyle() const
+{
+ return m_pDataContainer->GetToolboxStyle();
+}
+
+void SvtMiscOptions::SetToolboxStyle( sal_Int16 nStyle )
+{
+ m_pDataContainer->SetToolboxStyle( nStyle, true );
+}
+
+sal_Bool SvtMiscOptions::IsGetToolboxStyleReadOnly() const
+{
+ return m_pDataContainer->IsGetToolboxStyleReadOnly();
+}
+
+sal_Bool SvtMiscOptions::UseSystemPrintDialog() const
+{
+ return m_pDataContainer->UseSystemPrintDialog();
+}
+
+void SvtMiscOptions::SetUseSystemPrintDialog( sal_Bool bEnable )
+{
+ m_pDataContainer->SetUseSystemPrintDialog( bEnable );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Mutex & SvtMiscOptions::GetInitMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+
+void SvtMiscOptions::AddListenerLink( const Link& rLink )
+{
+ m_pDataContainer->AddListenerLink( rLink );
+}
+
+void SvtMiscOptions::RemoveListenerLink( const Link& rLink )
+{
+ m_pDataContainer->RemoveListenerLink( rLink );
+}
diff --git a/svtools/source/config/optionsdrawinglayer.cxx b/svtools/source/config/optionsdrawinglayer.cxx
new file mode 100644
index 000000000000..57cf1cd8ad5b
--- /dev/null
+++ b/svtools/source/config/optionsdrawinglayer.cxx
@@ -0,0 +1,1713 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <svtools/optionsdrawinglayer.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::utl ;
+using namespace ::rtl ;
+using namespace ::osl ;
+using namespace ::com::sun::star::uno ;
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Drawinglayer" ))
+#define DEFAULT_OVERLAYBUFFER sal_True
+#define DEFAULT_PAINTBUFFER sal_True
+#define DEFAULT_STRIPE_COLOR_A 0
+#define DEFAULT_STRIPE_COLOR_B 16581375
+#define DEFAULT_STRIPE_LENGTH 4
+
+// #i73602#
+// #i74769#, #i75172# : Change default for Calc and Writer to True
+#define DEFAULT_OVERLAYBUFFER_CALC sal_True
+#define DEFAULT_OVERLAYBUFFER_WRITER sal_True
+#define DEFAULT_OVERLAYBUFFER_DRAWIMPRESS sal_True
+
+// #i74769#, #i75172#
+#define DEFAULT_PAINTBUFFER_CALC sal_True
+#define DEFAULT_PAINTBUFFER_WRITER sal_True
+#define DEFAULT_PAINTBUFFER_DRAWIMPRESS sal_True
+
+// #i4219#
+#define DEFAULT_MAXIMUMPAPERWIDTH 300
+#define DEFAULT_MAXIMUMPAPERHEIGHT 300
+#define DEFAULT_MAXIMUMPAPERLEFTMARGIN 9999
+#define DEFAULT_MAXIMUMPAPERRIGHTMARGIN 9999
+#define DEFAULT_MAXIMUMPAPERTOPMARGIN 9999
+#define DEFAULT_MAXIMUMPAPERBOTTOMMARGIN 9999
+
+// primitives
+#define DEFAULT_ANTIALIASING sal_True
+#define DEFAULT_SNAPHORVERLINESTODISCRETE sal_True
+#define DEFAULT_SOLIDDRAGCREATE sal_True
+#define DEFAULT_RENDERDECORATEDTEXTDIRECT sal_True
+#define DEFAULT_RENDERSIMPLETEXTDIRECT sal_True
+#define DEFAULT_QUADRATIC3DRENDERLIMIT 1000000
+#define DEFAULT_QUADRATICFORMCONTROLRENDERLIMIT 45000
+
+// #i97672# selection settings
+#define DEFAULT_TRANSPARENTSELECTION sal_True
+#define DEFAULT_TRANSPARENTSELECTIONPERCENT 75
+#define DEFAULT_SELECTIONMAXIMUMLUMINANCEPERCENT 70
+
+#define PROPERTYNAME_OVERLAYBUFFER OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer" ))
+#define PROPERTYNAME_PAINTBUFFER OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer" ))
+#define PROPERTYNAME_STRIPE_COLOR_A OUString(RTL_CONSTASCII_USTRINGPARAM("StripeColorA" ))
+#define PROPERTYNAME_STRIPE_COLOR_B OUString(RTL_CONSTASCII_USTRINGPARAM("StripeColorB" ))
+#define PROPERTYNAME_STRIPE_LENGTH OUString(RTL_CONSTASCII_USTRINGPARAM("StripeLength" ))
+
+// #i73602#
+#define PROPERTYNAME_OVERLAYBUFFER_CALC OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer_Calc"))
+#define PROPERTYNAME_OVERLAYBUFFER_WRITER OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer_Writer"))
+#define PROPERTYNAME_OVERLAYBUFFER_DRAWIMPRESS OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer_DrawImpress"))
+
+// #i74769#, #i75172#
+#define PROPERTYNAME_PAINTBUFFER_CALC OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer_Calc"))
+#define PROPERTYNAME_PAINTBUFFER_WRITER OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer_Writer"))
+#define PROPERTYNAME_PAINTBUFFER_DRAWIMPRESS OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer_DrawImpress"))
+
+// #i4219#
+#define PROPERTYNAME_MAXIMUMPAPERWIDTH OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperWidth"))
+#define PROPERTYNAME_MAXIMUMPAPERHEIGHT OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperHeight"))
+#define PROPERTYNAME_MAXIMUMPAPERLEFTMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperLeftMargin"))
+#define PROPERTYNAME_MAXIMUMPAPERRIGHTMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperRightMargin"))
+#define PROPERTYNAME_MAXIMUMPAPERTOPMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperTopMargin"))
+#define PROPERTYNAME_MAXIMUMPAPERBOTTOMMARGIN OUString(RTL_CONSTASCII_USTRINGPARAM("MaximumPaperBottomMargin"))
+
+// primitives
+#define PROPERTYNAME_ANTIALIASING OUString(RTL_CONSTASCII_USTRINGPARAM("AntiAliasing"))
+#define PROPERTYNAME_SNAPHORVERLINESTODISCRETE OUString(RTL_CONSTASCII_USTRINGPARAM("SnapHorVerLinesToDiscrete"))
+#define PROPERTYNAME_SOLIDDRAGCREATE OUString(RTL_CONSTASCII_USTRINGPARAM("SolidDragCreate"))
+#define PROPERTYNAME_RENDERDECORATEDTEXTDIRECT OUString(RTL_CONSTASCII_USTRINGPARAM("RenderDecoratedTextDirect"))
+#define PROPERTYNAME_RENDERSIMPLETEXTDIRECT OUString(RTL_CONSTASCII_USTRINGPARAM("RenderSimpleTextDirect"))
+#define PROPERTYNAME_QUADRATIC3DRENDERLIMIT OUString(RTL_CONSTASCII_USTRINGPARAM("Quadratic3DRenderLimit"))
+#define PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT OUString(RTL_CONSTASCII_USTRINGPARAM("QuadraticFormControlRenderLimit"))
+
+// #i97672# selection settings
+#define PROPERTYNAME_TRANSPARENTSELECTION OUString(RTL_CONSTASCII_USTRINGPARAM("TransparentSelection"))
+#define PROPERTYNAME_TRANSPARENTSELECTIONPERCENT OUString(RTL_CONSTASCII_USTRINGPARAM("TransparentSelectionPercent"))
+#define PROPERTYNAME_SELECTIONMAXIMUMLUMINANCEPERCENT OUString(RTL_CONSTASCII_USTRINGPARAM("SelectionMaximumLuminancePercent"))
+
+#define PROPERTYHANDLE_OVERLAYBUFFER 0
+#define PROPERTYHANDLE_PAINTBUFFER 1
+#define PROPERTYHANDLE_STRIPE_COLOR_A 2
+#define PROPERTYHANDLE_STRIPE_COLOR_B 3
+#define PROPERTYHANDLE_STRIPE_LENGTH 4
+
+// #i73602#
+#define PROPERTYHANDLE_OVERLAYBUFFER_CALC 5
+#define PROPERTYHANDLE_OVERLAYBUFFER_WRITER 6
+#define PROPERTYHANDLE_OVERLAYBUFFER_DRAWIMPRESS 7
+
+// #i74769#, #i75172#
+#define PROPERTYHANDLE_PAINTBUFFER_CALC 8
+#define PROPERTYHANDLE_PAINTBUFFER_WRITER 9
+#define PROPERTYHANDLE_PAINTBUFFER_DRAWIMPRESS 10
+
+// #i4219#
+#define PROPERTYHANDLE_MAXIMUMPAPERWIDTH 11
+#define PROPERTYHANDLE_MAXIMUMPAPERHEIGHT 12
+#define PROPERTYHANDLE_MAXIMUMPAPERLEFTMARGIN 13
+#define PROPERTYHANDLE_MAXIMUMPAPERRIGHTMARGIN 14
+#define PROPERTYHANDLE_MAXIMUMPAPERTOPMARGIN 15
+#define PROPERTYHANDLE_MAXIMUMPAPERBOTTOMMARGIN 16
+
+// primitives
+#define PROPERTYHANDLE_ANTIALIASING 17
+#define PROPERTYHANDLE_SNAPHORVERLINESTODISCRETE 18
+#define PROPERTYHANDLE_SOLIDDRAGCREATE 19
+#define PROPERTYHANDLE_RENDERDECORATEDTEXTDIRECT 20
+#define PROPERTYHANDLE_RENDERSIMPLETEXTDIRECT 21
+#define PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT 22
+#define PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT 23
+
+// #i97672# selection settings
+#define PROPERTYHANDLE_TRANSPARENTSELECTION 24
+#define PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT 25
+#define PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT 26
+
+#define PROPERTYCOUNT 27
+
+class SvtOptionsDrawinglayer_Impl : public ConfigItem
+{
+public:
+
+//---------------------------------------------------------------------------------------------------------
+// constructor / destructor
+//---------------------------------------------------------------------------------------------------------
+
+ SvtOptionsDrawinglayer_Impl();
+ ~SvtOptionsDrawinglayer_Impl();
+
+//---------------------------------------------------------------------------------------------------------
+// overloaded methods of baseclass
+//---------------------------------------------------------------------------------------------------------
+
+ virtual void Commit();
+ virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames);
+
+//---------------------------------------------------------------------------------------------------------
+// public interface
+//---------------------------------------------------------------------------------------------------------
+
+ sal_Bool IsOverlayBuffer() const;
+ sal_Bool IsPaintBuffer() const;
+ Color GetStripeColorA() const;
+ Color GetStripeColorB() const;
+ sal_uInt16 GetStripeLength() const;
+
+ // #i73602#
+ sal_Bool IsOverlayBuffer_Calc() const;
+ sal_Bool IsOverlayBuffer_Writer() const;
+ sal_Bool IsOverlayBuffer_DrawImpress() const;
+
+ // #i74769#, #i75172#
+ sal_Bool IsPaintBuffer_Calc() const;
+ sal_Bool IsPaintBuffer_Writer() const;
+ sal_Bool IsPaintBuffer_DrawImpress() const;
+
+ void SetOverlayBuffer( sal_Bool bState );
+ void SetPaintBuffer( sal_Bool bState );
+ void SetStripeColorA( Color aColor );
+ void SetStripeColorB( Color aColor );
+ void SetStripeLength( sal_uInt16 nLength );
+
+ // #i73602#
+ void SetOverlayBuffer_Calc( sal_Bool bState );
+ void SetOverlayBuffer_Writer( sal_Bool bState );
+ void SetOverlayBuffer_DrawImpress( sal_Bool bState );
+
+ // #i74769#, #i75172#
+ void SetPaintBuffer_Calc( sal_Bool bState );
+ void SetPaintBuffer_Writer( sal_Bool bState );
+ void SetPaintBuffer_DrawImpress( sal_Bool bState );
+
+ // #i4219#
+ sal_uInt32 GetMaximumPaperWidth() const;
+ sal_uInt32 GetMaximumPaperHeight() const;
+ sal_uInt32 GetMaximumPaperLeftMargin() const;
+ sal_uInt32 GetMaximumPaperRightMargin() const;
+ sal_uInt32 GetMaximumPaperTopMargin() const;
+ sal_uInt32 GetMaximumPaperBottomMargin() const;
+
+ void SetMaximumPaperWidth(sal_uInt32 nNew);
+ void SetMaximumPaperHeight(sal_uInt32 nNew);
+ void SetMaximumPaperLeftMargin(sal_uInt32 nNew);
+ void SetMaximumPaperRightMargin(sal_uInt32 nNew);
+ void SetMaximumPaperTopMargin(sal_uInt32 nNew);
+ void SetMaximumPaperBottomMargin(sal_uInt32 nNew);
+
+ // helper
+ sal_Bool IsAAPossibleOnThisSystem() const;
+
+ // primitives
+ sal_Bool IsAntiAliasing() const;
+ sal_Bool IsSnapHorVerLinesToDiscrete() const;
+ sal_Bool IsSolidDragCreate() const;
+ sal_Bool IsRenderDecoratedTextDirect() const;
+ sal_Bool IsRenderSimpleTextDirect() const;
+ sal_uInt32 GetQuadratic3DRenderLimit() const;
+ sal_uInt32 GetQuadraticFormControlRenderLimit() const;
+
+ void SetAntiAliasing( sal_Bool bState );
+ void SetSnapHorVerLinesToDiscrete( sal_Bool bState );
+ void SetSolidDragCreate( sal_Bool bState );
+ void SetRenderDecoratedTextDirect( sal_Bool bState );
+ void SetRenderSimpleTextDirect( sal_Bool bState );
+ void SetQuadratic3DRenderLimit(sal_uInt32 nNew);
+ void SetQuadraticFormControlRenderLimit(sal_uInt32 nNew);
+
+ // #i97672# selection settings
+ sal_Bool IsTransparentSelection() const;
+ sal_uInt16 GetTransparentSelectionPercent() const;
+ sal_uInt16 GetSelectionMaximumLuminancePercent() const;
+
+ void SetTransparentSelection( sal_Bool bState );
+ void SetTransparentSelectionPercent( sal_uInt16 nPercent );
+ void SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent );
+
+//-------------------------------------------------------------------------------------------------------------
+// private methods
+//-------------------------------------------------------------------------------------------------------------
+
+private:
+
+ static Sequence< OUString > impl_GetPropertyNames();
+
+//-------------------------------------------------------------------------------------------------------------
+// private member
+//-------------------------------------------------------------------------------------------------------------
+
+private:
+
+ sal_Bool m_bOverlayBuffer;
+ sal_Bool m_bPaintBuffer;
+ Color m_bStripeColorA;
+ Color m_bStripeColorB;
+ sal_uInt16 m_nStripeLength;
+
+ // #i73602#
+ sal_Bool m_bOverlayBuffer_Calc;
+ sal_Bool m_bOverlayBuffer_Writer;
+ sal_Bool m_bOverlayBuffer_DrawImpress;
+
+ // #i74769#, #i75172#
+ sal_Bool m_bPaintBuffer_Calc;
+ sal_Bool m_bPaintBuffer_Writer;
+ sal_Bool m_bPaintBuffer_DrawImpress;
+
+ // #i4219#
+ sal_uInt32 m_nMaximumPaperWidth;
+ sal_uInt32 m_nMaximumPaperHeight;
+ sal_uInt32 m_nMaximumPaperLeftMargin;
+ sal_uInt32 m_nMaximumPaperRightMargin;
+ sal_uInt32 m_nMaximumPaperTopMargin;
+ sal_uInt32 m_nMaximumPaperBottomMargin;
+
+ // primitives
+ sal_Bool m_bAntiAliasing;
+ sal_Bool m_bSnapHorVerLinesToDiscrete;
+ sal_Bool m_bSolidDragCreate;
+ sal_Bool m_bRenderDecoratedTextDirect;
+ sal_Bool m_bRenderSimpleTextDirect;
+ sal_uInt32 m_nQuadratic3DRenderLimit;
+ sal_uInt32 m_nQuadraticFormControlRenderLimit;
+
+ // #i97672# selection settings
+ sal_uInt16 m_nTransparentSelectionPercent;
+ sal_uInt16 m_nSelectionMaximumLuminancePercent;
+ sal_Bool m_bTransparentSelection;
+
+ // local values
+ bool m_bAllowAA : 1;
+ bool m_bAllowAAChecked : 1;
+};
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl() :
+ ConfigItem( ROOTNODE_START ),
+ m_bOverlayBuffer( DEFAULT_OVERLAYBUFFER ),
+ m_bPaintBuffer( DEFAULT_PAINTBUFFER ),
+ m_bStripeColorA(Color(DEFAULT_STRIPE_COLOR_A)),
+ m_bStripeColorB(Color(DEFAULT_STRIPE_COLOR_B)),
+ m_nStripeLength(DEFAULT_STRIPE_LENGTH),
+
+ // #i73602#
+ m_bOverlayBuffer_Calc( DEFAULT_OVERLAYBUFFER_CALC ),
+ m_bOverlayBuffer_Writer( DEFAULT_OVERLAYBUFFER_WRITER ),
+ m_bOverlayBuffer_DrawImpress( DEFAULT_OVERLAYBUFFER_DRAWIMPRESS ),
+
+ // #i74769#, #i75172#
+ m_bPaintBuffer_Calc( DEFAULT_PAINTBUFFER_CALC ),
+ m_bPaintBuffer_Writer( DEFAULT_PAINTBUFFER_WRITER ),
+ m_bPaintBuffer_DrawImpress( DEFAULT_PAINTBUFFER_DRAWIMPRESS ),
+
+ // #i4219#
+ m_nMaximumPaperWidth(DEFAULT_MAXIMUMPAPERWIDTH),
+ m_nMaximumPaperHeight(DEFAULT_MAXIMUMPAPERHEIGHT),
+ m_nMaximumPaperLeftMargin(DEFAULT_MAXIMUMPAPERLEFTMARGIN),
+ m_nMaximumPaperRightMargin(DEFAULT_MAXIMUMPAPERRIGHTMARGIN),
+ m_nMaximumPaperTopMargin(DEFAULT_MAXIMUMPAPERTOPMARGIN),
+ m_nMaximumPaperBottomMargin(DEFAULT_MAXIMUMPAPERBOTTOMMARGIN),
+
+ // primitives
+ m_bAntiAliasing(DEFAULT_ANTIALIASING),
+ m_bSnapHorVerLinesToDiscrete(DEFAULT_SNAPHORVERLINESTODISCRETE),
+ m_bSolidDragCreate(DEFAULT_SOLIDDRAGCREATE),
+ m_bRenderDecoratedTextDirect(DEFAULT_RENDERDECORATEDTEXTDIRECT),
+ m_bRenderSimpleTextDirect(DEFAULT_RENDERSIMPLETEXTDIRECT),
+ m_nQuadratic3DRenderLimit(DEFAULT_QUADRATIC3DRENDERLIMIT),
+ m_nQuadraticFormControlRenderLimit(DEFAULT_QUADRATICFORMCONTROLRENDERLIMIT),
+
+ // #i97672# selection settings
+ m_nTransparentSelectionPercent(DEFAULT_TRANSPARENTSELECTIONPERCENT),
+ m_nSelectionMaximumLuminancePercent(DEFAULT_SELECTIONMAXIMUMLUMINANCEPERCENT),
+ m_bTransparentSelection(DEFAULT_TRANSPARENTSELECTION),
+
+ // local values
+ m_bAllowAA(true),
+ m_bAllowAAChecked(false)
+{
+ Sequence< OUString > seqNames( impl_GetPropertyNames() );
+ Sequence< Any > seqValues = GetProperties( seqNames ) ;
+
+ DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nI miss some values of configuration keys!\n" );
+
+ // Copy values from list in right order to ouer internal member.
+ sal_Int32 nPropertyCount = seqValues.getLength();
+ sal_Int32 nProperty = 0;
+
+ for( nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nInvalid property value for property detected!\n" );
+
+ switch( nProperty )
+ {
+ case PROPERTYHANDLE_OVERLAYBUFFER:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer\"?" );
+ seqValues[nProperty] >>= m_bOverlayBuffer;
+ }
+ break;
+
+ case PROPERTYHANDLE_PAINTBUFFER:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer\"?" );
+ seqValues[nProperty] >>= m_bPaintBuffer;
+ }
+ break;
+
+ case PROPERTYHANDLE_STRIPE_COLOR_A:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\StripeColorA\"?" );
+ sal_Int32 nValue = 0;
+ seqValues[nProperty] >>= nValue;
+ m_bStripeColorA = nValue;
+ }
+ break;
+
+ case PROPERTYHANDLE_STRIPE_COLOR_B:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\StripeColorB\"?" );
+ sal_Int32 nValue = 0;
+ seqValues[nProperty] >>= nValue;
+ m_bStripeColorB = nValue;
+ }
+ break;
+
+ case PROPERTYHANDLE_STRIPE_LENGTH:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\StripeLength\"?" );
+ seqValues[nProperty] >>= m_nStripeLength;
+ }
+ break;
+
+ // #i73602#
+ case PROPERTYHANDLE_OVERLAYBUFFER_CALC:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer_Calc\"?" );
+ seqValues[nProperty] >>= m_bOverlayBuffer_Calc;
+ }
+ break;
+
+ case PROPERTYHANDLE_OVERLAYBUFFER_WRITER:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer_Writer\"?" );
+ seqValues[nProperty] >>= m_bOverlayBuffer_Writer;
+ }
+ break;
+
+ case PROPERTYHANDLE_OVERLAYBUFFER_DRAWIMPRESS:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\OverlayBuffer_DrawImpress\"?" );
+ seqValues[nProperty] >>= m_bOverlayBuffer_DrawImpress;
+ }
+ break;
+
+ // #i74769#, #i75172#
+ case PROPERTYHANDLE_PAINTBUFFER_CALC:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer_Calc\"?" );
+ seqValues[nProperty] >>= m_bPaintBuffer_Calc;
+ }
+ break;
+
+ case PROPERTYHANDLE_PAINTBUFFER_WRITER:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer_Writer\"?" );
+ seqValues[nProperty] >>= m_bPaintBuffer_Writer;
+ }
+ break;
+
+ case PROPERTYHANDLE_PAINTBUFFER_DRAWIMPRESS:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\PaintBuffer_DrawImpress\"?" );
+ seqValues[nProperty] >>= m_bPaintBuffer_DrawImpress;
+ }
+ break;
+
+ // #i4219#
+ case PROPERTYHANDLE_MAXIMUMPAPERWIDTH:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperWidth\"?" );
+ seqValues[nProperty] >>= m_nMaximumPaperWidth;
+ }
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERHEIGHT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperHeight\"?" );
+ seqValues[nProperty] >>= m_nMaximumPaperHeight;
+ }
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERLEFTMARGIN:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperLeftMargin\"?" );
+ seqValues[nProperty] >>= m_nMaximumPaperLeftMargin;
+ }
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERRIGHTMARGIN:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperRightMargin\"?" );
+ seqValues[nProperty] >>= m_nMaximumPaperRightMargin;
+ }
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERTOPMARGIN:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperTopMargin\"?" );
+ seqValues[nProperty] >>= m_nMaximumPaperTopMargin;
+ }
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERBOTTOMMARGIN:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\MaximumPaperBottomMargin\"?" );
+ seqValues[nProperty] >>= m_nMaximumPaperBottomMargin;
+ }
+ break;
+
+ // primitives
+ case PROPERTYHANDLE_ANTIALIASING:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\AntiAliasing\"?" );
+ seqValues[nProperty] >>= m_bAntiAliasing;
+ }
+ break;
+
+ // primitives
+ case PROPERTYHANDLE_SNAPHORVERLINESTODISCRETE:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SnapHorVerLinesToDiscrete\"?" );
+ seqValues[nProperty] >>= m_bSnapHorVerLinesToDiscrete;
+ }
+ break;
+
+ case PROPERTYHANDLE_SOLIDDRAGCREATE:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SolidDragCreate\"?" );
+ seqValues[nProperty] >>= m_bSolidDragCreate;
+ }
+ break;
+
+ case PROPERTYHANDLE_RENDERDECORATEDTEXTDIRECT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\RenderDecoratedTextDirect\"?" );
+ seqValues[nProperty] >>= m_bRenderDecoratedTextDirect;
+ }
+ break;
+
+ case PROPERTYHANDLE_RENDERSIMPLETEXTDIRECT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\RenderSimpleTextDirect\"?" );
+ seqValues[nProperty] >>= m_bRenderSimpleTextDirect;
+ }
+ break;
+
+ case PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\Quadratic3DRenderLimit\"?" );
+ seqValues[nProperty] >>= m_nQuadratic3DRenderLimit;
+ }
+ break;
+
+ case PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\QuadraticFormControlRenderLimit\"?" );
+ seqValues[nProperty] >>= m_nQuadraticFormControlRenderLimit;
+ }
+ break;
+
+ // #i97672# selection settings
+ case PROPERTYHANDLE_TRANSPARENTSELECTION:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\TransparentSelection\"?" );
+ seqValues[nProperty] >>= m_bTransparentSelection;
+ }
+ break;
+
+ case PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\TransparentSelectionPercent\"?" );
+ seqValues[nProperty] >>= m_nTransparentSelectionPercent;
+ }
+
+ case PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT:
+ {
+ DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SelectionMaximumLuminancePercent\"?" );
+ seqValues[nProperty] >>= m_nSelectionMaximumLuminancePercent;
+ }
+ break;
+ }
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtOptionsDrawinglayer_Impl::~SvtOptionsDrawinglayer_Impl()
+{
+ if( IsModified() )
+ Commit();
+}
+
+//*****************************************************************************************************************
+// Commit
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer_Impl::Commit()
+{
+ Sequence< OUString > aSeqNames( impl_GetPropertyNames() );
+ Sequence< Any > aSeqValues( aSeqNames.getLength() );
+
+ for( sal_Int32 nProperty = 0, nCount = aSeqNames.getLength(); nProperty < nCount; ++nProperty )
+ {
+ switch( nProperty )
+ {
+ case PROPERTYHANDLE_OVERLAYBUFFER:
+ aSeqValues[nProperty] <<= m_bOverlayBuffer;
+ break;
+
+ case PROPERTYHANDLE_PAINTBUFFER:
+ aSeqValues[nProperty] <<= m_bPaintBuffer;
+ break;
+
+ case PROPERTYHANDLE_STRIPE_COLOR_A:
+ aSeqValues[nProperty] <<= m_bStripeColorA.GetColor();
+ break;
+
+ case PROPERTYHANDLE_STRIPE_COLOR_B:
+ aSeqValues[nProperty] <<= m_bStripeColorB.GetColor();
+ break;
+
+ case PROPERTYHANDLE_STRIPE_LENGTH:
+ aSeqValues[nProperty] <<= m_nStripeLength;
+ break;
+
+ // #i73602#
+ case PROPERTYHANDLE_OVERLAYBUFFER_CALC:
+ aSeqValues[nProperty] <<= m_bOverlayBuffer_Calc;
+ break;
+
+ case PROPERTYHANDLE_OVERLAYBUFFER_WRITER:
+ aSeqValues[nProperty] <<= m_bOverlayBuffer_Writer;
+ break;
+
+ case PROPERTYHANDLE_OVERLAYBUFFER_DRAWIMPRESS:
+ aSeqValues[nProperty] <<= m_bOverlayBuffer_DrawImpress;
+ break;
+
+ // #i74769#, #i75172#
+ case PROPERTYHANDLE_PAINTBUFFER_CALC:
+ aSeqValues[nProperty] <<= m_bPaintBuffer_Calc;
+ break;
+
+ case PROPERTYHANDLE_PAINTBUFFER_WRITER:
+ aSeqValues[nProperty] <<= m_bPaintBuffer_Writer;
+ break;
+
+ case PROPERTYHANDLE_PAINTBUFFER_DRAWIMPRESS:
+ aSeqValues[nProperty] <<= m_bPaintBuffer_DrawImpress;
+ break;
+
+ // #i4219#
+ case PROPERTYHANDLE_MAXIMUMPAPERWIDTH:
+ aSeqValues[nProperty] <<= m_nMaximumPaperWidth;
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERHEIGHT:
+ aSeqValues[nProperty] <<= m_nMaximumPaperHeight;
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERLEFTMARGIN:
+ aSeqValues[nProperty] <<= m_nMaximumPaperLeftMargin;
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERRIGHTMARGIN:
+ aSeqValues[nProperty] <<= m_nMaximumPaperRightMargin;
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERTOPMARGIN:
+ aSeqValues[nProperty] <<= m_nMaximumPaperTopMargin;
+ break;
+
+ case PROPERTYHANDLE_MAXIMUMPAPERBOTTOMMARGIN:
+ aSeqValues[nProperty] <<= m_nMaximumPaperBottomMargin;
+ break;
+
+ // primitives
+ case PROPERTYHANDLE_ANTIALIASING:
+ aSeqValues[nProperty] <<= m_bAntiAliasing;
+ break;
+
+ case PROPERTYHANDLE_SNAPHORVERLINESTODISCRETE:
+ aSeqValues[nProperty] <<= m_bSnapHorVerLinesToDiscrete;
+ break;
+
+ case PROPERTYHANDLE_SOLIDDRAGCREATE:
+ aSeqValues[nProperty] <<= m_bSolidDragCreate;
+ break;
+
+ case PROPERTYHANDLE_RENDERDECORATEDTEXTDIRECT:
+ aSeqValues[nProperty] <<= m_bRenderDecoratedTextDirect;
+ break;
+
+ case PROPERTYHANDLE_RENDERSIMPLETEXTDIRECT:
+ aSeqValues[nProperty] <<= m_bRenderSimpleTextDirect;
+ break;
+
+ case PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT:
+ aSeqValues[nProperty] <<= m_nQuadratic3DRenderLimit;
+ break;
+
+ case PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT:
+ aSeqValues[nProperty] <<= m_nQuadraticFormControlRenderLimit;
+ break;
+
+ // #i97672# selection settings
+ case PROPERTYHANDLE_TRANSPARENTSELECTION:
+ aSeqValues[nProperty] <<= m_bTransparentSelection;
+ break;
+
+ case PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT:
+ aSeqValues[nProperty] <<= m_nTransparentSelectionPercent;
+ break;
+
+ case PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT:
+ aSeqValues[nProperty] <<= m_nSelectionMaximumLuminancePercent;
+ break;
+ }
+ }
+
+ PutProperties( aSeqNames, aSeqValues );
+}
+
+void SvtOptionsDrawinglayer_Impl::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& )
+{
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer() const
+{
+ return m_bOverlayBuffer;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer() const
+{
+ return m_bPaintBuffer;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Color SvtOptionsDrawinglayer_Impl::GetStripeColorA() const
+{
+ return m_bStripeColorA;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Color SvtOptionsDrawinglayer_Impl::GetStripeColorB() const
+{
+ return m_bStripeColorB;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_uInt16 SvtOptionsDrawinglayer_Impl::GetStripeLength() const
+{
+ return m_nStripeLength;
+}
+
+// #i73602#
+sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer_Calc() const
+{
+ return m_bOverlayBuffer_Calc;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer_Writer() const
+{
+ return m_bOverlayBuffer_Writer;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsOverlayBuffer_DrawImpress() const
+{
+ return m_bOverlayBuffer_DrawImpress;
+}
+
+// #i74769#, #i75172#
+sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer_Calc() const
+{
+ return m_bPaintBuffer_Calc;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer_Writer() const
+{
+ return m_bPaintBuffer_Writer;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsPaintBuffer_DrawImpress() const
+{
+ return m_bPaintBuffer_DrawImpress;
+}
+
+// #i4219#
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperWidth() const
+{
+ return m_nMaximumPaperWidth;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperHeight() const
+{
+ return m_nMaximumPaperHeight;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperLeftMargin() const
+{
+ return m_nMaximumPaperLeftMargin;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperRightMargin() const
+{
+ return m_nMaximumPaperRightMargin;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperTopMargin() const
+{
+ return m_nMaximumPaperTopMargin;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetMaximumPaperBottomMargin() const
+{
+ return m_nMaximumPaperBottomMargin;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer( sal_Bool bState )
+{
+ if(m_bOverlayBuffer != bState)
+ {
+ m_bOverlayBuffer = bState;
+ SetModified();
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer_Impl::SetPaintBuffer( sal_Bool bState )
+{
+ if(m_bPaintBuffer != bState)
+ {
+ m_bPaintBuffer = bState;
+ SetModified();
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer_Impl::SetStripeColorA( Color aColor )
+{
+ if(m_bStripeColorA != aColor)
+ {
+ m_bStripeColorA = aColor;
+ SetModified();
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer_Impl::SetStripeColorB( Color aColor )
+{
+ if(m_bStripeColorB != aColor)
+ {
+ m_bStripeColorB = aColor;
+ SetModified();
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer_Impl::SetStripeLength( sal_uInt16 nLength )
+{
+ if(m_nStripeLength != nLength)
+ {
+ m_nStripeLength = nLength;
+ SetModified();
+ }
+}
+
+// #i73602#
+void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer_Calc( sal_Bool bState )
+{
+ if(m_bOverlayBuffer_Calc != bState)
+ {
+ m_bOverlayBuffer_Calc = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer_Writer( sal_Bool bState )
+{
+ if(m_bOverlayBuffer_Writer != bState)
+ {
+ m_bOverlayBuffer_Writer = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetOverlayBuffer_DrawImpress( sal_Bool bState )
+{
+ if(m_bOverlayBuffer_DrawImpress != bState)
+ {
+ m_bOverlayBuffer_DrawImpress = bState;
+ SetModified();
+ }
+}
+
+// #i74769#, #i75172#
+void SvtOptionsDrawinglayer_Impl::SetPaintBuffer_Calc( sal_Bool bState )
+{
+ if(m_bPaintBuffer_Calc != bState)
+ {
+ m_bPaintBuffer_Calc = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetPaintBuffer_Writer( sal_Bool bState )
+{
+ if(m_bPaintBuffer_Writer != bState)
+ {
+ m_bPaintBuffer_Writer = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetPaintBuffer_DrawImpress( sal_Bool bState )
+{
+ if(m_bPaintBuffer_DrawImpress != bState)
+ {
+ m_bPaintBuffer_DrawImpress = bState;
+ SetModified();
+ }
+}
+
+// #i4219#
+void SvtOptionsDrawinglayer_Impl::SetMaximumPaperWidth( sal_uInt32 nNew )
+{
+ if(m_nMaximumPaperWidth != nNew)
+ {
+ m_nMaximumPaperWidth = nNew;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetMaximumPaperHeight( sal_uInt32 nNew )
+{
+ if(m_nMaximumPaperHeight != nNew)
+ {
+ m_nMaximumPaperHeight = nNew;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetMaximumPaperLeftMargin( sal_uInt32 nNew )
+{
+ if(m_nMaximumPaperLeftMargin != nNew)
+ {
+ m_nMaximumPaperLeftMargin = nNew;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetMaximumPaperRightMargin( sal_uInt32 nNew )
+{
+ if(m_nMaximumPaperRightMargin != nNew)
+ {
+ m_nMaximumPaperRightMargin = nNew;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetMaximumPaperTopMargin( sal_uInt32 nNew )
+{
+ if(m_nMaximumPaperTopMargin != nNew)
+ {
+ m_nMaximumPaperTopMargin = nNew;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetMaximumPaperBottomMargin( sal_uInt32 nNew )
+{
+ if(m_nMaximumPaperBottomMargin != nNew)
+ {
+ m_nMaximumPaperBottomMargin = nNew;
+ SetModified();
+ }
+}
+
+// helper
+sal_Bool SvtOptionsDrawinglayer_Impl::IsAAPossibleOnThisSystem() const
+{
+ if(!m_bAllowAAChecked)
+ {
+ SvtOptionsDrawinglayer_Impl* pThat = const_cast< SvtOptionsDrawinglayer_Impl* >(this);
+ pThat->m_bAllowAAChecked = true;
+
+#ifdef WIN32
+ // WIN32 uses GDIPlus with VCL forthe first incarnation; this will be enhanced
+ // in the future to use canvases and the canvas renderer, thus a AA-abled
+ // canvas needs to be checked here in the future.
+ // Currently, just allow AA for WIN32
+#endif
+
+ // check XRenderExtension
+ if(m_bAllowAA && !Application::GetDefaultDevice()->supportsOperation( OutDevSupport_TransparentRect ))
+ {
+ pThat->m_bAllowAA = false;
+ }
+ }
+
+ return m_bAllowAA;
+}
+
+// primitives
+sal_Bool SvtOptionsDrawinglayer_Impl::IsAntiAliasing() const
+{
+ return m_bAntiAliasing;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsSnapHorVerLinesToDiscrete() const
+{
+ return m_bSnapHorVerLinesToDiscrete;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsSolidDragCreate() const
+{
+ return m_bSolidDragCreate;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsRenderDecoratedTextDirect() const
+{
+ return m_bRenderDecoratedTextDirect;
+}
+
+sal_Bool SvtOptionsDrawinglayer_Impl::IsRenderSimpleTextDirect() const
+{
+ return m_bRenderSimpleTextDirect;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetQuadratic3DRenderLimit() const
+{
+ return m_nQuadratic3DRenderLimit;
+}
+
+sal_uInt32 SvtOptionsDrawinglayer_Impl::GetQuadraticFormControlRenderLimit() const
+{
+ return m_nQuadraticFormControlRenderLimit;
+}
+
+void SvtOptionsDrawinglayer_Impl::SetAntiAliasing( sal_Bool bState )
+{
+ if(m_bAntiAliasing != bState)
+ {
+ m_bAntiAliasing = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetSnapHorVerLinesToDiscrete( sal_Bool bState )
+{
+ if(m_bSnapHorVerLinesToDiscrete != bState)
+ {
+ m_bSnapHorVerLinesToDiscrete = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetSolidDragCreate( sal_Bool bState )
+{
+ if(m_bSolidDragCreate != bState)
+ {
+ m_bSolidDragCreate = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetRenderDecoratedTextDirect( sal_Bool bState )
+{
+ if(m_bRenderDecoratedTextDirect != bState)
+ {
+ m_bRenderDecoratedTextDirect = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetRenderSimpleTextDirect( sal_Bool bState )
+{
+ if(m_bRenderSimpleTextDirect != bState)
+ {
+ m_bRenderSimpleTextDirect = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetQuadratic3DRenderLimit(sal_uInt32 nNew)
+{
+ if(m_nQuadratic3DRenderLimit != nNew)
+ {
+ m_nQuadratic3DRenderLimit = nNew;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetQuadraticFormControlRenderLimit(sal_uInt32 nNew)
+{
+ if(m_nQuadraticFormControlRenderLimit != nNew)
+ {
+ m_nQuadraticFormControlRenderLimit = nNew;
+ SetModified();
+ }
+}
+
+// #i97672# selection settings
+sal_Bool SvtOptionsDrawinglayer_Impl::IsTransparentSelection() const
+{
+ return m_bTransparentSelection;
+}
+
+void SvtOptionsDrawinglayer_Impl::SetTransparentSelection( sal_Bool bState )
+{
+ if(m_bTransparentSelection != bState)
+ {
+ m_bTransparentSelection = bState;
+ SetModified();
+ }
+}
+
+void SvtOptionsDrawinglayer_Impl::SetTransparentSelectionPercent( sal_uInt16 nPercent )
+{
+ if(m_nTransparentSelectionPercent != nPercent)
+ {
+ m_nTransparentSelectionPercent = nPercent;
+ SetModified();
+ }
+}
+
+sal_uInt16 SvtOptionsDrawinglayer_Impl::GetTransparentSelectionPercent() const
+{
+ return m_nTransparentSelectionPercent;
+}
+
+void SvtOptionsDrawinglayer_Impl::SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent )
+{
+ if(m_nSelectionMaximumLuminancePercent != nPercent)
+ {
+ m_nSelectionMaximumLuminancePercent = nPercent;
+ SetModified();
+ }
+}
+
+sal_uInt16 SvtOptionsDrawinglayer_Impl::GetSelectionMaximumLuminancePercent() const
+{
+ return m_nSelectionMaximumLuminancePercent;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< OUString > SvtOptionsDrawinglayer_Impl::impl_GetPropertyNames()
+{
+ // Build static list of configuration key names.
+ static const OUString pProperties[] =
+ {
+ PROPERTYNAME_OVERLAYBUFFER ,
+ PROPERTYNAME_PAINTBUFFER ,
+ PROPERTYNAME_STRIPE_COLOR_A ,
+ PROPERTYNAME_STRIPE_COLOR_B ,
+ PROPERTYNAME_STRIPE_LENGTH ,
+
+ // #i73602#
+ PROPERTYNAME_OVERLAYBUFFER_CALC,
+ PROPERTYNAME_OVERLAYBUFFER_WRITER,
+ PROPERTYNAME_OVERLAYBUFFER_DRAWIMPRESS,
+
+ // #i74769#, #i75172#
+ PROPERTYNAME_PAINTBUFFER_CALC,
+ PROPERTYNAME_PAINTBUFFER_WRITER,
+ PROPERTYNAME_PAINTBUFFER_DRAWIMPRESS,
+
+ // #i4219#
+ PROPERTYNAME_MAXIMUMPAPERWIDTH,
+ PROPERTYNAME_MAXIMUMPAPERHEIGHT,
+ PROPERTYNAME_MAXIMUMPAPERLEFTMARGIN,
+ PROPERTYNAME_MAXIMUMPAPERRIGHTMARGIN,
+ PROPERTYNAME_MAXIMUMPAPERTOPMARGIN,
+ PROPERTYNAME_MAXIMUMPAPERBOTTOMMARGIN,
+
+ // primitives
+ PROPERTYNAME_ANTIALIASING,
+ PROPERTYNAME_SNAPHORVERLINESTODISCRETE,
+ PROPERTYNAME_SOLIDDRAGCREATE,
+ PROPERTYNAME_RENDERDECORATEDTEXTDIRECT,
+ PROPERTYNAME_RENDERSIMPLETEXTDIRECT,
+ PROPERTYNAME_QUADRATIC3DRENDERLIMIT,
+ PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT,
+
+ // #i97672# selection settings
+ PROPERTYNAME_TRANSPARENTSELECTION,
+ PROPERTYNAME_TRANSPARENTSELECTIONPERCENT,
+ PROPERTYNAME_SELECTIONMAXIMUMLUMINANCEPERCENT
+ };
+
+ // Initialize return sequence with these list ...
+ static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
+ // ... and return it.
+ return seqPropertyNames;
+}
+
+//*****************************************************************************************************************
+// initialize static member
+// DON'T DO IT IN YOUR HEADER!
+// see definition for further informations
+//*****************************************************************************************************************
+SvtOptionsDrawinglayer_Impl* SvtOptionsDrawinglayer::m_pDataContainer = NULL;
+sal_Int32 SvtOptionsDrawinglayer::m_nRefCount = 0;
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtOptionsDrawinglayer::SvtOptionsDrawinglayer()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already!
+ if( m_pDataContainer == NULL )
+ {
+ m_pDataContainer = new SvtOptionsDrawinglayer_Impl();
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtOptionsDrawinglayer::~SvtOptionsDrawinglayer()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pDataContainer;
+ m_pDataContainer = NULL;
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsOverlayBuffer();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsPaintBuffer();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Color SvtOptionsDrawinglayer::GetStripeColorA() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetStripeColorA();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Color SvtOptionsDrawinglayer::GetStripeColorB() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetStripeColorB();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_uInt16 SvtOptionsDrawinglayer::GetStripeLength() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetStripeLength();
+}
+
+// #i73602#
+sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer_Calc() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsOverlayBuffer_Calc();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer_Writer() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsOverlayBuffer_Writer();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsOverlayBuffer_DrawImpress() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsOverlayBuffer_DrawImpress();
+}
+
+// #i74769#, #i75172#
+sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer_Calc() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsPaintBuffer_Calc();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer_Writer() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsPaintBuffer_Writer();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsPaintBuffer_DrawImpress() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsPaintBuffer_DrawImpress();
+}
+
+// #i4219#
+sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperWidth() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMaximumPaperWidth();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperHeight() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMaximumPaperHeight();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperLeftMargin() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMaximumPaperLeftMargin();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperRightMargin() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMaximumPaperRightMargin();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperTopMargin() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMaximumPaperTopMargin();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetMaximumPaperBottomMargin() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMaximumPaperBottomMargin();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer::SetOverlayBuffer( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetOverlayBuffer( bState );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer::SetPaintBuffer( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetPaintBuffer( bState );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer::SetStripeColorA( Color aColor )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetStripeColorA( aColor );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer::SetStripeColorB( Color aColor )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetStripeColorB( aColor );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtOptionsDrawinglayer::SetStripeLength( sal_uInt16 nLength )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetStripeLength( nLength );
+}
+
+// #i73602#
+void SvtOptionsDrawinglayer::SetOverlayBuffer_Calc( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetOverlayBuffer_Calc( bState );
+}
+
+void SvtOptionsDrawinglayer::SetOverlayBuffer_Writer( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetOverlayBuffer_Writer( bState );
+}
+
+void SvtOptionsDrawinglayer::SetOverlayBuffer_DrawImpress( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetOverlayBuffer_DrawImpress( bState );
+}
+
+// #i74769#, #i75172#
+void SvtOptionsDrawinglayer::SetPaintBuffer_Calc( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetPaintBuffer_Calc( bState );
+}
+
+void SvtOptionsDrawinglayer::SetPaintBuffer_Writer( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetPaintBuffer_Writer( bState );
+}
+
+void SvtOptionsDrawinglayer::SetPaintBuffer_DrawImpress( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetPaintBuffer_DrawImpress( bState );
+}
+
+// #i4219#
+void SvtOptionsDrawinglayer::SetMaximumPaperWidth( sal_uInt32 nNew )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMaximumPaperWidth( nNew );
+}
+
+void SvtOptionsDrawinglayer::SetMaximumPaperHeight( sal_uInt32 nNew )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMaximumPaperHeight( nNew );
+}
+
+void SvtOptionsDrawinglayer::SetMaximumPaperLeftMargin( sal_uInt32 nNew )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMaximumPaperLeftMargin( nNew );
+}
+
+void SvtOptionsDrawinglayer::SetMaximumPaperRightMargin( sal_uInt32 nNew )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMaximumPaperRightMargin( nNew );
+}
+
+void SvtOptionsDrawinglayer::SetMaximumPaperTopMargin( sal_uInt32 nNew )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMaximumPaperTopMargin( nNew );
+}
+
+void SvtOptionsDrawinglayer::SetMaximumPaperBottomMargin( sal_uInt32 nNew )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetMaximumPaperBottomMargin( nNew );
+}
+
+// helper
+sal_Bool SvtOptionsDrawinglayer::IsAAPossibleOnThisSystem() const
+{
+ return m_pDataContainer->IsAAPossibleOnThisSystem();
+}
+
+// primitives
+sal_Bool SvtOptionsDrawinglayer::IsAntiAliasing() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsAntiAliasing() && IsAAPossibleOnThisSystem();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsSnapHorVerLinesToDiscrete() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsAntiAliasing() && m_pDataContainer->IsSnapHorVerLinesToDiscrete();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsSolidDragCreate() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsSolidDragCreate();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsRenderDecoratedTextDirect() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsRenderDecoratedTextDirect();
+}
+
+sal_Bool SvtOptionsDrawinglayer::IsRenderSimpleTextDirect() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsRenderSimpleTextDirect();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetQuadratic3DRenderLimit() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetQuadratic3DRenderLimit();
+}
+
+sal_uInt32 SvtOptionsDrawinglayer::GetQuadraticFormControlRenderLimit() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetQuadraticFormControlRenderLimit();
+}
+
+void SvtOptionsDrawinglayer::SetAntiAliasing( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetAntiAliasing( bState );
+}
+
+void SvtOptionsDrawinglayer::SetSnapHorVerLinesToDiscrete( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetSnapHorVerLinesToDiscrete( bState );
+}
+
+void SvtOptionsDrawinglayer::SetSolidDragCreate( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetSolidDragCreate( bState );
+}
+
+void SvtOptionsDrawinglayer::SetRenderDecoratedTextDirect( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetRenderDecoratedTextDirect( bState );
+}
+
+void SvtOptionsDrawinglayer::SetRenderSimpleTextDirect( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetRenderSimpleTextDirect( bState );
+}
+
+void SvtOptionsDrawinglayer::SetQuadratic3DRenderLimit(sal_uInt32 nNew)
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetQuadratic3DRenderLimit( nNew );
+}
+
+void SvtOptionsDrawinglayer::SetQuadraticFormControlRenderLimit(sal_uInt32 nNew)
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetQuadraticFormControlRenderLimit( nNew );
+}
+
+// #i97672# selection settings
+sal_Bool SvtOptionsDrawinglayer::IsTransparentSelection() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsTransparentSelection();
+}
+
+void SvtOptionsDrawinglayer::SetTransparentSelection( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetTransparentSelection( bState );
+}
+
+sal_uInt16 SvtOptionsDrawinglayer::GetTransparentSelectionPercent() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ sal_uInt16 aRetval(m_pDataContainer->GetTransparentSelectionPercent());
+
+ // crop to range [10% .. 90%]
+ if(aRetval < 10)
+ {
+ aRetval = 10;
+ }
+
+ if(aRetval > 90)
+ {
+ aRetval = 90;
+ }
+
+ return aRetval;
+}
+
+void SvtOptionsDrawinglayer::SetTransparentSelectionPercent( sal_uInt16 nPercent )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+
+ // crop to range [10% .. 90%]
+ if(nPercent < 10)
+ {
+ nPercent = 10;
+ }
+
+ if(nPercent > 90)
+ {
+ nPercent = 90;
+ }
+
+ m_pDataContainer->SetTransparentSelectionPercent( nPercent );
+}
+
+sal_uInt16 SvtOptionsDrawinglayer::GetSelectionMaximumLuminancePercent() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ sal_uInt16 aRetval(m_pDataContainer->GetSelectionMaximumLuminancePercent());
+
+ // crop to range [0% .. 100%]
+ if(aRetval > 90)
+ {
+ aRetval = 90;
+ }
+
+ return aRetval;
+}
+
+void SvtOptionsDrawinglayer::SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+
+ // crop to range [0% .. 100%]
+ if(nPercent > 90)
+ {
+ nPercent = 90;
+ }
+
+ m_pDataContainer->SetSelectionMaximumLuminancePercent( nPercent );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Mutex& SvtOptionsDrawinglayer::GetOwnStaticMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+
+// eof
+
diff --git a/svtools/source/config/printoptions.cxx b/svtools/source/config/printoptions.cxx
new file mode 100644
index 000000000000..46e1f737d347
--- /dev/null
+++ b/svtools/source/config/printoptions.cxx
@@ -0,0 +1,870 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <svtools/printoptions.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <tools/debug.hxx>
+#include <vcl/print.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
+#include <com/sun/star/container/XNameAccess.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
+#include <com/sun/star/container/XNameContainer.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#endif
+
+#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
+#include <comphelper/configurationhelper.hxx>
+#endif
+
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
+#include <unotools/processfactory.hxx>
+#endif
+
+#ifndef _SVT_LOGHELPER_HXX
+#include <unotools/loghelper.hxx>
+#endif
+
+#include <itemholder2.hxx>
+
+
+// -----------
+// - statics -
+// -----------
+
+static USHORT aDPIArray[] = { 72, 96, 150, 200, 300, 600 };
+
+#define DPI_COUNT (sizeof(aDPIArray)/sizeof(aDPIArray[0 ]))
+
+// -----------
+// - Defines -
+// -----------
+
+#define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Print/Option"))
+#define ROOTNODE_PRINTOPTION OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/Print/Option"))
+
+#define PROPERTYNAME_REDUCETRANSPARENCY OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceTransparency"))
+#define PROPERTYNAME_REDUCEDTRANSPARENCYMODE OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedTransparencyMode"))
+#define PROPERTYNAME_REDUCEGRADIENTS OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceGradients"))
+#define PROPERTYNAME_REDUCEDGRADIENTMODE OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedGradientMode"))
+#define PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedGradientStepCount"))
+#define PROPERTYNAME_REDUCEBITMAPS OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceBitmaps"))
+#define PROPERTYNAME_REDUCEDBITMAPMODE OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapMode"))
+#define PROPERTYNAME_REDUCEDBITMAPRESOLUTION OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapResolution"))
+#define PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapIncludesTransparency"))
+#define PROPERTYNAME_CONVERTTOGREYSCALES OUString(RTL_CONSTASCII_USTRINGPARAM("ConvertToGreyscales"))
+
+// --------------
+// - Namespaces -
+// --------------
+
+using namespace ::utl;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+namespace css = com::sun::star;
+
+// -----------
+// - statics -
+// -----------
+
+static SvtPrintOptions_Impl* pPrinterOptionsDataContainer = NULL;
+static SvtPrintOptions_Impl* pPrintFileOptionsDataContainer = NULL;
+
+SvtPrintOptions_Impl* SvtPrinterOptions::m_pStaticDataContainer = NULL;
+sal_Int32 SvtPrinterOptions::m_nRefCount = 0;
+
+SvtPrintOptions_Impl* SvtPrintFileOptions::m_pStaticDataContainer = NULL;
+sal_Int32 SvtPrintFileOptions::m_nRefCount = 0;
+
+// ------------------------
+// - SvtPrintOptions_Impl -
+// ------------------------
+
+class SvtPrintOptions_Impl
+{
+public:
+
+//---------------------------------------------------------------------------------------------------------
+// constructor / destructor
+//---------------------------------------------------------------------------------------------------------
+
+ SvtPrintOptions_Impl( const OUString& rConfigRoot );
+ ~SvtPrintOptions_Impl();
+
+//---------------------------------------------------------------------------------------------------------
+// public interface
+//---------------------------------------------------------------------------------------------------------
+
+ sal_Bool IsReduceTransparency() const ;
+ sal_Int16 GetReducedTransparencyMode() const ;
+ sal_Bool IsReduceGradients() const ;
+ sal_Int16 GetReducedGradientMode() const ;
+ sal_Int16 GetReducedGradientStepCount() const ;
+ sal_Bool IsReduceBitmaps() const ;
+ sal_Int16 GetReducedBitmapMode() const ;
+ sal_Int16 GetReducedBitmapResolution() const ;
+ sal_Bool IsReducedBitmapIncludesTransparency() const ;
+ sal_Bool IsConvertToGreyscales() const;
+
+ void SetReduceTransparency( sal_Bool bState ) ;
+ void SetReducedTransparencyMode( sal_Int16 nMode ) ;
+ void SetReduceGradients( sal_Bool bState ) ;
+ void SetReducedGradientMode( sal_Int16 nMode ) ;
+ void SetReducedGradientStepCount( sal_Int16 nStepCount ) ;
+ void SetReduceBitmaps( sal_Bool bState ) ;
+ void SetReducedBitmapMode( sal_Int16 nMode ) ;
+ void SetReducedBitmapResolution( sal_Int16 nResolution ) ;
+ void SetReducedBitmapIncludesTransparency( sal_Bool bState ) ;
+ void SetConvertToGreyscales( sal_Bool bState ) ;
+
+//-------------------------------------------------------------------------------------------------------------
+// private API
+//-------------------------------------------------------------------------------------------------------------
+
+private:
+ void impl_setValue (const ::rtl::OUString& sProp,
+ ::sal_Bool bNew );
+ void impl_setValue (const ::rtl::OUString& sProp,
+ ::sal_Int16 nNew );
+
+//-------------------------------------------------------------------------------------------------------------
+// private member
+//-------------------------------------------------------------------------------------------------------------
+
+private:
+ css::uno::Reference< css::container::XNameAccess > m_xCfg;
+ css::uno::Reference< css::container::XNameAccess > m_xNode;
+};
+
+SvtPrintOptions_Impl::SvtPrintOptions_Impl(const OUString& rConfigRoot)
+{
+ try
+ {
+ m_xCfg = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(
+ utl::getProcessServiceFactory(),
+ ROOTNODE_PRINTOPTION,
+ ::comphelper::ConfigurationHelper::E_STANDARD),
+ css::uno::UNO_QUERY);
+
+ if (m_xCfg.is())
+ {
+ UniString sTmp = UniString(rConfigRoot);
+ xub_StrLen nTokenCount = sTmp.GetTokenCount('/');
+ sTmp = sTmp.GetToken(nTokenCount - 1, '/');
+ m_xCfg->getByName(OUString(sTmp.GetBuffer())) >>= m_xNode;
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ m_xNode.clear();
+ m_xCfg.clear();
+ LogHelper::logIt(ex);
+ }
+}
+
+sal_Bool SvtPrintOptions_Impl::IsReduceTransparency() const
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference< css::beans::XPropertySet > xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ xSet->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY) >>= bRet;
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Int16 SvtPrintOptions_Impl::GetReducedTransparencyMode() const
+{
+ sal_Int16 nRet = 0;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference< css::beans::XPropertySet > xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE) >>= nRet;
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return nRet;
+}
+
+sal_Bool SvtPrintOptions_Impl::IsReduceGradients() const
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS) >>= bRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Int16 SvtPrintOptions_Impl::GetReducedGradientMode() const
+{
+ sal_Int16 nRet = 0;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE) >>= nRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return nRet;
+}
+
+sal_Int16 SvtPrintOptions_Impl::GetReducedGradientStepCount() const
+{
+ sal_Int16 nRet = 64;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT) >>= nRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return nRet;
+}
+
+sal_Bool SvtPrintOptions_Impl::IsReduceBitmaps() const
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS) >>= bRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Int16 SvtPrintOptions_Impl::GetReducedBitmapMode() const
+{
+ sal_Int16 nRet = 1;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE) >>= nRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return nRet;
+}
+
+sal_Int16 SvtPrintOptions_Impl::GetReducedBitmapResolution() const
+{
+ sal_Int16 nRet = 3;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION) >>= nRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return nRet;
+}
+
+sal_Bool SvtPrintOptions_Impl::IsReducedBitmapIncludesTransparency() const
+{
+ sal_Bool bRet = sal_True;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY) >>= bRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+}
+
+sal_Bool SvtPrintOptions_Impl::IsConvertToGreyscales() const
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ if (m_xNode.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES) >>= bRet;
+ }
+ }
+ }
+ catch (const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+
+ return bRet;
+
+}
+
+void SvtPrintOptions_Impl::SetReduceTransparency(sal_Bool bState)
+{
+ impl_setValue(PROPERTYNAME_REDUCETRANSPARENCY, bState);
+}
+
+void SvtPrintOptions_Impl::SetReducedTransparencyMode(sal_Int16 nMode)
+{
+ impl_setValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE, nMode);
+}
+
+void SvtPrintOptions_Impl::SetReduceGradients(sal_Bool bState)
+{
+ impl_setValue(PROPERTYNAME_REDUCEGRADIENTS, bState);
+}
+
+void SvtPrintOptions_Impl::SetReducedGradientMode(sal_Int16 nMode)
+{
+ impl_setValue(PROPERTYNAME_REDUCEDGRADIENTMODE, nMode);
+}
+
+void SvtPrintOptions_Impl::SetReducedGradientStepCount(sal_Int16 nStepCount )
+{
+ impl_setValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT, nStepCount);
+}
+
+void SvtPrintOptions_Impl::SetReduceBitmaps(sal_Bool bState )
+{
+ impl_setValue(PROPERTYNAME_REDUCEBITMAPS, bState);
+}
+
+void SvtPrintOptions_Impl::SetReducedBitmapMode(sal_Int16 nMode )
+{
+ impl_setValue(PROPERTYNAME_REDUCEDBITMAPMODE, nMode);
+}
+
+void SvtPrintOptions_Impl::SetReducedBitmapResolution(sal_Int16 nResolution )
+{
+ impl_setValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION, nResolution);
+}
+
+void SvtPrintOptions_Impl::SetReducedBitmapIncludesTransparency(sal_Bool bState )
+{
+ impl_setValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY, bState);
+}
+
+void SvtPrintOptions_Impl::SetConvertToGreyscales(sal_Bool bState)
+{
+ impl_setValue(PROPERTYNAME_CONVERTTOGREYSCALES, bState);
+}
+
+SvtPrintOptions_Impl::~SvtPrintOptions_Impl()
+{
+ m_xNode.clear();
+ m_xCfg.clear();
+}
+
+void SvtPrintOptions_Impl::impl_setValue (const ::rtl::OUString& sProp,
+ ::sal_Bool bNew )
+{
+ try
+ {
+ if ( ! m_xNode.is())
+ return;
+
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if ( ! xSet.is())
+ return;
+
+ ::sal_Bool bOld = ! bNew;
+ if ( ! (xSet->getPropertyValue(sProp) >>= bOld))
+ return;
+
+ if (bOld != bNew)
+ {
+ xSet->setPropertyValue(sProp, css::uno::makeAny(bNew));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+void SvtPrintOptions_Impl::impl_setValue (const ::rtl::OUString& sProp,
+ ::sal_Int16 nNew )
+{
+ try
+ {
+ if ( ! m_xNode.is())
+ return;
+
+ css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY);
+ if ( ! xSet.is())
+ return;
+
+ ::sal_Int16 nOld = nNew+1;
+ if ( ! (xSet->getPropertyValue(sProp) >>= nOld))
+ return;
+
+ if (nOld != nNew)
+ {
+ xSet->setPropertyValue(sProp, css::uno::makeAny(nNew));
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+ }
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ LogHelper::logIt(ex);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+
+// -----------------------
+// - SvtBasePrintOptions -
+// -----------------------
+
+SvtBasePrintOptions::SvtBasePrintOptions()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SvtBasePrintOptions::~SvtBasePrintOptions()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+Mutex& SvtBasePrintOptions::GetOwnStaticMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvtBasePrintOptions::IsReduceTransparency() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsReduceTransparency();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SvtBasePrintOptions::GetReducedTransparencyMode() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetReducedTransparencyMode();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvtBasePrintOptions::IsReduceGradients() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsReduceGradients();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SvtBasePrintOptions::GetReducedGradientMode() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetReducedGradientMode();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SvtBasePrintOptions::GetReducedGradientStepCount() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetReducedGradientStepCount();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvtBasePrintOptions::IsReduceBitmaps() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsReduceBitmaps();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SvtBasePrintOptions::GetReducedBitmapMode() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetReducedBitmapMode();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SvtBasePrintOptions::GetReducedBitmapResolution() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetReducedBitmapResolution();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvtBasePrintOptions::IsReducedBitmapIncludesTransparency() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsReducedBitmapIncludesTransparency();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvtBasePrintOptions::IsConvertToGreyscales() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->IsConvertToGreyscales();
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReduceTransparency( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReduceTransparency( bState ) ;
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReducedTransparencyMode( sal_Int16 nMode )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReducedTransparencyMode( nMode );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReduceGradients( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReduceGradients( bState );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReducedGradientMode( sal_Int16 nMode )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReducedGradientMode( nMode );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReducedGradientStepCount( sal_Int16 nStepCount )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReducedGradientStepCount( nStepCount );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReduceBitmaps( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReduceBitmaps( bState );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReducedBitmapMode( sal_Int16 nMode )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReducedBitmapMode( nMode );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReducedBitmapResolution( sal_Int16 nResolution )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReducedBitmapResolution( nResolution );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetReducedBitmapIncludesTransparency( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetReducedBitmapIncludesTransparency( bState );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetConvertToGreyscales( sal_Bool bState )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->SetConvertToGreyscales( bState );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::GetPrinterOptions( PrinterOptions& rOptions ) const
+{
+ rOptions.SetReduceTransparency( IsReduceTransparency() );
+ rOptions.SetReducedTransparencyMode( (PrinterTransparencyMode) GetReducedTransparencyMode() );
+ rOptions.SetReduceGradients( IsReduceGradients() );
+ rOptions.SetReducedGradientMode( (PrinterGradientMode) GetReducedGradientMode() );
+ rOptions.SetReducedGradientStepCount( GetReducedGradientStepCount() );
+ rOptions.SetReduceBitmaps( IsReduceBitmaps() );
+ rOptions.SetReducedBitmapMode( (PrinterBitmapMode) GetReducedBitmapMode() );
+ rOptions.SetReducedBitmapResolution( aDPIArray[ Min( (USHORT) GetReducedBitmapResolution(), (USHORT)( DPI_COUNT - 1 ) ) ] );
+ rOptions.SetReducedBitmapIncludesTransparency( IsReducedBitmapIncludesTransparency() );
+ rOptions.SetConvertToGreyscales( IsConvertToGreyscales() );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtBasePrintOptions::SetPrinterOptions( const PrinterOptions& rOptions )
+{
+ SetReduceTransparency( rOptions.IsReduceTransparency() );
+ SetReducedTransparencyMode(
+ sal::static_int_cast< sal_Int16 >(
+ rOptions.GetReducedTransparencyMode()) );
+ SetReduceGradients( rOptions.IsReduceGradients() );
+ SetReducedGradientMode(
+ sal::static_int_cast< sal_Int16 >(rOptions.GetReducedGradientMode()) );
+ SetReducedGradientStepCount( rOptions.GetReducedGradientStepCount() );
+ SetReduceBitmaps( rOptions.IsReduceBitmaps() );
+ SetReducedBitmapMode(
+ sal::static_int_cast< sal_Int16 >(rOptions.GetReducedBitmapMode()) );
+ SetReducedBitmapIncludesTransparency( rOptions.IsReducedBitmapIncludesTransparency() );
+ SetConvertToGreyscales( rOptions.IsConvertToGreyscales() );
+
+ const USHORT nDPI = rOptions.GetReducedBitmapResolution();
+
+ if( nDPI < aDPIArray[ 0 ] )
+ SetReducedBitmapResolution( 0 );
+ else
+ {
+ for( long i = ( DPI_COUNT - 1 ); i >= 0; i-- )
+ {
+ if( nDPI >= aDPIArray[ i ] )
+ {
+ SetReducedBitmapResolution( (sal_Int16) i );
+ i = -1;
+ }
+ }
+ }
+}
+
+// ---------------------
+// - SvtPrinterOptions -
+// ---------------------
+
+SvtPrinterOptions::SvtPrinterOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already!
+ if( m_pStaticDataContainer == NULL )
+ {
+ OUString aRootPath( ROOTNODE_START );
+ m_pStaticDataContainer = new SvtPrintOptions_Impl( aRootPath += OUString( RTL_CONSTASCII_USTRINGPARAM( "/Printer" ) ) );
+ pPrinterOptionsDataContainer = m_pStaticDataContainer;
+ ItemHolder2::holdConfigItem(E_PRINTOPTIONS);
+ }
+
+ SetDataContainer( m_pStaticDataContainer );
+}
+
+// -----------------------------------------------------------------------------
+
+SvtPrinterOptions::~SvtPrinterOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pStaticDataContainer;
+ m_pStaticDataContainer = NULL;
+ pPrinterOptionsDataContainer = NULL;
+ }
+}
+
+// ---------------------
+// - SvtPrintFileOptions -
+// ---------------------
+
+SvtPrintFileOptions::SvtPrintFileOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already!
+ if( m_pStaticDataContainer == NULL )
+ {
+ OUString aRootPath( ROOTNODE_START );
+ m_pStaticDataContainer = new SvtPrintOptions_Impl( aRootPath += OUString( RTL_CONSTASCII_USTRINGPARAM( "/File" ) ) );
+ pPrintFileOptionsDataContainer = m_pStaticDataContainer;
+
+ ItemHolder2::holdConfigItem(E_PRINTFILEOPTIONS);
+ }
+
+ SetDataContainer( m_pStaticDataContainer );
+}
+
+// -----------------------------------------------------------------------------
+
+SvtPrintFileOptions::~SvtPrintFileOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pStaticDataContainer;
+ m_pStaticDataContainer = NULL;
+ pPrintFileOptionsDataContainer = NULL;
+ }
+}
diff --git a/svtools/source/config/test/makefile.mk b/svtools/source/config/test/makefile.mk
new file mode 100644
index 000000000000..71bea788d8de
--- /dev/null
+++ b/svtools/source/config/test/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= svtools
+TARGET= test_configitems
+LIBTARGET= NO
+ENABLE_EXCEPTIONS= TRUE
+USE_DEFFILE= TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- application: "test" --------------------------------------------------
+
+APP1TARGET= test
+
+APP1OBJS= $(SLO)$/test.obj \
+ $(SLO)$/dynamicmenuoptions.obj
+
+DEPOBJFILES=$(APP1OBJS)
+
+APP1STDLIBS= $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(SALLIB) \
+ $(VOSLIB) \
+ $(TOOLSLIB) \
+ $(VCLLIB)
+
+APP1DEPN= $(SLO)$/dynamicmenuoptions.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/config/test/test.cxx b/svtools/source/config/test/test.cxx
new file mode 100644
index 000000000000..ea4e0c0ec942
--- /dev/null
+++ b/svtools/source/config/test/test.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_svtools.hxx"
+
+//_________________________________________________________________________________________________________________
+// switches
+// use it to enable test szenarios
+//_________________________________________________________________________________________________________________
+
+#define TEST_DYNAMICMENUOPTIONS
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <unotools/dynamicmenuoptions.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/regpathhelper.hxx>
+#endif
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.h>
+
+#ifndef _RTL_USTRING_
+#include <rtl/ustring>
+#endif
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+/*
+#include <svtools/unoiface.hxx>
+#include <tools/urlobj.hxx>
+*/
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/msgbox.hxx>
+#include <stdio.h>
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::rtl ;
+using namespace ::osl ;
+using namespace ::comphelper ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::registry ;
+
+//_________________________________________________________________________________________________________________
+// defines
+//_________________________________________________________________________________________________________________
+
+#define ASCII( STEXT ) OUString( RTL_CONSTASCII_USTRINGPARAM( STEXT ))
+
+#define SERVICENAME_SIMPLEREGISTRY OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry" ))
+#define SERVICENAME_NESTEDREGISTRY OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.NestedRegistry" ))
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+class TestApplication : public Application
+{
+ //*************************************************************************************************************
+ // interface
+ //*************************************************************************************************************
+ public:
+ void Main();
+
+ //*************************************************************************************************************
+ // test methods
+ //*************************************************************************************************************
+ private:
+ void impl_testDynamicMenuOptions();
+
+ //*************************************************************************************************************
+ // helper methods
+ //*************************************************************************************************************
+ private:
+ static Reference< XMultiServiceFactory > getUNOServiceManager();
+
+ //*************************************************************************************************************
+ // member
+ //*************************************************************************************************************
+ private:
+
+}; // class TestApplication
+
+//_________________________________________________________________________________________________________________
+// global variables
+//_________________________________________________________________________________________________________________
+
+TestApplication aTestApplication ;
+
+//_________________________________________________________________________________________________________________
+// main
+//_________________________________________________________________________________________________________________
+
+void TestApplication::Main()
+{
+ /**-***********************************************************************************************************
+ initialize program
+ **************************************************************************************************************/
+
+ // Init global servicemanager and set it for external services.
+ ::comphelper::setProcessServiceFactory( TestApplication::getUNOServiceManager() );
+ // Control sucess of operation.
+ OSL_ENSURE( !(::comphelper::getProcessServiceFactory()!=TestApplication::getUNOServiceManager()), "TestApplication::Main()\nGlobal servicemanager not right initialized.\n" );
+
+ /**-***********************************************************************************************************
+ test area
+ **************************************************************************************************************/
+
+ #ifdef TEST_DYNAMICMENUOPTIONS
+ impl_testDynamicMenuOptions();
+ #endif
+
+// Execute();
+ OSL_ENSURE( sal_False, "Test was successful!\n" );
+}
+
+//*****************************************************************************************************************
+// test configuration of dynamic menus "New" and "Wizard"
+//*****************************************************************************************************************
+void TestApplication::impl_testDynamicMenuOptions()
+{
+ SvtDynamicMenuOptions aCFG;
+
+ // Test:
+ // read menus
+ // if( menus == empty )
+ // {
+ // fill it with samples
+ // read it again
+ // }
+ // output content
+
+ Sequence< Sequence< PropertyValue > > lNewMenu = aCFG.GetMenu( E_NEWMENU );
+ Sequence< Sequence< PropertyValue > > lWizardMenu = aCFG.GetMenu( E_WIZARDMENU );
+
+ if( lNewMenu.getLength() < 1 )
+ {
+ aCFG.AppendItem( E_NEWMENU, ASCII("private:factory/swriter"), ASCII("new writer"), ASCII("icon_writer"), ASCII("_blank") );
+ aCFG.AppendItem( E_NEWMENU, ASCII("private:factory/scalc" ), ASCII("new calc" ), ASCII("icon_calc" ), ASCII("_blank") );
+ aCFG.AppendItem( E_NEWMENU, ASCII("private:factory/sdraw" ), ASCII("new draw" ), ASCII("icon_draw" ), ASCII("_blank") );
+
+ lNewMenu = aCFG.GetMenu( E_NEWMENU );
+ }
+
+ if( lWizardMenu.getLength() < 1 )
+ {
+ aCFG.AppendItem( E_WIZARDMENU, ASCII("file://a"), ASCII("system file"), ASCII("icon_file"), ASCII("_self") );
+ aCFG.AppendItem( E_WIZARDMENU, ASCII("ftp://b" ), ASCII("ftp host" ), ASCII("icon_ftp" ), ASCII("_self") );
+ aCFG.AppendItem( E_WIZARDMENU, ASCII("http://c"), ASCII("www" ), ASCII("icon_www" ), ASCII("_self") );
+
+ lWizardMenu = aCFG.GetMenu( E_WIZARDMENU );
+ }
+
+ sal_uInt32 nItemCount ;
+ sal_uInt32 nItem ;
+ sal_uInt32 nPropertyCount;
+ sal_uInt32 nProperty ;
+ OUString sPropertyValue;
+ OUStringBuffer sOut( 5000 ) ;
+
+ nItemCount = lNewMenu.getLength();
+ for( nItem=0; nItem<nItemCount; ++nItem )
+ {
+ nPropertyCount = lNewMenu[nItem].getLength();
+ for( nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ lNewMenu[nItem][nProperty].Value >>= sPropertyValue;
+
+ sOut.appendAscii ( "New/" );
+ sOut.append ( (sal_Int32)nItem );
+ sOut.appendAscii ( "/" );
+ sOut.append ( lNewMenu[nItem][nProperty].Name );
+ sOut.appendAscii ( " = " );
+ sOut.append ( sPropertyValue );
+ sOut.appendAscii ( "\n" );
+ }
+ }
+
+ sOut.appendAscii("\n--------------------------------------\n");
+
+ nItemCount = lWizardMenu.getLength();
+ for( nItem=0; nItem<nItemCount; ++nItem )
+ {
+ nPropertyCount = lNewMenu[nItem].getLength();
+ for( nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ lWizardMenu[nItem][nProperty].Value >>= sPropertyValue;
+
+ sOut.appendAscii ( "Wizard/" );
+ sOut.append ( (sal_Int32)nItem );
+ sOut.appendAscii ( "/" );
+ sOut.append ( lNewMenu[nItem][nProperty].Name );
+ sOut.appendAscii ( " = " );
+ sOut.append ( sPropertyValue );
+ sOut.appendAscii ( "\n" );
+ }
+ }
+
+ OSL_ENSURE( sal_False, OUStringToOString( sOut.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr() );
+}
+
+//*****************************************************************************************************************
+// create new uno servicemanager by using normall applicat.rdb and user.rdb of an office installation!
+// Don't use this application at same time like the office!
+//*****************************************************************************************************************
+Reference< XMultiServiceFactory > TestApplication::getUNOServiceManager()
+{
+ static Reference< XMultiServiceFactory > smgr;
+ if( ! smgr.is() )
+ {
+ Reference< XComponentContext > rCtx =
+ cppu::defaultBootstrap_InitialComponentContext();
+ smgr = Reference< XMultiServiceFactory > ( rCtx->getServiceManager() , UNO_QUERY );
+ }
+ return smgr;
+}
diff --git a/svtools/source/contnr/cont_pch.cxx b/svtools/source/contnr/cont_pch.cxx
new file mode 100644
index 000000000000..4661a08162a2
--- /dev/null
+++ b/svtools/source/contnr/cont_pch.cxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <sv.hxx>
+#include <svtools/treelist.hxx>
+#include <svtools/svtabbx.hxx>
+#include <svtools/svtreebx.hxx>
+#include <svtools/svicnvw.hxx>
+#include "svimpbox.hxx"
+#include "svimpicn.hxx"
+#include <svtools/svlbox.hxx>
+#include <svtools/svlbitm.hxx>
+
+
diff --git a/svtools/source/contnr/contentenumeration.cxx b/svtools/source/contnr/contentenumeration.cxx
new file mode 100644
index 000000000000..93f328ae2028
--- /dev/null
+++ b/svtools/source/contnr/contentenumeration.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_svtools.hxx"
+#include "contentenumeration.hxx"
+#include <svl/urlfilter.hxx>
+#include <svtools/inettbc.hxx>
+#include "imagemgr.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+/** === end UNO includes === **/
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+#include <memory>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+#define ROW_TITLE 1
+#define ROW_SIZE 2
+#define ROW_DATE_MOD 3
+#define ROW_DATE_CREATE 4
+#define ROW_IS_FOLDER 5
+#define ROW_TARGET_URL 6
+#define ROW_IS_HIDDEN 7
+#define ROW_IS_VOLUME 8
+#define ROW_IS_REMOTE 9
+#define ROW_IS_REMOVEABLE 10
+#define ROW_IS_FLOPPY 11
+#define ROW_IS_COMPACTDISC 12
+
+#define CONVERT_DATETIME( aUnoDT, aToolsDT ) \
+ aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \
+ Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) );
+
+ 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::Any;
+ using ::com::sun::star::util::DateTime;
+ using ::com::sun::star::sdbc::XResultSet;
+ using ::com::sun::star::sdbc::XRow;
+ using ::com::sun::star::ucb::XDynamicResultSet;
+ using ::com::sun::star::ucb::CommandAbortedException;
+ using ::com::sun::star::ucb::XContentAccess;
+ using ::com::sun::star::ucb::XCommandEnvironment;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::rtl::OUString;
+ using ::ucbhelper::ResultSetInclude;
+ using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
+
+ //====================================================================
+ //= FileViewContentEnumerator
+ //====================================================================
+ //--------------------------------------------------------------------
+ FileViewContentEnumerator::FileViewContentEnumerator(
+ const Reference< XCommandEnvironment >& _rxCommandEnv,
+ ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex,
+ const IContentTitleTranslation* _pTranslator )
+ :m_rContent ( _rContentToFill )
+ ,m_rContentMutex ( _rContentMutex )
+ ,m_refCount ( 0 )
+ ,m_xCommandEnv ( _rxCommandEnv )
+ ,m_pFilter ( NULL )
+ ,m_pTranslator ( _pTranslator )
+ ,m_bCancelled ( false )
+ ,m_rBlackList ( ::com::sun::star::uno::Sequence< ::rtl::OUString >() )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ FileViewContentEnumerator::~FileViewContentEnumerator()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void FileViewContentEnumerator::cancel()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bCancelled = true;
+ m_pResultHandler = NULL;
+ m_pTranslator = NULL;
+ m_pFilter = NULL;
+ m_aFolder.aContent = ::ucbhelper::Content();
+ m_aFolder.sURL = String();
+ }
+
+ //--------------------------------------------------------------------
+ EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync(
+ const FolderDescriptor& _rFolder,
+ const IUrlFilter* _pFilter,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
+ {
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFolder = _rFolder;
+ m_pFilter = _pFilter;
+ m_pResultHandler = NULL;
+ m_rBlackList = rBlackList;
+ }
+ return enumerateFolderContent();
+ }
+
+ //--------------------------------------------------------------------
+ void FileViewContentEnumerator::enumerateFolderContent(
+ const FolderDescriptor& _rFolder, const IUrlFilter* _pFilter, IEnumerationResultHandler* _pResultHandler )
+ {
+ // ensure that we don't get deleted while herein
+ acquire();
+ // the matching "release" will be called in onTerminated
+ // Note that onTerminated is only called if run was left normally.
+ // If somebody terminates the thread from the outside, then onTerminated
+ // will never be called. However, our terminate method is not accessible
+ // to our clients, so the only class which could misbehave is this class
+ // here itself ...
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFolder = _rFolder;
+ m_pFilter = _pFilter;
+ m_pResultHandler = _pResultHandler;
+
+ OSL_ENSURE( m_aFolder.aContent.get().is() || m_aFolder.sURL.Len(),
+ "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
+
+ // start the thread
+ create();
+ }
+
+ //--------------------------------------------------------------------
+ oslInterlockedCount SAL_CALL FileViewContentEnumerator::acquire()
+ {
+ return osl_incrementInterlockedCount( &m_refCount );
+ }
+
+ //--------------------------------------------------------------------
+ oslInterlockedCount SAL_CALL FileViewContentEnumerator::release()
+ {
+ if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
+ {
+ delete this;
+ return 0;
+ }
+ return m_refCount;
+ }
+
+ //--------------------------------------------------------------------
+ EnumerationResult FileViewContentEnumerator::enumerateFolderContent()
+ {
+ EnumerationResult eResult = ERROR;
+ try
+ {
+
+ Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(12);
+
+ aProps[0] = OUString::createFromAscii( "Title" );
+ aProps[1] = OUString::createFromAscii( "Size" );
+ aProps[2] = OUString::createFromAscii( "DateModified" );
+ aProps[3] = OUString::createFromAscii( "DateCreated" );
+ aProps[4] = OUString::createFromAscii( "IsFolder" );
+ aProps[5] = OUString::createFromAscii( "TargetURL" );
+ aProps[6] = OUString::createFromAscii( "IsHidden" );
+ aProps[7] = OUString::createFromAscii( "IsVolume" );
+ aProps[8] = OUString::createFromAscii( "IsRemote" );
+ aProps[9] = OUString::createFromAscii( "IsRemoveable" );
+ aProps[10] = OUString::createFromAscii( "IsFloppy" );
+ aProps[11] = OUString::createFromAscii( "IsCompactDisc" );
+
+ Reference< XCommandEnvironment > xEnvironment;
+ try
+ {
+ FolderDescriptor aFolder;
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ aFolder = m_aFolder;
+ xEnvironment = m_xCommandEnv;
+ }
+ if ( !aFolder.aContent.get().is() )
+ {
+ aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment );
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFolder.aContent = aFolder.aContent;
+ }
+ }
+
+ Reference< XDynamicResultSet > xDynResultSet;
+ ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS;
+ xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, eInclude );
+
+ if ( xDynResultSet.is() )
+ xResultSet = xDynResultSet->getStaticResultSet();
+ }
+ catch( CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "createCursor: CommandAbortedException" );
+ }
+ catch( Exception& )
+ {
+ }
+
+ bool bCancelled = false;
+ if ( xResultSet.is() )
+ {
+ Reference< XRow > xRow( xResultSet, UNO_QUERY );
+ Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+
+ try
+ {
+ SortingData_Impl* pData;
+ DateTime aDT;
+
+ while ( !bCancelled && xResultSet->next() )
+ {
+ sal_Bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN );
+ // don't show hidden files
+ if ( !bIsHidden || xRow->wasNull() )
+ {
+ pData = NULL;
+
+ aDT = xRow->getTimestamp( ROW_DATE_MOD );
+ sal_Bool bContainsDate = !xRow->wasNull();
+ if ( !bContainsDate )
+ {
+ aDT = xRow->getTimestamp( ROW_DATE_CREATE );
+ bContainsDate = !xRow->wasNull();
+ }
+
+ OUString aContentURL = xContentAccess->queryContentIdentifierString();
+ OUString aTargetURL = xRow->getString( ROW_TARGET_URL );
+ sal_Bool bHasTargetURL = !xRow->wasNull() && aTargetURL.getLength() > 0;
+
+ OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL;
+
+ // check for restrictions
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pFilter && !m_pFilter->isUrlAllowed( sRealURL ) )
+ continue;
+
+ if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) )
+ continue;
+ }
+
+ pData = new SortingData_Impl;
+ pData->maTargetURL = sRealURL;
+
+ pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull();
+ pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull();
+ pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull();
+ pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVEABLE ) && !xRow->wasNull();
+ pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull();
+ pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull();
+ pData->SetNewTitle( xRow->getString( ROW_TITLE ) );
+ pData->maSize = xRow->getLong( ROW_SIZE );
+
+ if ( bHasTargetURL &&
+ INetURLObject( aContentURL ).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER )
+ {
+ ::ucbhelper::Content aCnt( aTargetURL, xEnvironment );
+ try
+ {
+ aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= pData->maSize;
+ aCnt.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aDT;
+ }
+ catch (...) {}
+ }
+
+ if ( bContainsDate )
+ {
+ CONVERT_DATETIME( aDT, pData->maModDate );
+ }
+
+ if ( pData->mbIsFolder )
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote,
+ pData->mbIsRemoveable, pData->mbIsFloppy,
+ pData->mbIsCompactDisc );
+ pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
+ }
+ else
+ pData->maType = SvFileInformationManager::GetFileDescription(
+ INetURLObject( pData->maTargetURL ) );
+
+ // replace names on demand
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( m_pTranslator )
+ {
+ OUString sNewTitle;
+ sal_Bool bTranslated = sal_False;
+
+ if ( pData->mbIsFolder )
+ bTranslated = m_pTranslator->GetTranslation( pData->GetTitle(), sNewTitle );
+ else
+ bTranslated = implGetDocTitle( pData->maTargetURL, sNewTitle );
+
+ if ( bTranslated )
+ pData->ChangeTitle( sNewTitle );
+ }
+ }
+
+ {
+ ::osl::MutexGuard aGuard( m_rContentMutex );
+ m_rContent.push_back( pData );
+ }
+ }
+
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bCancelled = m_bCancelled;
+ }
+ }
+ eResult = SUCCESS;
+ }
+ catch( CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" );
+ }
+ }
+ }
+ catch( CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" );
+ }
+
+ IEnumerationResultHandler* pHandler = NULL;
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ pHandler = m_pResultHandler;
+ if ( m_bCancelled )
+ return ERROR;
+ }
+
+ {
+ ::osl::MutexGuard aGuard( m_rContentMutex );
+ if ( eResult != SUCCESS )
+ // clear any "intermediate" and unfinished result
+ m_rContent.clear();
+ }
+
+ if ( pHandler )
+ pHandler->enumerationDone( eResult );
+ return eResult;
+ }
+
+ //--------------------------------------------------------------------
+
+ sal_Bool FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString& sRealURL )
+ {
+ ::rtl::OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( rtl::OUString::createFromAscii("/")) +1 );
+
+ for (int i = 0; i < m_rBlackList.getLength() ; i++)
+ {
+ if ( entryName.equals( m_rBlackList[i] ) )
+ return true;
+ }
+
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool FileViewContentEnumerator::implGetDocTitle( const OUString& _rTargetURL, OUString& _rRet ) const
+ {
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( !m_xDocInfo.is() )
+ {
+ m_xDocInfo = m_xDocInfo.query(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ String( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.StandaloneDocumentInfo") )
+ )
+ );
+ }
+
+ DBG_ASSERT( m_xDocInfo.is(), "FileViewContentEnumerator::implGetDocTitle: no DocumentProperties service!" );
+ if ( !m_xDocInfo.is() )
+ return sal_False;
+
+ m_xDocInfo->loadFromURL( _rTargetURL );
+ Reference< XPropertySet > xPropSet( m_xDocInfo, UNO_QUERY );
+
+ Any aAny = xPropSet->getPropertyValue( OUString::createFromAscii( "Title" ) );
+
+ OUString sTitle;
+ if ( ( aAny >>= sTitle ) && sTitle.getLength() > 0 )
+ {
+ _rRet = sTitle;
+ bRet = sal_True;
+ }
+ }
+ catch ( const Exception& )
+ {
+ }
+
+ return bRet;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL FileViewContentEnumerator::run()
+ {
+ enumerateFolderContent();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL FileViewContentEnumerator::onTerminated()
+ {
+ release();
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
diff --git a/svtools/source/contnr/contentenumeration.hxx b/svtools/source/contnr/contentenumeration.hxx
new file mode 100644
index 000000000000..16db279ad547
--- /dev/null
+++ b/svtools/source/contnr/contentenumeration.hxx
@@ -0,0 +1,287 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SVTOOLS_SOURCE_CONTNR_CONTENTENUMERATION_HXX
+#define SVTOOLS_SOURCE_CONTNR_CONTENTENUMERATION_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
+/** === end UNO includes === **/
+#include <osl/thread.hxx>
+#include <rtl/ref.hxx>
+#include <ucbhelper/content.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/datetime.hxx>
+#include <vcl/image.hxx>
+
+class IUrlFilter;
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= SortingData_Impl
+ //====================================================================
+ struct SortingData_Impl
+ {
+ private:
+ ::rtl::OUString maFilename; // only filename in upper case - for compare purposes
+ ::rtl::OUString maTitle; // -> be carefull when changing maTitle to update maFilename only when new
+ ::rtl::OUString maLowerTitle;
+
+
+ public:
+ ::rtl::OUString maType;
+ ::rtl::OUString maTargetURL;
+ ::rtl::OUString maImageURL;
+ ::rtl::OUString maDisplayText;
+ DateTime maModDate;
+ Image maImage;
+ sal_Int64 maSize;
+ sal_Bool mbIsFolder;
+ sal_Bool mbIsVolume;
+ sal_Bool mbIsRemote;
+ sal_Bool mbIsRemoveable;
+ sal_Bool mbIsFloppy;
+ sal_Bool mbIsCompactDisc;
+
+ inline SortingData_Impl();
+ inline const ::rtl::OUString& GetTitle() const;
+ inline const ::rtl::OUString& GetLowerTitle() const;
+ inline const ::rtl::OUString& GetFileName() const;
+ inline void SetNewTitle( const ::rtl::OUString& rNewTitle ); // new maTitle is set -> maFilename is set to same!
+ inline void ChangeTitle( const ::rtl::OUString& rChangedTitle ); // maTitle is changed, maFilename is unchanged!
+
+ private:
+ inline void SetTitles( const ::rtl::OUString& rNewTitle );
+ };
+
+ inline SortingData_Impl::SortingData_Impl() :
+ maSize ( 0 ),
+ mbIsFolder ( sal_False ),
+ mbIsVolume ( sal_False ),
+ mbIsRemote ( sal_False ),
+ mbIsRemoveable ( sal_False ),
+ mbIsFloppy ( sal_False ),
+ mbIsCompactDisc ( sal_False )
+ {
+ }
+
+ inline const ::rtl::OUString& SortingData_Impl::GetTitle() const
+ {
+ return maTitle;
+ }
+
+ inline const ::rtl::OUString& SortingData_Impl::GetLowerTitle() const
+ {
+ return maLowerTitle;
+ }
+
+ inline const ::rtl::OUString& SortingData_Impl::GetFileName() const
+ {
+ return maFilename;
+ }
+
+ inline void SortingData_Impl::SetNewTitle( const ::rtl::OUString& rNewTitle )
+ {
+ SetTitles( rNewTitle );
+ maFilename = rNewTitle.toAsciiUpperCase();
+ }
+
+ inline void SortingData_Impl::ChangeTitle( const ::rtl::OUString& rChangedTitle )
+ {
+ SetTitles( rChangedTitle );
+ }
+
+ inline void SortingData_Impl::SetTitles( const ::rtl::OUString& rNewTitle )
+ {
+ maTitle = rNewTitle;
+ maLowerTitle = rNewTitle.toAsciiLowerCase();
+ }
+
+ //====================================================================
+ //= IContentTitleTranslation
+ //====================================================================
+ class IContentTitleTranslation
+ {
+ public:
+ virtual sal_Bool GetTranslation( const ::rtl::OUString& _rOriginalName, ::rtl::OUString& _rTranslatedName ) const = 0;
+ };
+
+ //====================================================================
+ //= EnumerationResult
+ //====================================================================
+ enum EnumerationResult
+ {
+ SUCCESS, /// the enumration was successfull
+ ERROR, /// the enumration was unsuccessfull
+ RUNNING /// the enumeration is still running, and the maximum wait time has passed
+ };
+
+ //====================================================================
+ //= FolderDescriptor
+ //====================================================================
+ struct FolderDescriptor
+ {
+ /** a content object describing the folder. Can be <NULL/>, in this case <member>sURL</member>
+ is relevant.
+ */
+ ::ucbhelper::Content aContent;
+ /** the URL of a folder. Will be ignored if <member>aContent</member> is not <NULL/>.
+ */
+ String sURL;
+
+ FolderDescriptor() { }
+
+ FolderDescriptor( const ::ucbhelper::Content& _rContent )
+ :aContent( _rContent )
+ {
+ }
+
+ FolderDescriptor( const String& _rURL )
+ :sURL( _rURL )
+ {
+ }
+ };
+
+ //====================================================================
+ //= IEnumerationResultHandler
+ //====================================================================
+ class IEnumerationResultHandler
+ {
+ public:
+ virtual void enumerationDone( EnumerationResult _eResult ) = 0;
+ };
+
+ //====================================================================
+ //= FileViewContentEnumerator
+ //====================================================================
+ class FileViewContentEnumerator
+ :public ::rtl::IReference
+ ,private ::osl::Thread
+ {
+ public:
+ typedef ::std::vector< SortingData_Impl* > ContentData;
+
+ private:
+ ContentData& m_rContent;
+ ::osl::Mutex& m_rContentMutex;
+
+ oslInterlockedCount m_refCount;
+ mutable ::osl::Mutex m_aMutex;
+
+ FolderDescriptor m_aFolder;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >
+ m_xCommandEnv;
+ const IUrlFilter* m_pFilter;
+ const IContentTitleTranslation* m_pTranslator;
+ IEnumerationResultHandler* m_pResultHandler;
+ bool m_bCancelled;
+
+ mutable ::com::sun::star::uno::Reference< ::com::sun::star::document::XStandaloneDocumentInfo >
+ m_xDocInfo;
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_rBlackList;
+
+ sal_Bool URLOnBlackList ( const ::rtl::OUString& sRealURL );
+
+ public:
+ /** constructs an enumerator instance
+
+ @param _rContentToFill
+ the structure which is to be filled with the found content
+ @param _rContentMutex
+ the mutex which protects the access to <arg>_rContentToFill</arg>
+ @param _pTranslator
+ an instance which should be used to translate content titles. May be <NULL/>
+ */
+ FileViewContentEnumerator(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& _rxCommandEnv,
+ ContentData& _rContentToFill,
+ ::osl::Mutex& _rContentMutex,
+ const IContentTitleTranslation* _pTranslator
+ );
+
+ /** enumerates the content of a given folder
+
+ @param _rFolder
+ the folder whose content is to be enumerated
+ @param _pFilter
+ a filter to apply to the found contents
+ @param _pResultHandler
+ an instance which should handle the results of the enumeration
+ */
+ void enumerateFolderContent(
+ const FolderDescriptor& _rFolder,
+ const IUrlFilter* _pFilter,
+ IEnumerationResultHandler* _pResultHandler
+ );
+
+ /** enumerates the content of a given folder synchronously
+ */
+ EnumerationResult enumerateFolderContentSync(
+ const FolderDescriptor& _rFolder,
+ const IUrlFilter* _pFilter,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList = ::com::sun::star::uno::Sequence< ::rtl::OUString >()
+ );
+
+ /** cancels the running operation.
+
+ Note that "cancel" may mean that the operation is running, but its result
+ is simply disregarded later on.
+ */
+ void cancel();
+
+ // IReference overridables
+ virtual oslInterlockedCount SAL_CALL acquire();
+ virtual oslInterlockedCount SAL_CALL release();
+
+ using Thread::operator new;
+ using Thread::operator delete;
+
+ protected:
+ ~FileViewContentEnumerator();
+
+ private:
+ EnumerationResult enumerateFolderContent();
+
+ // Thread overridables
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+
+ private:
+ sal_Bool implGetDocTitle( const ::rtl::OUString& _rTargetURL, ::rtl::OUString& _rRet ) const;
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // SVTOOLS_SOURCE_CONTNR_CONTENTENUMERATION_HXX
+
diff --git a/svtools/source/contnr/ctrdll.cxx b/svtools/source/contnr/ctrdll.cxx
new file mode 100644
index 000000000000..463c6ccc8b35
--- /dev/null
+++ b/svtools/source/contnr/ctrdll.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_svtools.hxx"
+
+#ifdef WIN
+#include <svwin.h>
+
+#ifndef _SYSDEP_HXX
+#include <sysdep.hxx>
+#endif
+
+// Statische DLL-Verwaltungs-Variablen
+static HINSTANCE hDLLInst = 0; // HANDLE der DLL
+
+
+/***************************************************************************
+|*
+|* LibMain()
+|*
+|* Beschreibung Initialisierungsfunktion der DLL
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
+{
+#ifndef WNT
+ if ( nHeap )
+ UnlockData( 0 );
+#endif
+
+ hDLLInst = hDLL;
+
+ return TRUE;
+}
+
+/***************************************************************************
+|*
+|* WEP()
+|*
+|* Beschreibung DLL-Deinitialisierung
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+#endif
diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx
new file mode 100644
index 000000000000..af19379d8b8f
--- /dev/null
+++ b/svtools/source/contnr/fileview.cxx
@@ -0,0 +1,2809 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "fileview.hxx"
+#include <svtools/svtdata.hxx>
+#include "imagemgr.hxx"
+#include <svtools/headbar.hxx>
+#include <svtools/svtabbx.hxx>
+
+#include <svtools/svtools.hrc>
+#include "fileview.hrc"
+#include "contentenumeration.hxx"
+#include <svtools/AccessibleBrowseBoxObjType.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <vcl/waitobj.hxx>
+#include <com/sun/star/io/XPersist.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <algorithm>
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <tools/datetime.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <vcl/msgbox.hxx>
+#ifndef INCLUDED_RTL_MATH_H
+#include <rtl/math.hxx>
+#endif
+#include <tools/config.hxx>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <vos/timer.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/sound.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <svl/urlfilter.hxx>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::beans;
+using namespace ::comphelper;
+using ::svt::SortingData_Impl;
+using ::svt::FolderDescriptor;
+using ::vos::TTimeValue;
+using ::rtl::OUString;
+
+#define ALL_FILES_FILTER "*.*"
+
+#define COLUMN_TITLE 1
+#define COLUMN_TYPE 2
+#define COLUMN_SIZE 3
+#define COLUMN_DATE 4
+
+DECLARE_LIST( StringList_Impl, OUString* )
+
+#define ROW_HEIGHT 17 // the height of a row has to be a little higher than the bitmap
+#define QUICK_SEARCH_TIMEOUT 1500 // time in mSec before the quicksearch string will be reseted
+
+namespace
+{
+ //====================================================================
+ //= ReleaseSolarMutex
+ //====================================================================
+ struct ReleaseSolarMutex
+ {
+ private:
+ ULONG m_nCount;
+
+ public:
+ inline ReleaseSolarMutex()
+ {
+ m_nCount = Application::ReleaseSolarMutex();
+ }
+ inline ~ReleaseSolarMutex()
+ {
+ Application::AcquireSolarMutex( m_nCount );
+ }
+ };
+
+ //====================================================================
+ //= ITimeoutHandler
+ //====================================================================
+ class CallbackTimer;
+ class ITimeoutHandler
+ {
+ public:
+ virtual void onTimeout( CallbackTimer* _pInstigator ) = 0;
+ };
+
+ //====================================================================
+ //= CallbackTimer
+ //====================================================================
+ class CallbackTimer : public ::vos::OTimer
+ {
+ protected:
+ ITimeoutHandler* m_pTimeoutHandler;
+
+ public:
+ CallbackTimer( ITimeoutHandler* _pHandler ) : m_pTimeoutHandler( _pHandler ) { }
+
+ protected:
+ virtual void SAL_CALL onShot();
+ };
+
+ //--------------------------------------------------------------------
+ void SAL_CALL CallbackTimer::onShot()
+ {
+ OSL_ENSURE( m_pTimeoutHandler, "CallbackTimer::onShot: nobody interested in?" );
+ ITimeoutHandler* pHandler( m_pTimeoutHandler );
+ if ( pHandler )
+ pHandler->onTimeout( this );
+ }
+
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Bool isHighContrast( const Window* _pView )
+{
+ return _pView->GetSettings().GetStyleSettings().GetHighContrastMode();
+}
+
+// -----------------------------------------------------------------------
+
+void FilterMatch::createWildCardFilterList(const String& _rFilterList,::std::vector< WildCard >& _rFilters)
+{
+ if( _rFilterList.Len() )
+ {// filter is given
+ xub_StrLen nCount = _rFilterList.GetTokenCount();
+ _rFilters.reserve( nCount );
+ xub_StrLen nIndex = 0;
+ OUString sToken;
+ do
+ {
+ sToken = _rFilterList.GetToken( 0, ';', nIndex );
+ if ( sToken.getLength() )
+ {
+ _rFilters.push_back( WildCard( sToken.toAsciiUpperCase() ) );
+ }
+ }
+ while ( nIndex != STRING_NOTFOUND );
+ }
+ else
+ // no filter is given -> match all
+ _rFilters.push_back( WildCard( String::CreateFromAscii( "*" ) ) );
+}
+// class ViewTabListBox_Impl ---------------------------------------------
+
+class ViewTabListBox_Impl : public SvHeaderTabListBox
+{
+private:
+ Reference< XCommandEnvironment > mxCmdEnv;
+
+ ::osl::Mutex maMutex;
+ HeaderBar* mpHeaderBar;
+ SvtFileView_Impl* mpParent;
+ Timer maResetQuickSearch;
+ OUString maQuickSearchText;
+ String msAccessibleDescText;
+ String msFolder;
+ String msFile;
+ sal_uInt32 mnSearchIndex;
+ sal_Bool mbResizeDisabled : 1;
+ sal_Bool mbAutoResize : 1;
+ sal_Bool mbEnableDelete : 1;
+ sal_Bool mbEnableRename : 1;
+
+ void DeleteEntries();
+ void DoQuickSearch( const xub_Unicode& rChar );
+ sal_Bool Kill( const OUString& rURL );
+
+protected:
+ virtual BOOL DoubleClickHdl();
+ virtual ::rtl::OUString GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const;
+
+public:
+ ViewTabListBox_Impl( Window* pParentWin, SvtFileView_Impl* pParent, sal_Int16 nFlags );
+ ~ViewTabListBox_Impl();
+
+ virtual void Resize();
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual BOOL EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText );
+
+ void ClearAll();
+ HeaderBar* GetHeaderBar() const { return mpHeaderBar; }
+
+ void EnableAutoResize() { mbAutoResize = sal_True; }
+ void EnableDelete( sal_Bool bEnable ) { mbEnableDelete = bEnable; }
+ void EnableRename( sal_Bool bEnable ) { mbEnableRename = bEnable; }
+ sal_Bool IsDeleteOrContextMenuEnabled() { return mbEnableDelete || IsContextMenuHandlingEnabled(); }
+
+ Reference< XCommandEnvironment > GetCommandEnvironment() const { return mxCmdEnv; }
+
+ DECL_LINK( ResetQuickSearch_Impl, Timer * );
+
+ virtual PopupMenu* CreateContextMenu( void );
+ virtual void ExcecuteContextMenuAction( USHORT nSelectedPopentry );
+};
+
+// class HashedEntry --------------------------------------------------
+
+class HashedEntry
+{ // just a special String which can be compared on equality much faster
+protected:
+ OUString maName;
+ sal_Int32 mnHashCode;
+public:
+ inline HashedEntry( const OUString& rName );
+ inline HashedEntry( const INetURLObject& rURL );
+ inline HashedEntry( const HashedEntry& rCopy );
+ virtual ~HashedEntry();
+
+ inline sal_Bool operator ==( const HashedEntry& rRef ) const;
+ inline sal_Bool operator !=( const HashedEntry& rRef ) const;
+
+ inline const OUString& GetName() const;
+};
+
+inline HashedEntry::HashedEntry( const OUString& rName ): maName( rName ), mnHashCode( rName.hashCode() )
+{
+}
+
+inline HashedEntry::HashedEntry( const INetURLObject& rURL ):
+ maName( rURL.GetMainURL( INetURLObject::NO_DECODE ) ),
+ mnHashCode( maName.hashCode() )
+{
+}
+
+inline HashedEntry::HashedEntry( const HashedEntry& r ): maName( r.maName ), mnHashCode( r.mnHashCode )
+{
+}
+
+HashedEntry::~HashedEntry()
+{
+}
+
+inline sal_Bool HashedEntry::operator ==( const HashedEntry& rRef ) const
+{
+ return mnHashCode == rRef.mnHashCode && maName.reverseCompareTo( rRef.maName ) == 0;
+}
+
+inline sal_Bool HashedEntry::operator !=( const HashedEntry& rRef ) const
+{
+ return mnHashCode != rRef.mnHashCode || maName.reverseCompareTo( rRef.maName ) != 0;
+}
+
+inline const OUString& HashedEntry::GetName() const
+{
+ return maName;
+}
+
+// class HashedEntryList ----------------------------------------------
+
+class HashedEntryList : protected List
+{// provides a list of _unique_ Entries
+protected:
+ inline HashedEntry* First();
+ inline HashedEntry* Next();
+ inline void Append( HashedEntry* pNewEntry );
+public:
+ virtual ~HashedEntryList();
+
+ const HashedEntry* Find( const OUString& rNameToSearchFor );
+ const HashedEntry* Find( const HashedEntry& rToSearchFor );
+ // not const, because First()/Next() is used
+ using List::Insert;
+ const HashedEntry& Insert( HashedEntry* pInsertOrDelete );
+ // don't care about pInsertOrDelete after this any more and handle it as invalid!
+ // returns the Entry, which is effectively inserted
+
+ void Clear();
+};
+
+inline HashedEntry* HashedEntryList::First()
+{
+ return ( HashedEntry* ) List::First();
+}
+
+inline HashedEntry* HashedEntryList::Next()
+{
+ return ( HashedEntry* ) List::Next();
+}
+
+inline void HashedEntryList::Append( HashedEntry* pNew )
+{
+ List::Insert( pNew, LIST_APPEND );
+}
+
+HashedEntryList::~HashedEntryList()
+{
+ Clear();
+}
+
+const HashedEntry* HashedEntryList::Find( const OUString& rRefName )
+{ // simple linear search, which should be fast enough for this purpose
+ HashedEntry aRef( rRefName );
+ HashedEntry* pIter = First();
+ while( pIter && *pIter != aRef )
+ pIter = Next();
+
+ return pIter;
+}
+
+const HashedEntry* HashedEntryList::Find( const HashedEntry& rRef )
+{ // simple linear search, which should be fast enough for this purpose
+ HashedEntry* pIter = First();
+ while( pIter && *pIter != rRef )
+ pIter = Next();
+
+ return pIter;
+}
+
+const HashedEntry& HashedEntryList::Insert( HashedEntry* pNew )
+{ // inserts (appends) only, if entry doesn't already exists
+ // if it already exists, pNew is deleted, because the caller must not worry about pNew any more
+
+ DBG_ASSERT( pNew, "HashedEntryList::Insert(): NULL-pointer can't be inserted" );
+
+ const HashedEntry* pSearch = Find( *pNew );
+ if( pSearch )
+ {
+ delete pNew;
+ return *pSearch;
+ }
+
+ Append( pNew );
+
+ return *pNew;
+}
+
+void HashedEntryList::Clear()
+{
+ HashedEntry* p = First();
+ while( p )
+ {
+ delete p;
+ p = Next();
+ }
+}
+
+// class NameTranslationEntry -----------------------------------------
+
+class NameTranslationEntry : public HashedEntry
+{// a fast compareble String and another String, which is used to get a substitution for a given String
+protected:
+ OUString maTranslatedName;
+public:
+ inline NameTranslationEntry( const OUString& rOriginalName, const OUString& rTranslatedName );
+ inline NameTranslationEntry( const ByteString& rOriginalName, const ByteString& rTranslatedName );
+
+ inline const OUString& GetTranslation() const;
+};
+
+inline NameTranslationEntry::NameTranslationEntry( const OUString& rOrg, const OUString& rTrans ):
+ HashedEntry( rOrg ),
+ maTranslatedName( rTrans )
+{
+}
+
+inline NameTranslationEntry::NameTranslationEntry( const ByteString& rOrg, const ByteString& rTrans ):
+ HashedEntry( OUString( rOrg.GetBuffer(), rOrg.Len(), RTL_TEXTENCODING_ASCII_US ) ),
+ maTranslatedName( OUString( rTrans.GetBuffer(), rTrans.Len(), RTL_TEXTENCODING_UTF8 ) )
+{
+}
+
+inline const OUString& NameTranslationEntry::GetTranslation() const
+{
+ return maTranslatedName;
+}
+
+// class NameTranslationList -----------------------------------------
+
+class NameTranslationList : protected HashedEntryList
+{ // contains a list of substitutes of strings for a given folder (as URL)
+ // explanation of the circumstances see in remarks for Init();
+protected:
+ INetURLObject maTransFile; // URL of file with translation entries
+ HashedEntry maHashedURL; // for future purposes when dealing with a set of cached
+ // NameTranslationLists
+private:
+ const String maTransFileName;
+ void Init(); // reads the translation file and fills the (internal) list
+
+public:
+ NameTranslationList( const INetURLObject& rBaseURL );
+ // rBaseURL: path to folder for which the translation of the entries
+ // should be done
+
+ using List::operator==;
+ inline sal_Bool operator ==( const HashedEntry& rRef ) const;
+ using List::operator!=;
+ inline sal_Bool operator !=( const HashedEntry& rRef ) const;
+
+ const OUString* Translate( const OUString& rName ) const;
+ // returns NULL, if rName can't be found
+
+ inline void Update(); // clears list and init
+
+ inline const String& GetTransTableFileName() const;
+ // returns the name for the file, which contains the translation strings
+};
+
+inline const String& NameTranslationList::GetTransTableFileName() const
+{
+ return maTransFileName;
+}
+
+void NameTranslationList::Init()
+{
+// Tries to read the file ".nametranslation.table" in the base folder. Complete path/name is in maTransFile.
+// Further on, the found entries in the section "TRANSLATIONNAMES" are used to replace names in the
+// base folder by translated ones. The translation must be given in UTF8
+// See examples of such a files in the samples-folder of an Office installation
+
+ try
+ {
+ ::ucbhelper::Content aTestContent( maTransFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >() );
+
+ if( aTestContent.isDocument() )
+ {// ... also tests the existence of maTransFile by throwing an Exception
+ const sal_Char* pSection = "TRANSLATIONNAMES";
+ String aFsysName( maTransFile.getFSysPath( INetURLObject::FSYS_DETECT ) );
+ Config aConfig( aFsysName );
+
+ aConfig.SetGroup( ByteString( pSection ) );
+
+ USHORT nKeyCnt = aConfig.GetKeyCount();
+
+ for( USHORT nCnt = 0 ; nCnt < nKeyCnt ; ++nCnt )
+ Insert( new NameTranslationEntry( aConfig.GetKeyName( nCnt ), aConfig.ReadKey( nCnt ) ) );
+ }
+ }
+ catch( Exception const & ) {}
+}
+
+NameTranslationList::NameTranslationList( const INetURLObject& rBaseURL ):
+ maTransFile( rBaseURL ),
+ maHashedURL( rBaseURL ),
+ maTransFileName( String::CreateFromAscii( ".nametranslation.table" ) )
+{
+ maTransFile.insertName( maTransFileName );
+ Init();
+}
+
+inline sal_Bool NameTranslationList::operator ==( const HashedEntry& rRef ) const
+{
+ return maHashedURL == rRef;
+}
+
+inline sal_Bool NameTranslationList::operator !=( const HashedEntry& rRef ) const
+{
+ return maHashedURL != rRef;
+}
+
+const OUString* NameTranslationList::Translate( const OUString& rName ) const
+{
+ const NameTranslationEntry* pSearch = static_cast< const NameTranslationEntry* >(
+ ( const_cast< NameTranslationList* >( this ) )->Find( rName ) );
+
+ return pSearch? &pSearch->GetTranslation() : NULL;
+}
+
+inline void NameTranslationList::Update()
+{
+ Clear();
+ Init();
+}
+
+// class NameTranslator_Impl ------------------------------------------
+
+// enables the user to get string substitutions (translations for the content) for a given folder
+// see more explanations above in the description for NameTranslationList
+class NameTranslator_Impl : public ::svt::IContentTitleTranslation
+{
+private:
+ NameTranslationList* mpActFolder;
+public:
+ NameTranslator_Impl( void );
+ NameTranslator_Impl( const INetURLObject& rActualFolder );
+ virtual ~NameTranslator_Impl();
+
+ // IContentTitleTranslation
+ virtual sal_Bool GetTranslation( const OUString& rOriginalName, OUString& rTranslatedName ) const;
+
+ void UpdateTranslationTable(); // reads the translation file again
+
+ void SetActualFolder( const INetURLObject& rActualFolder );
+ const String* GetTransTableFileName() const;
+ // returns the name for the file, which contains the translation strings
+};
+
+//====================================================================
+//= SvtFileView_Impl
+//====================================================================
+
+class SvtFileView_Impl :public ::svt::IEnumerationResultHandler
+ ,public ITimeoutHandler
+{
+protected:
+ SvtFileView* mpAntiImpl;
+ Link m_aSelectHandler;
+
+ ::rtl::Reference< ::svt::FileViewContentEnumerator >
+ m_pContentEnumerator;
+ Link m_aCurrentAsyncActionHandler;
+ ::osl::Condition m_aAsyncActionFinished;
+ ::rtl::Reference< ::vos::OTimer > m_pCancelAsyncTimer;
+ ::svt::EnumerationResult m_eAsyncActionResult;
+ bool m_bRunningAsyncAction;
+ bool m_bAsyncActionCancelled;
+
+
+public:
+
+ ::std::vector< SortingData_Impl* > maContent;
+ ::osl::Mutex maMutex;
+
+ ViewTabListBox_Impl* mpView;
+ NameTranslator_Impl* mpNameTrans;
+ const IUrlFilter* mpUrlFilter;
+ sal_uInt16 mnSortColumn;
+ sal_Bool mbAscending : 1;
+ sal_Bool mbOnlyFolder : 1;
+ sal_Bool mbReplaceNames : 1; // translate folder names or display doc-title instead of file name
+ sal_Int16 mnSuspendSelectCallback : 1;
+ sal_Bool mbIsFirstResort : 1;
+
+ IntlWrapper aIntlWrapper;
+
+ String maViewURL;
+ String maAllFilter;
+ String maCurrentFilter;
+ Image maFolderImage;
+ Link maOpenDoneLink;
+ Reference< XCommandEnvironment > mxCmdEnv;
+
+ SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > xEnv,
+ sal_Int16 nFlags,
+ sal_Bool bOnlyFolder );
+ virtual ~SvtFileView_Impl();
+
+ void Clear();
+
+ FileViewResult GetFolderContent_Impl(
+ const String& rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList = ::com::sun::star::uno::Sequence< ::rtl::OUString >() );
+
+ FileViewResult GetFolderContent_Impl(
+ const FolderDescriptor& _rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList = ::com::sun::star::uno::Sequence< ::rtl::OUString >());
+ void FilterFolderContent_Impl( const OUString &rFilter );
+ void CancelRunningAsyncAction();
+
+ void OpenFolder_Impl();
+ // #83004# -------
+ void ReplaceTabWithString( OUString& aValue );
+ void CreateDisplayText_Impl();
+ void CreateVector_Impl( const Sequence < OUString > &rList );
+ void SortFolderContent_Impl();
+
+ void EntryRemoved( const OUString& rURL );
+ void EntryRenamed( OUString& rURL,
+ const OUString& rName );
+ String FolderInserted( const OUString& rURL,
+ const OUString& rTitle );
+
+ ULONG GetEntryPos( const OUString& rURL );
+
+ inline void EnableContextMenu( sal_Bool bEnable );
+ inline void EnableDelete( sal_Bool bEnable );
+
+ void Resort_Impl( sal_Int16 nColumn, sal_Bool bAscending );
+ sal_Bool SearchNextEntry( sal_uInt32 &nIndex,
+ const OUString& rTitle,
+ sal_Bool bWrapAround );
+
+ inline sal_Bool EnableNameReplacing( sal_Bool bEnable = sal_True ); // returns false, if action wasn't possible
+ void SetActualFolder( const INetURLObject& rActualFolder );
+
+ sal_Bool GetDocTitle( const OUString& rTargetURL, OUString& rDocTitle ) const;
+
+ void SetSelectHandler( const Link& _rHdl );
+
+ void InitSelection();
+ void ResetCursor();
+
+ inline void EndEditing( bool _bCancel );
+
+protected:
+ DECL_LINK( SelectionMultiplexer, void* );
+
+protected:
+ // IEnumerationResultHandler overridables
+ virtual void enumerationDone( ::svt::EnumerationResult _eResult );
+ void implEnumerationSuccess();
+
+ // ITimeoutHandler
+ virtual void onTimeout( CallbackTimer* _pInstigator );
+};
+
+inline void SvtFileView_Impl::EnableContextMenu( sal_Bool bEnable )
+{
+ mpView->EnableContextMenuHandling( bEnable );
+ if( bEnable )
+ mbReplaceNames = sal_False;
+}
+
+inline void SvtFileView_Impl::EnableDelete( sal_Bool bEnable )
+{
+ mpView->EnableDelete( bEnable );
+ if( bEnable )
+ mbReplaceNames = sal_False;
+}
+
+inline sal_Bool SvtFileView_Impl::EnableNameReplacing( sal_Bool bEnable )
+{
+ mpView->EnableRename( bEnable );
+
+ sal_Bool bRet;
+ if( mpView->IsDeleteOrContextMenuEnabled() )
+ {
+ DBG_ASSERT( !mbReplaceNames, "SvtFileView_Impl::EnableNameReplacing(): state should be not possible!" );
+ bRet = !bEnable; // only for enabling this is an unsuccessful result
+ }
+ else
+ {
+ mbReplaceNames = bEnable;
+ bRet = sal_True;
+ }
+
+ return bRet;
+}
+
+inline void SvtFileView_Impl::EndEditing( bool _bCancel )
+{
+ if ( mpView->IsEditingActive() )
+ mpView->EndEditing( _bCancel != false );
+}
+
+// functions -------------------------------------------------------------
+
+OUString CreateExactSizeText_Impl( sal_Int64 nSize )
+{
+ double fSize( ( double ) nSize );
+ int nDec;
+
+ long nMega = 1024 * 1024;
+ long nGiga = nMega * 1024;
+
+ String aUnitStr = ' ';
+
+ if ( nSize < 10000 )
+ {
+ aUnitStr += String( SvtResId( STR_SVT_BYTES ) );
+ nDec = 0;
+ }
+ else if ( nSize < nMega )
+ {
+ fSize /= 1024;
+ aUnitStr += String( SvtResId( STR_SVT_KB ) );
+ nDec = 1;
+ }
+ else if ( nSize < nGiga )
+ {
+ fSize /= nMega;
+ aUnitStr += String( SvtResId( STR_SVT_MB ) );
+ nDec = 2;
+ }
+ else
+ {
+ fSize /= nGiga;
+ aUnitStr += String( SvtResId( STR_SVT_GB ) );
+ nDec = 3;
+ }
+
+ OUString aSizeStr( ::rtl::math::doubleToUString( fSize,
+ rtl_math_StringFormat_F, nDec,
+ SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0)));
+ aSizeStr += aUnitStr;
+
+ return aSizeStr;
+}
+
+// -----------------------------------------------------------------------
+// class ViewTabListBox_Impl ---------------------------------------------
+// -----------------------------------------------------------------------
+
+ViewTabListBox_Impl::ViewTabListBox_Impl( Window* pParentWin,
+ SvtFileView_Impl* pParent,
+ sal_Int16 nFlags ) :
+
+ SvHeaderTabListBox( pParentWin, WB_TABSTOP ),
+
+ mpHeaderBar ( NULL ),
+ mpParent ( pParent ),
+ msAccessibleDescText( SvtResId( STR_SVT_ACC_DESC_FILEVIEW ) ),
+ msFolder ( SvtResId( STR_SVT_ACC_DESC_FOLDER ) ),
+ msFile ( SvtResId( STR_SVT_ACC_DESC_FILE ) ),
+ mnSearchIndex ( 0 ),
+ mbResizeDisabled ( sal_False ),
+ mbAutoResize ( sal_False ),
+ mbEnableDelete ( sal_True ),
+ mbEnableRename ( sal_True )
+
+{
+ Size aBoxSize = pParentWin->GetSizePixel();
+ mpHeaderBar = new HeaderBar( pParentWin, WB_BUTTONSTYLE | WB_BOTTOMBORDER );
+ mpHeaderBar->SetPosSizePixel( Point( 0, 0 ), mpHeaderBar->CalcWindowSizePixel() );
+
+ HeaderBarItemBits nBits = ( HIB_LEFT | HIB_VCENTER | HIB_CLICKABLE );
+ if ( ( nFlags & FILEVIEW_SHOW_ALL ) == FILEVIEW_SHOW_ALL )
+ {
+ mpHeaderBar->InsertItem( COLUMN_TITLE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_TITLE ) ), 180, nBits | HIB_UPARROW );
+ mpHeaderBar->InsertItem( COLUMN_TYPE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_TYPE ) ), 140, nBits );
+ mpHeaderBar->InsertItem( COLUMN_SIZE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_SIZE ) ), 80, nBits );
+ mpHeaderBar->InsertItem( COLUMN_DATE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_DATE ) ), 500, nBits );
+ }
+ else
+ mpHeaderBar->InsertItem( COLUMN_TITLE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_TITLE ) ), 600, nBits );
+
+ Size aHeadSize = mpHeaderBar->GetSizePixel();
+ SetPosSizePixel( Point( 0, aHeadSize.Height() ),
+ Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) );
+ InitHeaderBar( mpHeaderBar );
+ SetHighlightRange();
+ SetEntryHeight( ROW_HEIGHT );
+
+ Show();
+ mpHeaderBar->Show();
+
+ maResetQuickSearch.SetTimeout( QUICK_SEARCH_TIMEOUT );
+ maResetQuickSearch.SetTimeoutHdl( LINK( this, ViewTabListBox_Impl, ResetQuickSearch_Impl ) );
+
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > (
+ xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY );
+
+ mxCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+
+ EnableContextMenuHandling();
+}
+
+// -----------------------------------------------------------------------
+
+ViewTabListBox_Impl::~ViewTabListBox_Impl()
+{
+ maResetQuickSearch.Stop();
+
+ delete mpHeaderBar;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ViewTabListBox_Impl, ResetQuickSearch_Impl, Timer*, EMPTYARG )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ maQuickSearchText = OUString();
+ mnSearchIndex = 0;
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ViewTabListBox_Impl::Resize()
+{
+ SvTabListBox::Resize();
+ Size aBoxSize = Control::GetParent()->GetOutputSizePixel();
+
+ if ( mbResizeDisabled || !aBoxSize.Width() )
+ return;
+
+ Size aBarSize = mpHeaderBar->GetSizePixel();
+ aBarSize.Width() = mbAutoResize ? aBoxSize.Width() : GetSizePixel().Width();
+ mpHeaderBar->SetSizePixel( aBarSize );
+
+ if ( mbAutoResize )
+ {
+ mbResizeDisabled = sal_True;
+ Point aPos = GetPosPixel();
+ SetPosSizePixel( Point( 0, aBarSize.Height() ),
+ Size( aBoxSize.Width(), aBoxSize.Height() - aBarSize.Height() ) );
+ mbResizeDisabled = sal_False;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ViewTabListBox_Impl::KeyInput( const KeyEvent& rKEvt )
+{
+ bool bHandled = false;
+
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ if ( 0 == rKeyCode.GetModifier() )
+ {
+ if ( rKeyCode.GetCode() == KEY_RETURN )
+ {
+ ResetQuickSearch_Impl( NULL );
+ GetDoubleClickHdl().Call( this );
+ bHandled = true;
+ }
+ else if ( ( rKeyCode.GetCode() == KEY_DELETE ) &&
+ mbEnableDelete )
+ {
+ ResetQuickSearch_Impl( NULL );
+ DeleteEntries();
+ bHandled = true;
+ }
+ else if ( ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_NUM ) ||
+ ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_ALPHA ) )
+ {
+ DoQuickSearch( rKEvt.GetCharCode() );
+ bHandled = true;
+ }
+ }
+
+ if ( !bHandled )
+ {
+ ResetQuickSearch_Impl( NULL );
+ SvHeaderTabListBox::KeyInput( rKEvt );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+PopupMenu* ViewTabListBox_Impl::CreateContextMenu( void )
+{
+ bool bEnableDelete = mbEnableDelete;
+ bool bEnableRename = mbEnableRename;
+
+ if ( bEnableDelete || bEnableRename )
+ {
+ sal_Int32 nSelectedEntries = GetSelectionCount();
+ bEnableDelete &= nSelectedEntries > 0;
+ bEnableRename &= nSelectedEntries == 1;
+ }
+
+ if ( bEnableDelete || bEnableRename )
+ {
+ SvLBoxEntry* pEntry = FirstSelected();
+ while ( pEntry )
+ {
+ ::ucbhelper::Content aCnt;
+ try
+ {
+ OUString aURL( static_cast< SvtContentEntry * >(
+ pEntry->GetUserData() )->maURL );
+ aCnt = ::ucbhelper::Content( aURL, mxCmdEnv );
+ }
+ catch( Exception const & )
+ {
+ bEnableDelete = bEnableRename = false;
+ }
+
+ if ( bEnableDelete )
+ {
+ try
+ {
+ Reference< XCommandInfo > aCommands = aCnt.getCommands();
+ if ( aCommands.is() )
+ bEnableDelete
+ = aCommands->hasCommandByName(
+ OUString::createFromAscii( "delete" ) );
+ else
+ bEnableDelete = false;
+ }
+ catch( Exception const & )
+ {
+ bEnableDelete = false;
+ }
+ }
+
+ if ( bEnableRename )
+ {
+ try
+ {
+ Reference< XPropertySetInfo > aProps = aCnt.getProperties();
+ if ( aProps.is() )
+ {
+ Property aProp
+ = aProps->getPropertyByName(
+ OUString::createFromAscii( "Title" ) );
+ bEnableRename
+ = !( aProp.Attributes & PropertyAttribute::READONLY );
+ }
+ else
+ bEnableRename = false;
+ }
+ catch( Exception const & )
+ {
+ bEnableRename = false;
+ }
+ }
+
+ pEntry = ( bEnableDelete || bEnableRename )
+ ? NextSelected( pEntry )
+ : 0;
+ }
+ }
+
+ if ( bEnableDelete || bEnableRename )
+ {
+ PopupMenu * pRet
+ = new PopupMenu( SvtResId( RID_FILEVIEW_CONTEXTMENU ) );
+ pRet->EnableItem( MID_FILEVIEW_DELETE, bEnableDelete );
+ pRet->EnableItem( MID_FILEVIEW_RENAME, bEnableRename );
+ pRet->RemoveDisabledEntries( sal_True, sal_True );
+ return pRet;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ViewTabListBox_Impl::ExcecuteContextMenuAction( USHORT nSelectedPopupEntry )
+{
+ switch ( nSelectedPopupEntry )
+ {
+ case MID_FILEVIEW_DELETE :
+ DeleteEntries();
+ break;
+
+ case MID_FILEVIEW_RENAME :
+ EditEntry( FirstSelected() );
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ViewTabListBox_Impl::ClearAll()
+{
+ for ( USHORT i = 0; i < GetEntryCount(); ++i )
+ delete (SvtContentEntry*)GetEntry(i)->GetUserData();
+ Clear();
+}
+
+// -----------------------------------------------------------------------
+void ViewTabListBox_Impl::DeleteEntries()
+{
+ svtools::QueryDeleteResult_Impl eResult = svtools::QUERYDELETE_YES;
+ SvLBoxEntry* pEntry = FirstSelected();
+ String aURL;
+
+ ByteString sDialogPosition;
+ while ( pEntry && ( eResult != svtools::QUERYDELETE_CANCEL ) )
+ {
+ SvLBoxEntry *pCurEntry = pEntry;
+ pEntry = NextSelected( pEntry );
+
+ if ( pCurEntry->GetUserData() )
+ aURL = ( (SvtContentEntry*)pCurEntry->GetUserData() )->maURL;
+
+ if ( !aURL.Len() )
+ continue;
+
+ bool canDelete = true;
+ try
+ {
+ ::ucbhelper::Content aCnt( aURL, mxCmdEnv );
+ Reference< XCommandInfo > aCommands = aCnt.getCommands();
+ if ( aCommands.is() )
+ canDelete
+ = aCommands->hasCommandByName(
+ OUString::createFromAscii( "delete" ) );
+ else
+ canDelete = false;
+ }
+ catch( Exception const & )
+ {
+ canDelete = false;
+ }
+
+ if (!canDelete)
+ continue; // process next entry
+
+ if ( eResult != svtools::QUERYDELETE_ALL )
+ {
+ INetURLObject aObj( aURL );
+ svtools::QueryDeleteDlg_Impl aDlg( NULL, aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) );
+ if ( sDialogPosition.Len() )
+ aDlg.SetWindowState( sDialogPosition );
+
+ if ( GetSelectionCount() > 1 )
+ aDlg.EnableAllButton();
+
+ if ( aDlg.Execute() == RET_OK )
+ eResult = aDlg.GetResult();
+ else
+ eResult = svtools::QUERYDELETE_CANCEL;
+
+ sDialogPosition = aDlg.GetWindowState( );
+ }
+
+ if ( ( eResult == svtools::QUERYDELETE_ALL ) ||
+ ( eResult == svtools::QUERYDELETE_YES ) )
+ {
+ if ( Kill( aURL ) )
+ {
+ delete (SvtContentEntry*)pCurEntry->GetUserData();
+ GetModel()->Remove( pCurEntry );
+ mpParent->EntryRemoved( aURL );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+BOOL ViewTabListBox_Impl::EditedEntry( SvLBoxEntry* pEntry,
+ const XubString& rNewText )
+{
+ BOOL bRet = FALSE;
+
+ OUString aURL;
+ SvtContentEntry* pData = (SvtContentEntry*)pEntry->GetUserData();
+
+ if ( pData )
+ aURL = OUString( pData->maURL );
+
+ if ( ! aURL.getLength() )
+ return bRet;
+
+ try
+ {
+ OUString aPropName = OUString::createFromAscii( "Title" );
+ bool canRename = true;
+ ::ucbhelper::Content aContent( aURL, mxCmdEnv );
+
+ try
+ {
+ Reference< XPropertySetInfo > aProps = aContent.getProperties();
+ if ( aProps.is() )
+ {
+ Property aProp = aProps->getPropertyByName( aPropName );
+ canRename = !( aProp.Attributes & PropertyAttribute::READONLY );
+ }
+ else
+ {
+ canRename = false;
+ }
+ }
+ catch ( Exception const & )
+ {
+ canRename = false;
+ }
+
+ if ( canRename )
+ {
+ Any aValue;
+ aValue <<= OUString( rNewText );
+ aContent.setPropertyValue( aPropName, aValue );
+ mpParent->EntryRenamed( aURL, rNewText );
+
+ pData->maURL = aURL;
+ pEntry->SetUserData( pData );
+
+ bRet = TRUE;
+ }
+ }
+ catch( Exception const & )
+ {
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+void ViewTabListBox_Impl::DoQuickSearch( const xub_Unicode& rChar )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ maResetQuickSearch.Stop();
+
+ OUString aLastText = maQuickSearchText;
+ sal_uInt32 aLastPos = mnSearchIndex;
+ sal_Bool bFound = sal_False;
+
+ maQuickSearchText += OUString( String( rChar ) ).toAsciiLowerCase();
+
+ bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, sal_False );
+
+ if ( !bFound && ( aLastText.getLength() == 1 ) &&
+ ( aLastText == OUString( String( rChar ) ) ) )
+ {
+ mnSearchIndex = aLastPos + 1;
+ maQuickSearchText = aLastText;
+ bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, sal_True );
+ }
+
+ if ( bFound )
+ {
+ SvLBoxEntry* pEntry = GetEntry( mnSearchIndex );
+ if ( pEntry )
+ {
+ SelectAll( FALSE );
+ Select( pEntry );
+ SetCurEntry( pEntry );
+ MakeVisible( pEntry );
+ }
+ else
+ bFound = sal_False;
+ }
+
+ if ( !bFound )
+ Sound::Beep();
+
+ maResetQuickSearch.Start();
+}
+
+// -----------------------------------------------------------------------
+BOOL ViewTabListBox_Impl::DoubleClickHdl()
+{
+ SvHeaderTabListBox::DoubleClickHdl();
+ return FALSE;
+ // this means "do no additional handling". Especially this means that the SvImpLBox does not
+ // recognize that the entry at the double click position change after the handler call (which is
+ // the case if in the handler, our content was replaced)
+ // If it _would_ recognize this change, it would take this as a reason to select the entry, again
+ // - which is not what in the case of content replace
+ // (I really doubt that this behaviour of the SvImpLBox does make any sense at all, but
+ // who knows ...)
+ // 07.12.2001 - 95727 - fs@openoffice.org
+}
+
+::rtl::OUString ViewTabListBox_Impl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
+{
+ ::rtl::OUString sRet = SvHeaderTabListBox::GetAccessibleObjectDescription( _eType, _nPos );
+ if ( ::svt::BBTYPE_TABLECELL == _eType )
+ {
+ sal_Int32 nRow = -1;
+ const sal_uInt16 nColumnCount = GetColumnCount();
+ if (nColumnCount > 0)
+ nRow = _nPos / nColumnCount;
+ SvLBoxEntry* pEntry = GetEntry( nRow );
+ if ( pEntry )
+ {
+ SvtContentEntry* pData = (SvtContentEntry*)pEntry->GetUserData();
+ if ( pData )
+ {
+ static const String sVar1( RTL_CONSTASCII_USTRINGPARAM( "%1" ) );
+ static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) );
+ String aText( msAccessibleDescText );
+ aText.SearchAndReplace( sVar1, pData->mbIsFolder ? msFolder : msFile );
+ aText.SearchAndReplace( sVar2, pData->maURL );
+ sRet += ::rtl::OUString( aText );
+ }
+ }
+ }
+
+ return sRet;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool ViewTabListBox_Impl::Kill( const OUString& rContent )
+{
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ ::ucbhelper::Content aCnt( rContent, mxCmdEnv );
+ aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException const & )
+ {
+ DBG_WARNING( "CommandAbortedException" );
+ bRet = sal_False;
+ }
+ catch( Exception const & )
+ {
+ DBG_WARNING( "Any other exception" );
+ bRet = sal_False;
+ }
+
+ return bRet;
+}
+
+
+
+
+// -----------------------------------------------------------------------
+// class SvtFileView -----------------------------------------------------
+// -----------------------------------------------------------------------
+
+SvtFileView::SvtFileView( Window* pParent, const ResId& rResId,
+ sal_Bool bOnlyFolder, sal_Bool bMultiSelection ) :
+
+ Control( pParent, rResId )
+{
+ sal_Int8 nFlags = FILEVIEW_SHOW_ALL;
+ if ( bOnlyFolder )
+ nFlags |= FILEVIEW_ONLYFOLDER;
+ if ( bMultiSelection )
+ nFlags |= FILEVIEW_MULTISELECTION;
+
+ Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > (
+ ::comphelper::getProcessServiceFactory()->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY );
+ Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+
+ mpImp = new SvtFileView_Impl( this, xCmdEnv, nFlags, bOnlyFolder );
+ mpImp->mpView->ForbidEmptyText();
+
+ long pTabs[] = { 5, 20, 180, 320, 400, 600 };
+ mpImp->mpView->SetTabs( &pTabs[0], MAP_PIXEL );
+ mpImp->mpView->SetTabJustify( 2, AdjustRight ); // column "Size"
+
+ if ( bMultiSelection )
+ mpImp->mpView->SetSelectionMode( MULTIPLE_SELECTION );
+
+ HeaderBar* pHeaderBar = mpImp->mpView->GetHeaderBar();
+ pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) );
+ pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) );
+}
+
+SvtFileView::SvtFileView( Window* pParent, const ResId& rResId, sal_Int8 nFlags ) :
+
+ Control( pParent, rResId )
+{
+ Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > (
+ ::comphelper::getProcessServiceFactory()->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY );
+ Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+ mpImp = new SvtFileView_Impl( this, xCmdEnv, nFlags,
+ ( nFlags & FILEVIEW_ONLYFOLDER ) == FILEVIEW_ONLYFOLDER );
+
+ if ( ( nFlags & FILEVIEW_SHOW_ALL ) == FILEVIEW_SHOW_ALL )
+ {
+ long pTabs[] = { 5, 20, 180, 320, 400, 600 };
+ mpImp->mpView->SetTabs( &pTabs[0], MAP_PIXEL );
+ mpImp->mpView->SetTabJustify( 2, AdjustRight ); // column "Size"
+ }
+ else
+ {
+ // show only title
+ long pTabs[] = { 2, 20, 600 };
+ mpImp->mpView->SetTabs( &pTabs[0], MAP_PIXEL );
+ }
+
+ if ( ( nFlags & FILEVIEW_MULTISELECTION ) == FILEVIEW_MULTISELECTION )
+ mpImp->mpView->SetSelectionMode( MULTIPLE_SELECTION );
+
+ HeaderBar *pHeaderBar = mpImp->mpView->GetHeaderBar();
+ pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) );
+ pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) );
+}
+
+// -----------------------------------------------------------------------
+
+SvtFileView::~SvtFileView()
+{
+ // use temp pointer to prevent access of deleted member (GetFocus())
+ SvtFileView_Impl* pTemp = mpImp;
+ mpImp = NULL;
+ delete pTemp;
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::OpenFolder( const Sequence< OUString >& aContents )
+{
+ mpImp->mpView->ClearAll();
+ const OUString* pFileProperties = aContents.getConstArray();
+ UINT32 i, nCount = aContents.getLength();
+ for ( i = 0; i < nCount; ++i )
+ {
+ String aRow( pFileProperties[i] );
+ // extract columns
+ // the columns are: title, type, size, date, target url, is folder, image url
+ String aTitle, aType, aSize, aDate, aURL, aImageURL;
+ xub_StrLen nIdx = 0;
+ aTitle = aRow.GetToken( 0, '\t', nIdx );
+ aType = aRow.GetToken( 0, '\t', nIdx );
+ aSize = aRow.GetToken( 0, '\t', nIdx );
+ aDate = aRow.GetToken( 0, '\t', nIdx );
+ aURL = aRow.GetToken( 0, '\t', nIdx );
+ sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0);
+ sal_Bool bIsFolder = ( '1' == cFolder );
+ if ( nIdx != STRING_NOTFOUND )
+ aImageURL = aRow.GetToken( 0, '\t', nIdx );
+
+ if ( mpImp->mbOnlyFolder && !bIsFolder )
+ continue;
+
+ // build new row
+ String aNewRow = aTitle;
+ aNewRow += '\t';
+ aNewRow += aType;
+ aNewRow += '\t';
+ aNewRow += aSize;
+ aNewRow += '\t';
+ aNewRow += aDate;
+ // detect image
+ sal_Bool bDoInsert = sal_True;
+ INetURLObject aObj( aImageURL.Len() > 0 ? aImageURL : aURL );
+ Image aImage = SvFileInformationManager::GetImage( aObj, FALSE, isHighContrast( this ) );
+
+ if ( bDoInsert )
+ {
+ // insert entry and set user data
+ SvLBoxEntry* pEntry = mpImp->mpView->InsertEntry( aNewRow, aImage, aImage, NULL );
+ SvtContentEntry* pUserData = new SvtContentEntry( aURL, bIsFolder );
+ pEntry->SetUserData( pUserData );
+ }
+ }
+
+ mpImp->InitSelection();
+ mpImp->ResetCursor();
+}
+
+// -----------------------------------------------------------------------
+
+String SvtFileView::GetURL( SvLBoxEntry* pEntry ) const
+{
+ String aURL;
+ if ( pEntry && pEntry->GetUserData() )
+ aURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL;
+ return aURL;
+}
+
+// -----------------------------------------------------------------------
+
+String SvtFileView::GetCurrentURL() const
+{
+ String aURL;
+ SvLBoxEntry* pEntry = mpImp->mpView->FirstSelected();
+ if ( pEntry && pEntry->GetUserData() )
+ aURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL;
+ return aURL;
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool SvtFileView::CreateNewFolder( const String& rNewFolder )
+{
+ sal_Bool bRet = sal_False;
+ INetURLObject aObj( mpImp->maViewURL );
+ aObj.insertName( rNewFolder, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
+ String sURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ if ( ::utl::UCBContentHelper::MakeFolder( sURL, sal_True ) )
+ {
+ String sTitle = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ String sEntry = mpImp->FolderInserted( sURL, sTitle );
+ SvLBoxEntry* pEntry = mpImp->mpView->InsertEntry( sEntry, mpImp->maFolderImage, mpImp->maFolderImage );
+ SvtContentEntry* pUserData = new SvtContentEntry( sURL, TRUE );
+ pEntry->SetUserData( pUserData );
+ mpImp->mpView->MakeVisible( pEntry );
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+FileViewResult SvtFileView::PreviousLevel( const FileViewAsyncAction* pAsyncDescriptor )
+{
+ FileViewResult eResult = eFailure;
+
+ String sParentURL;
+ if ( GetParentURL( sParentURL ) )
+ eResult = Initialize( sParentURL, mpImp->maCurrentFilter, pAsyncDescriptor, mpBlackList );
+
+ return eResult;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvtFileView::GetParentURL( String& rParentURL ) const
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ ::ucbhelper::Content aCnt( mpImp->maViewURL, mpImp->mxCmdEnv );
+ Reference< XContent > xContent( aCnt.get() );
+ Reference< com::sun::star::container::XChild > xChild( xContent, UNO_QUERY );
+ if ( xChild.is() )
+ {
+ Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
+ if ( xParent.is() )
+ {
+ rParentURL = String( xParent->getIdentifier()->getContentIdentifier() );
+ bRet = ( rParentURL.Len() > 0 && rParentURL != mpImp->maViewURL );
+ }
+ }
+ }
+ catch( Exception const & )
+ {
+ // perhaps an unkown url protocol (e.g. "private:newdoc")
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 SvtFileView::GetHelpId( ) const
+{
+ return mpImp->mpView->GetHelpId( );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetHelpId( sal_uInt32 nHelpId )
+{
+ mpImp->mpView->SetHelpId( nHelpId );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetSizePixel( const Size& rNewSize )
+{
+ Control::SetSizePixel( rNewSize );
+ mpImp->mpView->SetSizePixel( rNewSize );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
+{
+ SetPosPixel( rNewPos );
+ SetSizePixel( rNewSize );
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool SvtFileView::Initialize( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent>& _xContent, const String& rFilter )
+{
+ WaitObject aWaitCursor( this );
+
+ mpImp->Clear();
+ ::ucbhelper::Content aContent(_xContent, mpImp->mxCmdEnv );
+ FileViewResult eResult = mpImp->GetFolderContent_Impl( FolderDescriptor( aContent ), NULL );
+ OSL_ENSURE( eResult != eStillRunning, "SvtFileView::Initialize: this was expected to be synchronous!" );
+ if ( eResult != eSuccess )
+ return sal_False;
+
+ mpImp->FilterFolderContent_Impl( rFilter );
+
+ mpImp->SortFolderContent_Impl(); // possibly not necessary!!!!!!!!!!
+ mpImp->CreateDisplayText_Impl();
+ mpImp->OpenFolder_Impl();
+
+ mpImp->maOpenDoneLink.Call( this );
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+FileViewResult SvtFileView::Initialize(
+ const String& rURL,
+ const String& rFilter,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
+{
+ WaitObject aWaitCursor( this );
+ mpBlackList = rBlackList;
+
+ String sPushURL( mpImp->maViewURL );
+
+ mpImp->maViewURL = rURL;
+ FileViewResult eResult = ExecuteFilter( rFilter, pAsyncDescriptor );
+ switch ( eResult )
+ {
+ case eFailure:
+ case eTimeout:
+ mpImp->maViewURL = sPushURL;
+ return eResult;
+
+ case eStillRunning:
+ OSL_ENSURE( pAsyncDescriptor, "SvtFileView::Initialize: we told it to read synchronously!" );
+ case eSuccess:
+ return eResult;
+ }
+
+ OSL_ENSURE( sal_False, "SvtFileView::Initialize: unreachable!" );
+ return eFailure;
+}
+
+// -----------------------------------------------------------------------
+FileViewResult SvtFileView::Initialize(
+ const String& rURL,
+ const String& rFilter,
+ const FileViewAsyncAction* pAsyncDescriptor )
+{
+ return Initialize( rURL, rFilter, pAsyncDescriptor, ::com::sun::star::uno::Sequence< ::rtl::OUString >());
+}
+
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+sal_Bool SvtFileView::Initialize( const Sequence< OUString >& aContents )
+{
+ WaitObject aWaitCursor( this );
+
+ mpImp->maViewURL = String();
+ mpImp->maCurrentFilter = mpImp->maAllFilter;
+
+ mpImp->Clear();
+ mpImp->CreateVector_Impl( aContents );
+ mpImp->SortFolderContent_Impl();
+
+ mpImp->OpenFolder_Impl();
+
+ mpImp->maOpenDoneLink.Call( this );
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+FileViewResult SvtFileView::ExecuteFilter( const String& rFilter, const FileViewAsyncAction* pAsyncDescriptor )
+{
+ mpImp->maCurrentFilter = rFilter;
+ mpImp->maCurrentFilter.ToLowerAscii();
+
+ mpImp->Clear();
+ FileViewResult eResult = mpImp->GetFolderContent_Impl( mpImp->maViewURL, pAsyncDescriptor, mpBlackList );
+ OSL_ENSURE( ( eResult != eStillRunning ) || pAsyncDescriptor, "SvtFileView::ExecuteFilter: we told it to read synchronously!" );
+ return eResult;
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::CancelRunningAsyncAction()
+{
+ mpImp->CancelRunningAsyncAction();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetNoSelection()
+{
+ mpImp->mpView->SelectAll( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::GetFocus()
+{
+ Control::GetFocus();
+ if ( mpImp && mpImp->mpView )
+ mpImp->mpView->GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::ResetCursor()
+{
+ mpImp->ResetCursor();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetSelectHdl( const Link& rHdl )
+{
+ mpImp->SetSelectHandler( rHdl );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetDoubleClickHdl( const Link& rHdl )
+{
+ mpImp->mpView->SetDoubleClickHdl( rHdl );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SvtFileView::GetSelectionCount() const
+{
+ return mpImp->mpView->GetSelectionCount();
+}
+
+// -----------------------------------------------------------------------
+
+SvLBoxEntry* SvtFileView::FirstSelected() const
+{
+ return mpImp->mpView->FirstSelected();
+}
+
+// -----------------------------------------------------------------------
+
+SvLBoxEntry* SvtFileView::NextSelected( SvLBoxEntry* pEntry ) const
+{
+ return mpImp->mpView->NextSelected( pEntry );
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::EnableAutoResize()
+{
+ mpImp->mpView->EnableAutoResize();
+}
+
+// -----------------------------------------------------------------------
+
+void SvtFileView::SetFocus()
+{
+ mpImp->mpView->GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+const String& SvtFileView::GetViewURL() const
+{
+ return mpImp->maViewURL;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::SetOpenDoneHdl( const Link& rHdl )
+{
+ mpImp->maOpenDoneLink = rHdl;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::EnableContextMenu( sal_Bool bEnable )
+{
+ mpImp->EnableContextMenu( bEnable );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::EnableDelete( sal_Bool bEnable )
+{
+ mpImp->EnableDelete( bEnable );
+}
+
+void SvtFileView::EnableNameReplacing( sal_Bool bEnable )
+{
+ mpImp->EnableNameReplacing( bEnable );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::EndInplaceEditing( bool _bCancel )
+{
+ return mpImp->EndEditing( _bCancel );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvtFileView, HeaderSelect_Impl, HeaderBar*, pBar )
+{
+ DBG_ASSERT( pBar, "no headerbar" );
+ USHORT nItemID = pBar->GetCurItemId();
+
+ HeaderBarItemBits nBits;
+
+ // clear the arrow of the recently used column
+ if ( nItemID != mpImp->mnSortColumn )
+ {
+ if ( !nItemID )
+ {
+ // first call -> remove arrow from title column,
+ // because another column is the sort column
+ nItemID = mpImp->mnSortColumn;
+ mpImp->mnSortColumn = COLUMN_TITLE;
+ }
+ nBits = pBar->GetItemBits( mpImp->mnSortColumn );
+ nBits &= ~( HIB_UPARROW | HIB_DOWNARROW );
+ pBar->SetItemBits( mpImp->mnSortColumn, nBits );
+ }
+
+ nBits = pBar->GetItemBits( nItemID );
+
+ BOOL bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
+
+ if ( bUp )
+ {
+ nBits &= ~HIB_UPARROW;
+ nBits |= HIB_DOWNARROW;
+ }
+ else
+ {
+ nBits &= ~HIB_DOWNARROW;
+ nBits |= HIB_UPARROW;
+ }
+
+ pBar->SetItemBits( nItemID, nBits );
+ mpImp->Resort_Impl( nItemID, !bUp );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvtFileView, HeaderEndDrag_Impl, HeaderBar*, pBar )
+{
+ if ( !pBar->IsItemMode() )
+ {
+ Size aSize;
+ USHORT nTabs = pBar->GetItemCount();
+ long nTmpSize = 0;
+
+ for ( USHORT i = 1; i <= nTabs; ++i )
+ {
+ long nWidth = pBar->GetItemSize(i);
+ aSize.Width() = nWidth + nTmpSize;
+ nTmpSize += nWidth;
+ mpImp->mpView->SetTab( i, aSize.Width(), MAP_PIXEL );
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+String SvtFileView::GetConfigString() const
+{
+ String sRet;
+ HeaderBar* pBar = mpImp->mpView->GetHeaderBar();
+ DBG_ASSERT( pBar, "invalid headerbar" );
+
+ // sort order
+ sRet += String::CreateFromInt32( mpImp->mnSortColumn );
+ sRet += ';';
+ HeaderBarItemBits nBits = pBar->GetItemBits( mpImp->mnSortColumn );
+ BOOL bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
+ sRet += bUp ? '1' : '0';
+ sRet += ';';
+
+ USHORT nCount = pBar->GetItemCount();
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ USHORT nId = pBar->GetItemId(i);
+ sRet += String::CreateFromInt32( nId );
+ sRet += ';';
+ sRet += String::CreateFromInt32( pBar->GetItemSize( nId ) );
+ sRet += ';';
+ }
+
+ sRet.EraseTrailingChars( ';' );
+ return sRet;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::SetConfigString( const String& rCfgStr )
+{
+ HeaderBar* pBar = mpImp->mpView->GetHeaderBar();
+ DBG_ASSERT( pBar, "invalid headerbar" );
+
+ USHORT nIdx = 0;
+ mpImp->mnSortColumn = (USHORT)rCfgStr.GetToken( 0, ';', nIdx ).ToInt32();
+ BOOL bUp = (BOOL)(USHORT)rCfgStr.GetToken( 0, ';', nIdx ).ToInt32();
+ HeaderBarItemBits nBits = pBar->GetItemBits( mpImp->mnSortColumn );
+
+ if ( bUp )
+ {
+ nBits &= ~HIB_UPARROW;
+ nBits |= HIB_DOWNARROW;
+ }
+ else
+ {
+ nBits &= ~HIB_DOWNARROW;
+ nBits |= HIB_UPARROW;
+ }
+ pBar->SetItemBits( mpImp->mnSortColumn, nBits );
+
+ while ( nIdx != STRING_NOTFOUND )
+ {
+ USHORT nItemId = (USHORT)rCfgStr.GetToken( 0, ';', nIdx ).ToInt32();
+ pBar->SetItemSize( nItemId, rCfgStr.GetToken( 0, ';', nIdx ).ToInt32() );
+ }
+
+ HeaderSelect_Impl( pBar );
+ HeaderEndDrag_Impl( pBar );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::SetUrlFilter( const IUrlFilter* _pFilter )
+{
+ mpImp->mpUrlFilter = _pFilter;
+}
+
+// -----------------------------------------------------------------------
+const IUrlFilter* SvtFileView::GetUrlFilter( ) const
+{
+ return mpImp->mpUrlFilter;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView::StateChanged( StateChangedType nStateChange )
+{
+ if ( nStateChange == STATE_CHANGE_ENABLE )
+ Invalidate();
+ Control::StateChanged( nStateChange );
+}
+
+// -----------------------------------------------------------------------
+// class NameTranslator_Impl
+// -----------------------------------------------------------------------
+
+NameTranslator_Impl::NameTranslator_Impl( void ) :
+ mpActFolder( NULL )
+{
+}
+
+NameTranslator_Impl::NameTranslator_Impl( const INetURLObject& rActualFolder )
+{
+ mpActFolder = new NameTranslationList( rActualFolder );
+}
+
+NameTranslator_Impl::~NameTranslator_Impl()
+{
+ if( mpActFolder )
+ delete mpActFolder;
+}
+
+void NameTranslator_Impl::UpdateTranslationTable()
+{
+ if( mpActFolder )
+ mpActFolder->Update();
+}
+
+void NameTranslator_Impl::SetActualFolder( const INetURLObject& rActualFolder )
+{
+ HashedEntry aActFolder( rActualFolder );
+
+ if( mpActFolder )
+ {
+ if( *mpActFolder != aActFolder )
+ {
+ delete mpActFolder;
+ mpActFolder = new NameTranslationList( rActualFolder );
+ }
+ }
+ else
+ mpActFolder = new NameTranslationList( rActualFolder );
+}
+
+sal_Bool NameTranslator_Impl::GetTranslation( const OUString& rOrg, OUString& rTrans ) const
+{
+ sal_Bool bRet = sal_False;
+
+ if( mpActFolder )
+ {
+ const OUString* pTrans = mpActFolder->Translate( rOrg );
+ if( pTrans )
+ {
+ rTrans = *pTrans;
+ bRet = sal_True;
+ }
+ }
+
+ return bRet;
+}
+
+const String* NameTranslator_Impl::GetTransTableFileName() const
+{
+ return mpActFolder? &mpActFolder->GetTransTableFileName() : NULL;
+}
+
+// -----------------------------------------------------------------------
+// class SvtFileView_Impl
+// -----------------------------------------------------------------------
+
+SvtFileView_Impl::SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > xEnv, sal_Int16 nFlags, sal_Bool bOnlyFolder )
+
+ :mpAntiImpl ( pAntiImpl )
+ ,m_eAsyncActionResult ( ::svt::ERROR )
+ ,m_bRunningAsyncAction ( false )
+ ,m_bAsyncActionCancelled ( false )
+ ,mpNameTrans ( NULL )
+ ,mpUrlFilter ( NULL )
+ ,mnSortColumn ( COLUMN_TITLE )
+ ,mbAscending ( sal_True )
+ ,mbOnlyFolder ( bOnlyFolder )
+ ,mbReplaceNames ( sal_False )
+ ,mnSuspendSelectCallback ( 0 )
+ ,mbIsFirstResort ( sal_True )
+ ,aIntlWrapper ( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() )
+ ,maFolderImage ( SvtResId( IMG_SVT_FOLDER ) )
+ ,mxCmdEnv ( xEnv )
+
+{
+ maAllFilter = String::CreateFromAscii( "*.*" );
+ mpView = new ViewTabListBox_Impl( mpAntiImpl, this, nFlags );
+ mpView->EnableCellFocus();
+}
+
+// -----------------------------------------------------------------------
+SvtFileView_Impl::~SvtFileView_Impl()
+{
+ Clear();
+
+ // use temp pointer to prevent access of deleted member (GetFocus())
+ ViewTabListBox_Impl* pTemp = mpView;
+ mpView = NULL;
+ delete pTemp;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::Clear()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ std::vector< SortingData_Impl* >::iterator aIt;
+
+ for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ )
+ delete (*aIt);
+
+ maContent.clear();
+
+ if( mpNameTrans )
+ DELETEZ( mpNameTrans );
+}
+
+// -----------------------------------------------------------------------
+FileViewResult SvtFileView_Impl::GetFolderContent_Impl(
+ const String& rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
+{
+ ::osl::ClearableMutexGuard aGuard( maMutex );
+ INetURLObject aFolderObj( rFolder );
+ DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+
+ // prepare name translation
+ SetActualFolder( aFolderObj );
+
+ FolderDescriptor aFolder( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ aGuard.clear();
+ return GetFolderContent_Impl( aFolder, pAsyncDescriptor, rBlackList );
+}
+
+// -----------------------------------------------------------------------
+FileViewResult SvtFileView_Impl::GetFolderContent_Impl(
+ const FolderDescriptor& _rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
+{
+ DBG_TESTSOLARMUTEX();
+ ::osl::ClearableMutexGuard aGuard( maMutex );
+
+ OSL_ENSURE( !m_pContentEnumerator.is(), "SvtFileView_Impl::GetFolderContent_Impl: still running another enumeration!" );
+ m_pContentEnumerator = new ::svt::FileViewContentEnumerator(
+ mpView->GetCommandEnvironment(), maContent, maMutex, mbReplaceNames ? mpNameTrans : NULL );
+ // TODO: should we cache and re-use this thread?
+
+ if ( !pAsyncDescriptor )
+ {
+ ::svt::EnumerationResult eResult = m_pContentEnumerator->enumerateFolderContentSync( _rFolder, mpUrlFilter, rBlackList );
+ if ( ::svt::SUCCESS == eResult )
+ {
+ implEnumerationSuccess();
+ m_pContentEnumerator = NULL;
+ return eSuccess;
+ }
+ m_pContentEnumerator = NULL;
+ return eFailure;
+ }
+
+ m_bRunningAsyncAction = true;
+ m_bAsyncActionCancelled = false;
+ m_eAsyncActionResult = ::svt::ERROR;
+ m_aAsyncActionFinished.reset();
+
+ // don't (yet) set m_aCurrentAsyncActionHandler to pTimeout->aFinishHandler.
+ // By definition, this handler *only* get's called when the result cannot be obtained
+ // during the minimum wait time, so it is only set below, when needed.
+ m_aCurrentAsyncActionHandler = Link();
+
+ // minimum time to wait
+ ::std::auto_ptr< TimeValue > pTimeout( new TimeValue );
+ sal_Int32 nMinTimeout = pAsyncDescriptor->nMinTimeout;
+ OSL_ENSURE( nMinTimeout > 0, "SvtFileView_Impl::GetFolderContent_Impl: invalid minimum timeout!" );
+ if ( nMinTimeout <= 0 )
+ nMinTimeout = sal_Int32( 1000L );
+ pTimeout->Seconds = nMinTimeout / 1000L;
+ pTimeout->Nanosec = ( nMinTimeout % 1000L ) * 1000000L;
+
+ m_pContentEnumerator->enumerateFolderContent( _rFolder, mpUrlFilter, this );
+
+ // wait until the enumeration is finished
+ // for this, release our own mutex (which is used by the enumerator thread)
+ aGuard.clear();
+
+ ::osl::Condition::Result eResult = ::osl::Condition::result_ok;
+ {
+ // also release the SolarMutex. Not all code which is needed during the enumeration
+ // is Solar-Thread-Safe, in particular there is some code which needs to access
+ // string resources (and our resource system relies on the SolarMutex :()
+ ReleaseSolarMutex aSolarRelease;
+
+ // now wait. Note that if we didn't get an pAsyncDescriptor, then this is an infinite wait.
+ eResult = m_aAsyncActionFinished.wait( pTimeout.get() );
+ }
+
+ ::osl::MutexGuard aGuard2( maMutex );
+ if ( ::osl::Condition::result_timeout == eResult )
+ {
+ // maximum time to wait
+ OSL_ENSURE( !m_pCancelAsyncTimer.get(), "SvtFileView_Impl::GetFolderContent_Impl: there's still a previous timer!" );
+ m_pCancelAsyncTimer = new CallbackTimer( this );
+ sal_Int32 nMaxTimeout = pAsyncDescriptor->nMaxTimeout;
+ OSL_ENSURE( nMaxTimeout > nMinTimeout,
+ "SvtFileView_Impl::GetFolderContent_Impl: invalid maximum timeout!" );
+ if ( nMaxTimeout <= nMinTimeout )
+ nMaxTimeout = nMinTimeout + 5000;
+ m_pCancelAsyncTimer->setRemainingTime( TTimeValue( nMaxTimeout - nMinTimeout ) );
+ // we already waited for nMinTimeout milliseconds, so take this into account
+ m_pCancelAsyncTimer->start();
+
+ m_aCurrentAsyncActionHandler = pAsyncDescriptor->aFinishHandler;
+ DBG_ASSERT( m_aCurrentAsyncActionHandler.IsSet(), "SvtFileView_Impl::GetFolderContent_Impl: nobody interested when it's finished?" );
+ mpView->ClearAll();
+ return eStillRunning;
+ }
+
+ m_bRunningAsyncAction = false;
+ switch ( m_eAsyncActionResult )
+ {
+ case ::svt::SUCCESS:
+ return eSuccess;
+
+ case ::svt::ERROR:
+ return eFailure;
+
+ case ::svt::RUNNING:
+ return eStillRunning;
+ }
+
+ DBG_ERRORFILE( "SvtFileView_Impl::GetFolderContent_Impl: unreachable!" );
+ return eFailure;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::FilterFolderContent_Impl( const OUString &rFilter )
+{
+ sal_Bool bHideTransFile = mbReplaceNames && mpNameTrans;
+
+ String sHideEntry;
+ if( bHideTransFile )
+ {
+ const String* pTransTableFileName = mpNameTrans->GetTransTableFileName();
+ if( pTransTableFileName )
+ {
+ sHideEntry = *pTransTableFileName;
+ sHideEntry.ToUpperAscii();
+ }
+ else
+ bHideTransFile = sal_False;
+ }
+
+ if ( !bHideTransFile &&
+ ( !rFilter.getLength() || ( rFilter.compareToAscii( ALL_FILES_FILTER ) == COMPARE_EQUAL ) ) )
+ // when replacing names, there is always something to filter (no view of ".nametranslation.table")
+ return;
+
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( maContent.empty() )
+ return;
+
+ // count (estimate) the number of filter tokens
+ sal_Int32 nTokens=0;
+ const sal_Unicode* pStart = rFilter.getStr();
+ const sal_Unicode* pEnd = pStart + rFilter.getLength();
+ while ( pStart != pEnd )
+ if ( *pStart++ == ';' )
+ ++nTokens;
+
+ // collect the filter tokens
+ ::std::vector< WildCard > aFilters;
+ FilterMatch::createWildCardFilterList(rFilter,aFilters);
+
+
+ // do the filtering
+ ::std::vector< SortingData_Impl* >::iterator aContentLoop = maContent.begin();
+ String sCompareString;
+ do
+ {
+ if ( (*aContentLoop)->mbIsFolder )
+ ++aContentLoop;
+ else
+ {
+ // normalize the content title (we always match case-insensitive)
+ // 91872 - 11.09.2001 - frank.schoenheit@sun.com
+ sCompareString = (*aContentLoop)->GetFileName(); // filter works on file name, not on title!
+ sal_Bool bDelete;
+
+ if( bHideTransFile && sCompareString == sHideEntry )
+ bDelete = sal_True;
+ else
+ {
+ // search for the first filter which matches
+ ::std::vector< WildCard >::const_iterator pMatchingFilter =
+ ::std::find_if(
+ aFilters.begin(),
+ aFilters.end(),
+ FilterMatch( sCompareString )
+ );
+
+ bDelete = aFilters.end() == pMatchingFilter;
+ }
+
+ if( bDelete )
+ {
+ // none of the filters did match
+ delete (*aContentLoop);
+
+ if ( maContent.begin() == aContentLoop )
+ {
+ maContent.erase( aContentLoop );
+ aContentLoop = maContent.begin();
+ }
+ else
+ {
+ std::vector< SortingData_Impl* >::iterator aDelete = aContentLoop;
+ --aContentLoop; // move the iterator to a position which is not invalidated by the erase
+ maContent.erase( aDelete );
+ ++aContentLoop; // this is now the next one ....
+ }
+ }
+ else
+ ++aContentLoop;
+ }
+ }
+ while ( aContentLoop != maContent.end() );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvtFileView_Impl, SelectionMultiplexer, void*, _pSource )
+{
+ return mnSuspendSelectCallback ? 0L : m_aSelectHandler.Call( _pSource );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::SetSelectHandler( const Link& _rHdl )
+{
+ m_aSelectHandler = _rHdl;
+
+ Link aMasterHandler;
+ if ( m_aSelectHandler.IsSet() )
+ aMasterHandler = LINK( this, SvtFileView_Impl, SelectionMultiplexer );
+
+ mpView->SetSelectHdl( aMasterHandler );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::InitSelection()
+{
+ mpView->SelectAll( sal_False );
+ SvLBoxEntry* pFirst = mpView->First();
+ if ( pFirst )
+ mpView->SetCursor( pFirst, sal_True );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::OpenFolder_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ mpView->SetUpdateMode( FALSE );
+ mpView->ClearAll();
+
+ std::vector< SortingData_Impl* >::iterator aIt;
+
+ for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ )
+ {
+ if ( mbOnlyFolder && ! (*aIt)->mbIsFolder )
+ continue;
+
+ // insert entry and set user data
+ SvLBoxEntry* pEntry = mpView->InsertEntry( (*aIt)->maDisplayText,
+ (*aIt)->maImage,
+ (*aIt)->maImage );
+
+ SvtContentEntry* pUserData = new SvtContentEntry( (*aIt)->maTargetURL,
+ (*aIt)->mbIsFolder );
+ pEntry->SetUserData( pUserData );
+ }
+
+ InitSelection();
+
+ ++mnSuspendSelectCallback;
+ mpView->SetUpdateMode( TRUE );
+ --mnSuspendSelectCallback;
+
+ ResetCursor();
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::ResetCursor()
+{
+ // deselect
+ SvLBoxEntry* pEntry = mpView->FirstSelected();
+ if ( pEntry )
+ mpView->Select( pEntry, FALSE );
+ // set cursor to the first entry
+ mpView->SetCursor( mpView->First(), TRUE );
+ mpView->Update();
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::CancelRunningAsyncAction()
+{
+ DBG_TESTSOLARMUTEX();
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( !m_pContentEnumerator.is() )
+ return;
+
+ m_bAsyncActionCancelled = true;
+ m_pContentEnumerator->cancel();
+ m_bRunningAsyncAction = false;
+
+ m_pContentEnumerator = NULL;
+ if ( m_pCancelAsyncTimer.is() && m_pCancelAsyncTimer->isTicking() )
+ m_pCancelAsyncTimer->stop();
+ m_pCancelAsyncTimer = NULL;
+}
+
+//-----------------------------------------------------------------------
+void SvtFileView_Impl::onTimeout( CallbackTimer* )
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( !m_bRunningAsyncAction )
+ // there might have been a race condition while we waited for the mutex
+ return;
+
+ CancelRunningAsyncAction();
+
+ if ( m_aCurrentAsyncActionHandler.IsSet() )
+ {
+ Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( eTimeout ) );
+ m_aCurrentAsyncActionHandler = Link();
+ }
+}
+
+//-----------------------------------------------------------------------
+void SvtFileView_Impl::enumerationDone( ::svt::EnumerationResult _eResult )
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( maMutex );
+
+ m_pContentEnumerator = NULL;
+ if ( m_pCancelAsyncTimer.is() && m_pCancelAsyncTimer->isTicking() )
+ m_pCancelAsyncTimer->stop();
+ m_pCancelAsyncTimer = NULL;
+
+ if ( m_bAsyncActionCancelled )
+ // this is to prevent race conditions
+ return;
+
+ m_eAsyncActionResult = _eResult;
+ m_bRunningAsyncAction = false;
+
+ m_aAsyncActionFinished.set();
+
+ if ( svt::SUCCESS == _eResult )
+ implEnumerationSuccess();
+
+ if ( m_aCurrentAsyncActionHandler.IsSet() )
+ {
+ Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( m_eAsyncActionResult ) );
+ m_aCurrentAsyncActionHandler = Link();
+ }
+}
+
+//-----------------------------------------------------------------------
+void SvtFileView_Impl::implEnumerationSuccess()
+{
+ FilterFolderContent_Impl( maCurrentFilter );
+ SortFolderContent_Impl();
+ CreateDisplayText_Impl();
+ OpenFolder_Impl();
+ maOpenDoneLink.Call( mpAntiImpl );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::ReplaceTabWithString( OUString& aValue )
+{
+ OUString aTab = OUString::createFromAscii( "\t" );
+ OUString aTabString = OUString::createFromAscii( "%09" );
+ sal_Int32 iPos;
+
+ while ( ( iPos = aValue.indexOf( aTab ) ) >= 0 )
+ aValue = aValue.replaceAt( iPos, 1, aTabString );
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::CreateDisplayText_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ OUString aValue;
+ OUString aTab = OUString::createFromAscii( "\t" );
+ OUString aDateSep = OUString::createFromAscii( ", " );
+
+ std::vector< SortingData_Impl* >::iterator aIt;
+
+ for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ )
+ {
+ // title, type, size, date
+ aValue = (*aIt)->GetTitle();
+ // #83004# --------------------
+ ReplaceTabWithString( aValue );
+ aValue += aTab;
+ aValue += (*aIt)->maType;
+ aValue += aTab;
+ // folders don't have a size
+ if ( ! (*aIt)->mbIsFolder )
+ aValue += CreateExactSizeText_Impl( (*aIt)->maSize );
+ aValue += aTab;
+ // set the date, but volumes have no date
+ if ( ! (*aIt)->mbIsFolder || ! (*aIt)->mbIsVolume )
+ {
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
+ aValue += rLocaleData.getDate( (*aIt)->maModDate );
+ aValue += aDateSep;
+ aValue += rLocaleData.getTime( (*aIt)->maModDate );
+ }
+ (*aIt)->maDisplayText = aValue;
+
+ // detect image
+ if ( (*aIt)->mbIsFolder )
+ {
+ ::svtools::VolumeInfo aVolInfo( (*aIt)->mbIsVolume, (*aIt)->mbIsRemote,
+ (*aIt)->mbIsRemoveable, (*aIt)->mbIsFloppy,
+ (*aIt)->mbIsCompactDisc );
+ (*aIt)->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, FALSE, isHighContrast( mpView ) );
+ }
+ else
+ (*aIt)->maImage = SvFileInformationManager::GetFileImage( INetURLObject( (*aIt)->maTargetURL ), FALSE, isHighContrast( mpView ));
+ }
+}
+
+// -----------------------------------------------------------------------
+// this function converts the sequence of strings into a vector of SortingData
+// the string should have the form :
+// title \t type \t size \t date \t target url \t is folder \t image url
+
+void SvtFileView_Impl::CreateVector_Impl( const Sequence < OUString > &rList )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ OUString aTab = OUString::createFromAscii( "\t" );
+
+ sal_uInt32 nCount = (sal_uInt32) rList.getLength();
+
+ for( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ SortingData_Impl* pEntry = new SortingData_Impl;
+ OUString aValue = rList[i];
+ OUString aDisplayText;
+ sal_Int32 nIndex = 0;
+
+ // get the title
+ pEntry->SetNewTitle( aValue.getToken( 0, '\t', nIndex ) );
+ aDisplayText = pEntry->GetTitle();
+ // #83004# --------------------
+ ReplaceTabWithString( aDisplayText );
+ aDisplayText += aTab;
+
+ // get the type
+ if ( nIndex >= 0 )
+ {
+ pEntry->maType = aValue.getToken( 0, '\t', nIndex );
+ aDisplayText += pEntry->maType;
+ }
+ aDisplayText += aTab;
+
+ // get the size
+ if ( nIndex >= 0 )
+ {
+ OUString aSize = aValue.getToken( 0, '\t', nIndex );
+ aDisplayText += aSize;
+
+ if ( aSize.getLength() )
+ pEntry->maSize = aSize.toInt64();
+ }
+ aDisplayText += aTab;
+
+ // get the date
+ if ( nIndex >= 0 )
+ {
+ OUString aDate = aValue.getToken( 0, '\t', nIndex );
+ aDisplayText += aDate;
+
+ if ( aDate.getLength() )
+ {
+ DBG_ERRORFILE( "Don't know, how to convert date" );
+ ;// convert date string to date
+ }
+ }
+ // get the target url
+ if ( nIndex >= 0 )
+ {
+ pEntry->maTargetURL = aValue.getToken( 0, '\t', nIndex );
+ }
+ // get the size
+ if ( nIndex >= 0 )
+ {
+ OUString aBool = aValue.getToken( 0, '\t', nIndex );
+ if ( aBool.getLength() )
+ pEntry->mbIsFolder = aBool.toBoolean();
+ }
+ // get the image url
+ if ( nIndex >= 0 )
+ {
+ pEntry->maImageURL = aValue.getToken( 0, '\t', nIndex );
+ }
+
+ // set the display text
+ pEntry->maDisplayText = aDisplayText;
+
+ // detect the image
+ INetURLObject aObj( pEntry->maImageURL.getLength() ? pEntry->maImageURL : pEntry->maTargetURL );
+ pEntry->maImage = SvFileInformationManager::GetImage( aObj, FALSE, isHighContrast( mpView ) );
+
+ maContent.push_back( pEntry );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::Resort_Impl( sal_Int16 nColumn, sal_Bool bAscending )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( ( nColumn == mnSortColumn ) &&
+ ( bAscending == mbAscending ) )
+ return;
+
+ // reset the quick search index
+ mpView->ResetQuickSearch_Impl( NULL );
+
+ String aEntryURL;
+ SvLBoxEntry* pEntry = mpView->GetCurEntry();
+ if ( pEntry && pEntry->GetUserData() )
+ aEntryURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL;
+
+ mnSortColumn = nColumn;
+ mbAscending = bAscending;
+
+ SortFolderContent_Impl();
+ OpenFolder_Impl();
+
+ if ( !mbIsFirstResort )
+ {
+ ULONG nPos = GetEntryPos( aEntryURL );
+ if ( nPos < mpView->GetEntryCount() )
+ {
+ pEntry = mpView->GetEntry( nPos );
+
+ ++mnSuspendSelectCallback; // #i15668# - 2004-04-25 - fs@openoffice.org
+ mpView->SetCurEntry( pEntry );
+ --mnSuspendSelectCallback;
+ }
+ }
+ else
+ mbIsFirstResort = sal_False;
+}
+
+// -----------------------------------------------------------------------
+static sal_Bool gbAscending = sal_True;
+static sal_Int16 gnColumn = COLUMN_TITLE;
+static const CollatorWrapper* pCollatorWrapper = NULL;
+
+/* this functions returns true, if aOne is less then aTwo
+*/
+sal_Bool CompareSortingData_Impl( SortingData_Impl* const aOne, SortingData_Impl* const aTwo )
+{
+ DBG_ASSERT( pCollatorWrapper, "*CompareSortingData_Impl(): Can't work this way!" );
+
+ sal_Int32 nComp;
+ sal_Bool bRet = sal_False;
+ sal_Bool bEqual = sal_False;
+
+ if ( aOne->mbIsFolder != aTwo->mbIsFolder )
+ {
+ if ( aOne->mbIsFolder )
+ bRet = sal_True;
+ else
+ bRet = sal_False;
+
+ // !!! pb: #100376# folder always on top
+ if ( !gbAscending )
+ bRet = !bRet;
+ }
+ else
+ {
+ switch ( gnColumn )
+ {
+ case COLUMN_TITLE:
+ // compare case insensitiv first
+ nComp = pCollatorWrapper->compareString( aOne->GetLowerTitle(), aTwo->GetLowerTitle() );
+
+ if ( nComp == 0 )
+ nComp = pCollatorWrapper->compareString( aOne->GetTitle(), aTwo->GetTitle() );
+
+ if ( nComp < 0 )
+ bRet = sal_True;
+ else if ( nComp > 0 )
+ bRet = sal_False;
+ else
+ bEqual = sal_True;
+ break;
+ case COLUMN_TYPE:
+ nComp = pCollatorWrapper->compareString( aOne->maType, aTwo->maType );
+ if ( nComp < 0 )
+ bRet = sal_True;
+ else if ( nComp > 0 )
+ bRet = sal_False;
+ else
+ bEqual = sal_True;
+ break;
+ case COLUMN_SIZE:
+ if ( aOne->maSize < aTwo->maSize )
+ bRet = sal_True;
+ else if ( aOne->maSize > aTwo->maSize )
+ bRet = sal_False;
+ else
+ bEqual = sal_True;
+ break;
+ case COLUMN_DATE:
+ if ( aOne->maModDate < aTwo->maModDate )
+ bRet = sal_True;
+ else if ( aOne->maModDate > aTwo->maModDate )
+ bRet = sal_False;
+ else
+ bEqual = sal_True;
+ break;
+ default:
+ DBG_WARNING( "CompareSortingData_Impl: Compare unknown type!" );
+ bRet = sal_False;
+ }
+ }
+
+ // when the two elements are equal, we must not return TRUE (which would
+ // happen if we just return ! ( a < b ) when not sorting ascending )
+ if ( bEqual )
+ return sal_False;
+
+ return gbAscending ? bRet : !bRet;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::SortFolderContent_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ sal_uInt32 nSize = maContent.size();
+
+ if ( nSize > 1 )
+ {
+ gbAscending = mbAscending;
+ gnColumn = mnSortColumn;
+ pCollatorWrapper = aIntlWrapper.getCaseCollator();
+
+ std::stable_sort( maContent.begin(), maContent.end(), CompareSortingData_Impl );
+
+ pCollatorWrapper = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::EntryRemoved( const OUString& rURL )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ std::vector< SortingData_Impl* >::iterator aIt;
+
+ for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ )
+ {
+ if ( (*aIt)->maTargetURL == rURL )
+ {
+ maContent.erase( aIt );
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::EntryRenamed( OUString& rURL,
+ const OUString& rTitle )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ std::vector< SortingData_Impl* >::iterator aIt;
+
+ for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ )
+ {
+ if ( (*aIt)->maTargetURL == rURL )
+ {
+ (*aIt)->SetNewTitle( rTitle );
+ OUString aDisplayText = (*aIt)->maDisplayText;
+ sal_Int32 nIndex = aDisplayText.indexOf( '\t' );
+
+ if ( nIndex > 0 )
+ (*aIt)->maDisplayText = aDisplayText.replaceAt( 0, nIndex, rTitle );
+
+ INetURLObject aURLObj( rURL );
+ aURLObj.SetName( rTitle, INetURLObject::ENCODE_ALL );
+
+ rURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ (*aIt)->maTargetURL = rURL;
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+String SvtFileView_Impl::FolderInserted( const OUString& rURL, const OUString& rTitle )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ SortingData_Impl* pData = new SortingData_Impl;
+
+ pData->SetNewTitle( rTitle );
+ pData->maSize = 0;
+ pData->mbIsFolder = sal_True;
+ pData->maTargetURL = rURL;
+
+ INetURLObject aURLObj( rURL );
+
+ ::svtools::VolumeInfo aVolInfo;
+ pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
+ pData->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, FALSE, isHighContrast( mpView ) );
+
+ OUString aValue;
+ OUString aTab = OUString::createFromAscii( "\t" );
+ OUString aDateSep = OUString::createFromAscii( ", " );
+
+ // title, type, size, date
+ aValue = pData->GetTitle();
+ // #83004# --------------------
+ ReplaceTabWithString( aValue );
+ aValue += aTab;
+ aValue += pData->maType;
+ aValue += aTab;
+ // folders don't have a size
+ aValue += aTab;
+ // set the date
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
+ aValue += rLocaleData.getDate( pData->maModDate );
+ aValue += aDateSep;
+ aValue += rLocaleData.getTime( pData->maModDate );
+
+ pData->maDisplayText = aValue;
+ maContent.push_back( pData );
+
+ return String( aValue );
+}
+
+// -----------------------------------------------------------------------
+ULONG SvtFileView_Impl::GetEntryPos( const OUString& rURL )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ std::vector< SortingData_Impl* >::iterator aIt;
+ ULONG nPos = 0;
+
+ for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ )
+ {
+ if ( (*aIt)->maTargetURL == rURL )
+ return nPos;
+ nPos += 1;
+ }
+
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvtFileView_Impl::SearchNextEntry( sal_uInt32& nIndex, const OUString& rTitle, sal_Bool bWrapAround )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ sal_uInt32 nEnd = maContent.size();
+ sal_uInt32 nStart = nIndex;
+ while ( nIndex < nEnd )
+ {
+ SortingData_Impl* pData = maContent[ nIndex ];
+ if ( rTitle.compareTo( pData->GetLowerTitle(), rTitle.getLength() ) == 0 )
+ return sal_True;
+ nIndex += 1;
+ }
+
+ if ( bWrapAround )
+ {
+ nIndex = 0;
+ while ( nIndex < nEnd && nIndex <= nStart )
+ {
+ SortingData_Impl* pData = maContent[ nIndex ];
+ if ( rTitle.compareTo( pData->GetLowerTitle(), rTitle.getLength() ) == 0 )
+ return sal_True;
+ nIndex += 1;
+ }
+ }
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+void SvtFileView_Impl::SetActualFolder( const INetURLObject& rActualFolder )
+{
+ if( mbReplaceNames )
+ {
+ if( mpNameTrans )
+ mpNameTrans->SetActualFolder( rActualFolder );
+ else
+ mpNameTrans = new NameTranslator_Impl( rActualFolder );
+ }
+}
+
+namespace svtools {
+
+// -----------------------------------------------------------------------
+// QueryDeleteDlg_Impl
+// -----------------------------------------------------------------------
+
+QueryDeleteDlg_Impl::QueryDeleteDlg_Impl
+(
+ Window* pParent,
+ const String& rName // Eintragsname
+) :
+
+ ModalDialog( pParent, SvtResId( DLG_SVT_QUERYDELETE ) ),
+
+ _aEntryLabel ( this, SvtResId( TXT_ENTRY ) ),
+ _aEntry ( this, SvtResId( TXT_ENTRYNAME ) ),
+ _aQueryMsg ( this, SvtResId( TXT_QUERYMSG ) ),
+ _aYesButton ( this, SvtResId( BTN_YES ) ),
+ _aAllButton ( this, SvtResId( BTN_ALL ) ),
+ _aNoButton ( this, SvtResId( BTN_NO ) ),
+ _aCancelButton( this, SvtResId( BTN_CANCEL ) )
+
+{
+ FreeResource();
+
+ // Handler
+ Link aLink( STATIC_LINK( this, QueryDeleteDlg_Impl, ClickLink ) );
+ _aYesButton.SetClickHdl( aLink );
+ _aAllButton.SetClickHdl( aLink );
+ _aNoButton.SetClickHdl( aLink );
+
+ // Anzeige der spezifizierten Texte
+
+ WinBits nTmpStyle = _aEntry.GetStyle();
+ nTmpStyle |= WB_PATHELLIPSIS;
+ _aEntry.SetStyle( nTmpStyle );
+ _aEntry.SetText( rName );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_STATIC_LINK( QueryDeleteDlg_Impl, ClickLink, PushButton*, pBtn )
+{
+ if ( pBtn == &pThis->_aYesButton )
+ pThis->_eResult = QUERYDELETE_YES;
+ else if ( pBtn == &pThis->_aNoButton )
+ pThis->_eResult = QUERYDELETE_NO;
+ else if ( pBtn == &pThis->_aAllButton )
+ pThis->_eResult = QUERYDELETE_ALL;
+ else if ( pBtn == &pThis->_aCancelButton )
+ pThis->_eResult = QUERYDELETE_CANCEL;
+
+ pThis->EndDialog( RET_OK );
+
+ return 0;
+}
+
+}
+
diff --git a/svtools/source/contnr/fileview.hrc b/svtools/source/contnr/fileview.hrc
new file mode 100644
index 000000000000..bbf340148fc9
--- /dev/null
+++ b/svtools/source/contnr/fileview.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.
+ *
+ ************************************************************************/
+
+#define MID_FILEVIEW_DELETE 1
+#define MID_FILEVIEW_RENAME 2
+
+// DLG_SFX_QUERYDELETE ********************************************************
+
+#define TXT_ENTRY 1
+#define TXT_ENTRYNAME 2
+#define TXT_QUERYMSG 3
+#define BTN_YES 4
+#define BTN_NO 5
+#define BTN_ALL 6
+#define BTN_CANCEL 7
+
diff --git a/svtools/source/contnr/fileview.src b/svtools/source/contnr/fileview.src
new file mode 100644
index 000000000000..f40530c10347
--- /dev/null
+++ b/svtools/source/contnr/fileview.src
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ // includes ------------------------------------------------------------------
+
+#include <svtools/svtools.hrc>
+#include "fileview.hrc"
+#include <svtools/helpid.hrc>
+
+// strings --------------------------------------------------------------------
+
+String STR_SVT_FILEVIEW_COLUMN_TITLE
+{
+ Text [ en-US ] = "Title";
+};
+
+String STR_SVT_FILEVIEW_COLUMN_SIZE
+{
+ Text [ en-US ] = "Size";
+};
+
+String STR_SVT_FILEVIEW_COLUMN_DATE
+{
+ Text [ en-US ] = "Date modified";
+};
+
+String STR_SVT_FILEVIEW_COLUMN_TYPE
+{
+ Text [ en-US ] = "Type";
+};
+
+String STR_SVT_FILEVIEW_ERR_MAKEFOLDER
+{
+ Text [ en-US ] = "Could not create the folder %1.";
+};
+
+String STR_SVT_BYTES
+{
+ Text [ en-US ] = "Bytes" ;
+};
+
+String STR_SVT_KB
+{
+ Text [ en-US ] = "KB" ;
+};
+
+String STR_SVT_MB
+{
+ Text [ en-US ] = "MB" ;
+};
+
+
+String STR_SVT_GB
+{
+ Text [ en-US ] = "GB" ;
+};
+
+// Images ---------------------------------------------------------------------
+
+Image IMG_SVT_FOLDER
+{
+ ImageBitmap = Bitmap { File = "folder.bmp" ; };
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+};
+
+// Menus -----------------------------------------------------------------
+
+Menu RID_FILEVIEW_CONTEXTMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MID_FILEVIEW_DELETE ;
+ HelpId = HID_FILEVIEW_MENU_DELETE ;
+ Text [ en-US ] = "~Delete";
+ };
+ MenuItem
+ {
+ Identifier = MID_FILEVIEW_RENAME ;
+ HelpId = HID_FILEVIEW_MENU_RENAME ;
+ Text [ en-US ] = "~Rename";
+ };
+ };
+};
+
+ModalDialog DLG_SVT_QUERYDELETE
+{
+ SVLook = TRUE ;
+ OutputSize = TRUE ;
+ Moveable = TRUE ;
+ Size = MAP_APPFONT ( 221 , 67 ) ;
+ Text [ en-US ] = "Confirm Delete" ;
+
+ FixedText TXT_ENTRY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "Entry:" ;
+ };
+
+ FixedText TXT_ENTRYNAME
+ {
+ Pos = MAP_APPFONT ( 52 , 6 ) ;
+ Size = MAP_APPFONT ( 163 , 10 ) ;
+ NoLabel = TRUE ;
+ };
+
+ FixedText TXT_QUERYMSG
+ {
+ NoLabel = TRUE;
+ WordBreak = TRUE;
+ Pos = MAP_APPFONT ( 6 , 19 ) ;
+ Size = MAP_APPFONT ( 209 , 22 ) ;
+ Text [ en-US ] = "Are you sure you want to delete the selected data?" ;
+ };
+
+ PushButton BTN_YES
+ {
+ Pos = MAP_APPFONT ( 6 , 47 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ Text [ en-US ] = "~Delete" ;
+ };
+
+ PushButton BTN_ALL
+ {
+ Pos = MAP_APPFONT ( 59 , 47 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Disable = TRUE ;
+ Text [ en-US ] = "Delete ~All" ;
+ };
+
+ PushButton BTN_NO
+ {
+ Pos = MAP_APPFONT ( 112 , 47 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Do ~Not Delete" ;
+ };
+
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 165 , 47 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/contnr/imivctl.hxx b/svtools/source/contnr/imivctl.hxx
new file mode 100644
index 000000000000..cc7aa4e05ee1
--- /dev/null
+++ b/svtools/source/contnr/imivctl.hxx
@@ -0,0 +1,637 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _IMPICNVW_HXX
+#define _IMPICNVW_HXX
+
+#ifndef _VIRDEV_HXX
+#include <vcl/virdev.hxx>
+#endif
+#ifndef _SCRBAR_HXX
+#include <vcl/scrbar.hxx>
+#endif
+#include <vcl/timer.hxx>
+#include <vcl/seleng.hxx>
+#include <tools/debug.hxx>
+#include "svtaccessiblefactory.hxx"
+
+#include <limits.h>
+
+#include "ivctrl.hxx"
+#include <svl/svarray.hxx>
+
+class IcnCursor_Impl;
+class SvtIconChoiceCtrl;
+class SvxIconChoiceCtrlEntry;
+class IcnViewEdit_Impl;
+class IcnGridMap_Impl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// some defines
+//
+#define PAINTFLAG_HOR_CENTERED 0x0001
+#define PAINTFLAG_VER_CENTERED 0x0002
+
+#define F_VER_SBARSIZE_WITH_HBAR 0x0001
+#define F_HOR_SBARSIZE_WITH_VBAR 0x0002
+#define F_PAINTED 0x0004 // TRUE nach erstem Paint
+#define F_ADD_MODE 0x0008
+#define F_SELECTING_RECT 0x0020
+#define F_DOWN_CTRL 0x0080
+#define F_DOWN_DESELECT 0x0100
+#define F_START_EDITTIMER_IN_MOUSEUP 0x0400
+#define F_MOVED_ENTRIES 0x0800
+#define F_ENTRYLISTPOS_VALID 0x1000
+#define F_CLEARING_SELECTION 0x2000
+#define F_ARRANGING 0x4000
+
+// alle Angaben in Pixel
+// Abstaende von Fensterraendern
+#define LROFFS_WINBORDER 4
+#define TBOFFS_WINBORDER 4
+// fuer das Bounding-Rectangle
+#define LROFFS_BOUND 2
+#define TBOFFS_BOUND 2
+// Abstand Fokusrechteck - Icon
+#define LROFFS_ICON 2
+#define TBOFFS_ICON 2
+// Abstaende Icon - Text
+#define HOR_DIST_BMP_STRING 3
+#define VER_DIST_BMP_STRING 3
+// Breitenoffset Highlight-Rect bei Text
+#define LROFFS_TEXT 2
+
+#define DEFAULT_MAX_VIRT_WIDTH 200
+#define DEFAULT_MAX_VIRT_HEIGHT 200
+
+#define VIEWMODE_MASK (WB_ICON | WB_SMALLICON | WB_DETAILS)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//
+//
+enum IcnViewFieldType
+{
+ IcnViewFieldTypeDontknow = 0,
+ IcnViewFieldTypeImage = 1,
+ IcnViewFieldTypeText = 2
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Data about the focus of entries
+//
+struct LocalFocus
+{
+ BOOL bOn;
+ Rectangle aRect;
+ Color aPenColor;
+
+ LocalFocus() { bOn = FALSE; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Entry-List
+//
+class EntryList_Impl : public List
+{
+private:
+
+ using List::Replace;
+
+ SvxIconChoiceCtrl_Impl* _pOwner;
+
+ void Removed_Impl( SvxIconChoiceCtrlEntry* pEntry );
+
+public:
+ EntryList_Impl(
+ SvxIconChoiceCtrl_Impl*,
+ USHORT _nInitSize = 1024,
+ USHORT _nReSize = 1024 );
+ EntryList_Impl(
+ SvxIconChoiceCtrl_Impl*,
+ USHORT _nBlockSize,
+ USHORT _nInitSize,
+ USHORT _nReSize );
+ ~EntryList_Impl();
+
+ void Clear();
+ void Insert( SvxIconChoiceCtrlEntry* pEntry, ULONG nPos );
+ SvxIconChoiceCtrlEntry* Remove( ULONG nPos );
+ void Remove( SvxIconChoiceCtrlEntry* pEntry );
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Implementation-class of IconChoiceCtrl
+//
+class SvxIconChoiceCtrl_Impl
+{
+ friend class IcnCursor_Impl;
+ friend class EntryList_Impl;
+ friend class IcnGridMap_Impl;
+
+ BOOL bChooseWithCursor;
+ EntryList_Impl aEntries;
+ ScrollBar aVerSBar;
+ ScrollBar aHorSBar;
+ ScrollBarBox aScrBarBox;
+ Rectangle aCurSelectionRect;
+ SvPtrarr aSelectedRectList;
+ Timer aEditTimer; // fuer Inplace-Editieren
+ Timer aAutoArrangeTimer;
+ Timer aDocRectChangedTimer;
+ Timer aVisRectChangedTimer;
+ Timer aCallSelectHdlTimer;
+ Size aVirtOutputSize;
+ Size aImageSize;
+ Size aDefaultTextSize;
+ Size aOutputSize; // Pixel
+ Point aDDLastEntryPos;
+ Point aDDLastRectPos;
+ Point aDDPaintOffs;
+ Point aDDStartPos;
+ SvtIconChoiceCtrl* pView;
+ IcnCursor_Impl* pImpCursor;
+ IcnGridMap_Impl* pGridMap;
+ long nMaxVirtWidth; // max. Breite aVirtOutputSize bei ALIGN_TOP
+ long nMaxVirtHeight; // max. Hoehe aVirtOutputSize bei ALIGN_LEFT
+ List* pZOrderList;
+ SvPtrarr* pColumns;
+ IcnViewEdit_Impl* pEdit;
+ WinBits nWinBits;
+ long nMaxBoundHeight; // Hoehe des hoechsten BoundRects
+ USHORT nFlags;
+ USHORT nCurTextDrawFlags;
+ ULONG nUserEventAdjustScrBars;
+ ULONG nUserEventShowCursor;
+ SvxIconChoiceCtrlEntry* pCurHighlightFrame;
+ BOOL bHighlightFramePressed;
+ SvxIconChoiceCtrlEntry* pHead; // Eintrag oben links
+ SvxIconChoiceCtrlEntry* pCursor;
+ SvxIconChoiceCtrlEntry* pPrevDropTarget;
+ SvxIconChoiceCtrlEntry* pHdlEntry;
+ SvxIconChoiceCtrlEntry* pDDRefEntry;
+ VirtualDevice* pDDDev;
+ VirtualDevice* pDDBufDev;
+ VirtualDevice* pDDTempDev;
+ VirtualDevice* pEntryPaintDev;
+ SvxIconChoiceCtrlEntry* pAnchor; // fuer Selektion
+ LocalFocus aFocus; // Data for focusrect
+ ::svt::AccessibleFactoryAccess aAccFactory;
+
+ List* pDraggedSelection;
+ SvxIconChoiceCtrlEntry* pCurEditedEntry;
+ SvxIconChoiceCtrlTextMode eTextMode;
+ SelectionMode eSelectionMode;
+ ULONG nSelectionCount;
+ SvxIconChoiceCtrlPositionMode ePositionMode;
+ BOOL bBoundRectsDirty;
+ BOOL bUpdateMode;
+ BOOL bEntryEditingEnabled;
+ BOOL bInDragDrop;
+
+ void ShowCursor( BOOL bShow );
+
+ void ImpArrange( BOOL bKeepPredecessors = FALSE );
+ void AdjustVirtSize( const Rectangle& );
+ void ResetVirtSize();
+ void CheckScrollBars();
+
+ DECL_LINK( ScrollUpDownHdl, ScrollBar * );
+ DECL_LINK( ScrollLeftRightHdl, ScrollBar * );
+ DECL_LINK( EditTimeoutHdl, Timer* );
+ DECL_LINK( UserEventHdl, void* );
+ DECL_LINK( EndScrollHdl, void* );
+ DECL_LINK( AutoArrangeHdl, void* );
+ DECL_LINK( DocRectChangedHdl, void* );
+ DECL_LINK( VisRectChangedHdl, void* );
+ DECL_LINK( CallSelectHdlHdl, void* );
+
+ void AdjustScrollBars( BOOL bVirtSizeGrowedOnly = FALSE);
+ void PositionScrollBars( long nRealWidth, long nRealHeight );
+ long GetScrollBarPageSize( long nVisibleRange ) const { return ((nVisibleRange*75)/100); }
+ long GetScrollBarLineSize() const { return nMaxBoundHeight / 2; }
+ BOOL HandleScrollCommand( const CommandEvent& rCmd );
+ void ToDocPos( Point& rPosPixel ) { rPosPixel -= pView->GetMapMode().GetOrigin(); }
+ void InitScrollBarBox();
+ SvxIconChoiceCtrlEntry* FindNewCursor();
+ void ToggleSelection( SvxIconChoiceCtrlEntry* );
+ void DeselectAllBut( SvxIconChoiceCtrlEntry*, BOOL bPaintSync=FALSE );
+ void Center( SvxIconChoiceCtrlEntry* pEntry ) const;
+ void StopEditTimer() { aEditTimer.Stop(); }
+ void StartEditTimer() { aEditTimer.Start(); }
+ void ImpHideDDIcon();
+ void CallSelectHandler( SvxIconChoiceCtrlEntry* );
+ void SelectRect(
+ SvxIconChoiceCtrlEntry* pEntry1,
+ SvxIconChoiceCtrlEntry* pEntry2,
+ BOOL bAdd = TRUE,
+ SvPtrarr* pOtherRects = 0 );
+
+ void SelectRange(
+ SvxIconChoiceCtrlEntry* pStart,
+ SvxIconChoiceCtrlEntry* pEnd,
+ BOOL bAdd = TRUE );
+
+ void AddSelectedRect( const Rectangle& );
+ void AddSelectedRect(
+ SvxIconChoiceCtrlEntry* pEntry1,
+ SvxIconChoiceCtrlEntry* pEntry2 );
+
+ void ClearSelectedRectList();
+ void ClearColumnList();
+ Rectangle CalcMaxTextRect( const SvxIconChoiceCtrlEntry* pEntry ) const;
+
+ void ClipAtVirtOutRect( Rectangle& rRect ) const;
+ void AdjustAtGrid( const SvPtrarr& rRow, SvxIconChoiceCtrlEntry* pStart=0 );
+ Point AdjustAtGrid(
+ const Rectangle& rCenterRect, // "Schwerpunkt" des Objekts (typ. Bmp-Rect)
+ const Rectangle& rBoundRect ) const;
+ ULONG GetPredecessorGrid( const Point& rDocPos) const;
+
+ void InitPredecessors();
+ void ClearPredecessors();
+
+ BOOL CheckVerScrollBar();
+ BOOL CheckHorScrollBar();
+ void CancelUserEvents();
+ void EntrySelected( SvxIconChoiceCtrlEntry* pEntry, BOOL bSelect,
+ BOOL bSyncPaint );
+ void SaveSelection( List** );
+ void RepaintEntries( USHORT nEntryFlagsMask );
+ void SetListPositions();
+ void SetDefaultTextSize();
+ BOOL IsAutoArrange() const {
+ return (BOOL)(ePositionMode == IcnViewPositionModeAutoArrange); }
+ BOOL IsAutoAdjust() const {
+ return (BOOL)(ePositionMode == IcnViewPositionModeAutoAdjust); }
+ void DocRectChanged() { aDocRectChangedTimer.Start(); }
+ void VisRectChanged() { aVisRectChangedTimer.Start(); }
+ void SetOrigin( const Point&, BOOL bDoNotUpdateWallpaper = FALSE );
+
+ DECL_LINK( TextEditEndedHdl, IcnViewEdit_Impl* );
+
+ void ShowFocus ( Rectangle& rRect );
+ void HideFocus ();
+ void DrawFocusRect ( OutputDevice* pOut );
+
+ BOOL IsMnemonicChar( sal_Unicode cChar, ULONG& rPos ) const;
+
+public:
+
+ long nGridDX,
+ nGridDY;
+ long nHorSBarHeight,
+ nVerSBarWidth;
+
+ SvxIconChoiceCtrl_Impl( SvtIconChoiceCtrl* pView, WinBits nWinStyle );
+ ~SvxIconChoiceCtrl_Impl();
+
+ BOOL SetChoiceWithCursor ( BOOL bDo = TRUE ) { BOOL bOld=bChooseWithCursor; bChooseWithCursor = bDo; return bOld; }
+ void Clear( BOOL bInCtor = FALSE );
+ void SetStyle( WinBits nWinStyle );
+ WinBits GetStyle() const { return nWinBits; }
+ void InsertEntry( SvxIconChoiceCtrlEntry*, ULONG nPos, const Point* pPos=0 );
+ void CreateAutoMnemonics( MnemonicGenerator* _pGenerator = NULL );
+ void RemoveEntry( SvxIconChoiceCtrlEntry* pEntry );
+ void FontModified();
+ void SelectAll( BOOL bSelect = TRUE, BOOL bPaint = TRUE );
+ void SelectEntry(
+ SvxIconChoiceCtrlEntry*,
+ BOOL bSelect,
+ BOOL bCallHdl = TRUE,
+ BOOL bAddToSelection = FALSE,
+ BOOL bSyncPaint = FALSE );
+ void Paint( const Rectangle& rRect );
+ BOOL MouseButtonDown( const MouseEvent& );
+ BOOL MouseButtonUp( const MouseEvent& );
+ BOOL MouseMove( const MouseEvent&);
+ BOOL RequestHelp( const HelpEvent& rHEvt );
+ void SetCursor_Impl(
+ SvxIconChoiceCtrlEntry* pOldCursor,
+ SvxIconChoiceCtrlEntry* pNewCursor,
+ BOOL bMod1,
+ BOOL bShift,
+ BOOL bPaintSync = FALSE);
+ BOOL KeyInput( const KeyEvent& );
+ void Resize();
+ void GetFocus();
+ void LoseFocus();
+ void SetUpdateMode( BOOL bUpdate );
+ BOOL GetUpdateMode() const { return bUpdateMode; }
+ void PaintEntry( SvxIconChoiceCtrlEntry* pEntry, BOOL bIsBackgroundPainted=FALSE );
+ void PaintEntry(
+ SvxIconChoiceCtrlEntry*,
+ const Point&,
+ OutputDevice* pOut = 0,
+ BOOL bIsBackgroundPainted = FALSE);
+ void PaintEntryVirtOutDev( SvxIconChoiceCtrlEntry* );
+
+ void SetEntryPos(
+ SvxIconChoiceCtrlEntry* pEntry,
+ const Point& rPos,
+ BOOL bAdjustRow = FALSE,
+ BOOL bCheckScrollBars = FALSE,
+ BOOL bKeepGridMap = FALSE );
+
+ void InvalidateEntry( SvxIconChoiceCtrlEntry* );
+ IcnViewFieldType GetItem( SvxIconChoiceCtrlEntry*, const Point& rAbsPos );
+
+ void SetNoSelection();
+
+ SvxIconChoiceCtrlEntry* GetCurEntry() const { return pCursor; }
+ void SetCursor(
+ SvxIconChoiceCtrlEntry*,
+ // TRUE == bei Single-Selection die Sel. mitfuehren
+ BOOL bSyncSingleSelection = TRUE,
+ BOOL bShowFocusAsync = FALSE );
+
+ SvxIconChoiceCtrlEntry* GetEntry( const Point& rDocPos, BOOL bHit = FALSE );
+ SvxIconChoiceCtrlEntry* GetNextEntry( const Point& rDocPos, SvxIconChoiceCtrlEntry* pCurEntry );
+ SvxIconChoiceCtrlEntry* GetPrevEntry( const Point& rDocPos, SvxIconChoiceCtrlEntry* pCurEntry );
+
+ Point GetEntryPos( SvxIconChoiceCtrlEntry* );
+ void MakeEntryVisible( SvxIconChoiceCtrlEntry* pEntry, BOOL bBound = TRUE );
+
+ void Arrange(BOOL bKeepPredecessors = FALSE, long nSetMaxVirtWidth =0, long nSetMaxVirtHeight =0 );
+
+ Rectangle CalcFocusRect( SvxIconChoiceCtrlEntry* );
+ Rectangle CalcBmpRect( SvxIconChoiceCtrlEntry*, const Point* pPos = 0 );
+ Rectangle CalcTextRect(
+ SvxIconChoiceCtrlEntry*,
+ const Point* pPos = 0,
+ BOOL bForInplaceEdit = FALSE,
+ const String* pStr = 0 );
+
+ long CalcBoundingWidth( SvxIconChoiceCtrlEntry* ) const;
+ long CalcBoundingHeight( SvxIconChoiceCtrlEntry* ) const;
+ Size CalcBoundingSize( SvxIconChoiceCtrlEntry* ) const;
+ void FindBoundingRect( SvxIconChoiceCtrlEntry* pEntry );
+ void SetBoundingRect_Impl(
+ SvxIconChoiceCtrlEntry* pEntry,
+ const Point& rPos,
+ const Size& rBoundingSize );
+ // berechnet alle BoundRects neu
+ void RecalcAllBoundingRects();
+ // berechnet alle ungueltigen BoundRects neu
+ void RecalcAllBoundingRectsSmart();
+ const Rectangle& GetEntryBoundRect( SvxIconChoiceCtrlEntry* );
+ void InvalidateBoundingRect( SvxIconChoiceCtrlEntry* );
+ void InvalidateBoundingRect( Rectangle& rRect ) { rRect.Right() = LONG_MAX; bBoundRectsDirty = TRUE; }
+ BOOL IsBoundingRectValid( const Rectangle& rRect ) const { return (BOOL)( rRect.Right() != LONG_MAX ); }
+
+ void PaintEmphasis(
+ const Rectangle& rRect1,
+ const Rectangle& rRect2,
+ BOOL bSelected,
+ BOOL bDropTarget,
+ BOOL bCursored,
+ OutputDevice* pOut,
+ BOOL bIsBackgroundPainted = FALSE);
+
+ void PaintItem(
+ const Rectangle& rRect,
+ IcnViewFieldType eItem,
+ SvxIconChoiceCtrlEntry* pEntry,
+ USHORT nPaintFlags,
+ OutputDevice* pOut,
+ const String* pStr = 0,
+ ::vcl::ControlLayoutData* _pLayoutData = NULL );
+
+ // berechnet alle BoundingRects neu, wenn bMustRecalcBoundingRects == TRUE
+ void CheckBoundingRects() { if (bBoundRectsDirty) RecalcAllBoundingRectsSmart(); }
+ // berechnet alle invalidierten BoundingRects neu
+ void UpdateBoundingRects();
+ void ShowTargetEmphasis( SvxIconChoiceCtrlEntry* pEntry, BOOL bShow );
+ void PrepareCommandEvent( const CommandEvent& );
+ void Command( const CommandEvent& rCEvt );
+ void ToTop( SvxIconChoiceCtrlEntry* );
+
+ ULONG GetSelectionCount() const;
+ void SetGrid( const Size& );
+ Size GetMinGrid() const;
+ ULONG GetGridCount(
+ const Size& rSize,
+ BOOL bCheckScrBars,
+ BOOL bSmartScrBar ) const;
+ void Scroll( long nDeltaX, long nDeltaY, BOOL bScrollBar = FALSE );
+ const Size& GetItemSize( SvxIconChoiceCtrlEntry*, IcnViewFieldType ) const;
+
+ void HideDDIcon();
+ void ShowDDIcon( SvxIconChoiceCtrlEntry* pRefEntry, const Point& rPos );
+ void HideShowDDIcon(
+ SvxIconChoiceCtrlEntry* pRefEntry,
+ const Point& rPos );
+
+ BOOL IsOver(
+ SvPtrarr* pSelectedRectList,
+ const Rectangle& rEntryBoundRect ) const;
+
+ void SelectRect(
+ const Rectangle&,
+ BOOL bAdd = TRUE,
+ SvPtrarr* pOtherRects = 0 );
+
+ void CalcScrollOffsets(
+ const Point& rRefPosPixel,
+ long& rX,
+ long& rY,
+ BOOL bDragDrop = FALSE,
+ USHORT nBorderWidth = 10 );
+
+ BOOL IsTextHit( SvxIconChoiceCtrlEntry* pEntry, const Point& rDocPos );
+ void MakeVisible(
+ const Rectangle& rDocPos,
+ BOOL bInScrollBarEvent=FALSE,
+ BOOL bCallRectChangedHdl = TRUE );
+
+ void AdjustEntryAtGrid( SvxIconChoiceCtrlEntry* pStart = 0 );
+ void SetEntryTextMode( SvxIconChoiceCtrlTextMode, SvxIconChoiceCtrlEntry* pEntry = 0 );
+ SvxIconChoiceCtrlTextMode GetTextMode( const SvxIconChoiceCtrlEntry* pEntry = 0 ) const;
+ void ShowEntryFocusRect( const SvxIconChoiceCtrlEntry* pEntry );
+ void EnableEntryEditing( BOOL bEnable ) { bEntryEditingEnabled = bEnable; }
+ BOOL IsEntryEditingEnabled() const { return bEntryEditingEnabled; }
+ BOOL IsEntryEditing() const { return (BOOL)(pCurEditedEntry!=0); }
+ void EditEntry( SvxIconChoiceCtrlEntry* pEntry );
+ void StopEntryEditing( BOOL bCancel );
+ void LockEntryPos( SvxIconChoiceCtrlEntry* pEntry, BOOL bLock );
+ ULONG GetEntryCount() const { return aEntries.Count(); }
+ SvxIconChoiceCtrlEntry* GetEntry( ULONG nPos ) const { return (SvxIconChoiceCtrlEntry*)aEntries.GetObject(nPos); }
+ SvxIconChoiceCtrlEntry* GetFirstSelectedEntry( ULONG& ) const;
+ SvxIconChoiceCtrlEntry* GetNextSelectedEntry( ULONG& ) const;
+ SvxIconChoiceCtrlEntry* GetHdlEntry() const { return pHdlEntry; }
+ void SetHdlEntry( SvxIconChoiceCtrlEntry* pEntry ) { pHdlEntry = pEntry; }
+
+ SvxIconChoiceCtrlTextMode GetEntryTextModeSmart( const SvxIconChoiceCtrlEntry* pEntry ) const;
+ void SetSelectionMode( SelectionMode eMode ) { eSelectionMode=eMode; }
+ SelectionMode GetSelectionMode() const { return eSelectionMode; }
+ BOOL AreEntriesMoved() const { return (BOOL)((nFlags & F_MOVED_ENTRIES)!=0); }
+ void SetEntriesMoved( BOOL bMoved )
+ {
+ if( bMoved ) nFlags |= F_MOVED_ENTRIES;
+ else nFlags &= ~(F_MOVED_ENTRIES);
+ }
+ ULONG GetEntryListPos( SvxIconChoiceCtrlEntry* ) const;
+ void SetEntryListPos( SvxIconChoiceCtrlEntry* pEntry, ULONG nNewPos );
+ void SetEntryImageSize( const Size& rSize ) { aImageSize = rSize; }
+ void SetEntryFlags( SvxIconChoiceCtrlEntry* pEntry, USHORT nFlags );
+ SvxIconChoiceCtrlEntry* GoLeftRight( SvxIconChoiceCtrlEntry*, BOOL bRight );
+ SvxIconChoiceCtrlEntry* GoUpDown( SvxIconChoiceCtrlEntry*, BOOL bDown );
+ void InitSettings();
+ Rectangle GetOutputRect() const;
+
+ BOOL ArePredecessorsSet() const { return (BOOL)(pHead != 0); }
+ SvxIconChoiceCtrlEntry* GetPredecessorHead() const { return pHead; }
+ void SetEntryPredecessor(SvxIconChoiceCtrlEntry* pEntry,SvxIconChoiceCtrlEntry* pPredecessor);
+ BOOL GetEntryPredecessor(SvxIconChoiceCtrlEntry* pEntry,SvxIconChoiceCtrlEntry** ppPredecessor);
+ // liefert gueltige Ergebnisse nur im AutoArrange-Modus!
+ SvxIconChoiceCtrlEntry* FindEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry, const Point& );
+
+ void SetPositionMode( SvxIconChoiceCtrlPositionMode );
+ SvxIconChoiceCtrlPositionMode GetPositionMode() const { return ePositionMode;}
+
+ void Flush();
+ void SetColumn( USHORT nIndex, const SvxIconChoiceCtrlColumnInfo& );
+ const SvxIconChoiceCtrlColumnInfo* GetColumn( USHORT nIndex ) const;
+ const SvxIconChoiceCtrlColumnInfo* GetItemColumn( USHORT nSubItem, long& rLeft ) const;
+
+ Rectangle GetDocumentRect() const { return Rectangle( Point(), aVirtOutputSize ); }
+ Rectangle GetVisibleRect() const { return GetOutputRect(); }
+
+ void SetEntryHighlightFrame( SvxIconChoiceCtrlEntry* pEntry,BOOL bKeepHighlightFlags=FALSE );
+ void HideEntryHighlightFrame();
+ void DrawHighlightFrame( OutputDevice* pOut,
+ const Rectangle& rBmpRect, BOOL bHide );
+ void StopSelectTimer() { aCallSelectHdlTimer.Stop(); }
+ void Tracking( const TrackingEvent& rTEvt );
+ Point GetPopupMenuPosPixel() const;
+
+ BOOL HandleShortCutKey( const KeyEvent& rKeyEvent );
+
+ void CallEventListeners( ULONG nEvent, void* pData = NULL );
+
+ inline ::svt::IAccessibleFactory&
+ GetAccessibleFactory() { return aAccFactory.getFactory(); }
+};
+
+// ----------------------------------------------------------------------------------------------
+
+class IcnCursor_Impl
+{
+ SvxIconChoiceCtrl_Impl* pView;
+ SvPtrarr* pColumns;
+ SvPtrarr* pRows;
+ long nCols;
+ long nRows;
+ short nDeltaWidth;
+ short nDeltaHeight;
+ SvxIconChoiceCtrlEntry* pCurEntry;
+ void SetDeltas();
+ void ImplCreate();
+ void Create() { if( !pColumns ) ImplCreate(); }
+
+ USHORT GetSortListPos( SvPtrarr* pList, long nValue, int bVertical);
+ SvxIconChoiceCtrlEntry* SearchCol(USHORT nCol,USHORT nTop,USHORT nBottom,USHORT nPref,
+ BOOL bDown, BOOL bSimple );
+
+ SvxIconChoiceCtrlEntry* SearchRow(USHORT nRow,USHORT nRight,USHORT nLeft,USHORT nPref,
+ BOOL bRight, BOOL bSimple );
+
+public:
+ IcnCursor_Impl( SvxIconChoiceCtrl_Impl* pOwner );
+ ~IcnCursor_Impl();
+ void Clear();
+
+ // fuer Cursortravelling usw.
+ SvxIconChoiceCtrlEntry* GoLeftRight( SvxIconChoiceCtrlEntry*, BOOL bRight );
+ SvxIconChoiceCtrlEntry* GoUpDown( SvxIconChoiceCtrlEntry*, BOOL bDown );
+ SvxIconChoiceCtrlEntry* GoPageUpDown( SvxIconChoiceCtrlEntry*, BOOL bDown );
+
+ // Erzeugt fuer jede Zeile (Hoehe=nGridDY) eine nach BoundRect.Left()
+ // sortierte Liste der Eintraege, die in ihr stehen. Eine Liste kann
+ // leer sein. Die Listen gehen in das Eigentum des Rufenden ueber und
+ // muessen mit DestroyGridAdjustData geloescht werden
+ void CreateGridAjustData( SvPtrarr& pLists, SvxIconChoiceCtrlEntry* pRow=0);
+ static void DestroyGridAdjustData( SvPtrarr& rLists );
+};
+
+// ----------------------------------------------------------------------------------------------
+
+typedef ULONG GridId;
+
+#define GRID_NOT_FOUND ((GridId)ULONG_MAX)
+
+class IcnGridMap_Impl
+{
+ Rectangle _aLastOccupiedGrid;
+ SvxIconChoiceCtrl_Impl* _pView;
+ BOOL* _pGridMap;
+ USHORT _nGridCols, _nGridRows;
+
+ void Expand();
+ void Create_Impl();
+ void Create() { if(!_pGridMap) Create_Impl(); }
+
+ void GetMinMapSize( USHORT& rDX, USHORT& rDY ) const;
+
+public:
+ IcnGridMap_Impl(SvxIconChoiceCtrl_Impl* pView);
+ ~IcnGridMap_Impl();
+
+ void Clear();
+
+ GridId GetGrid( const Point& rDocPos, BOOL* pbClipped = 0 );
+ GridId GetGrid( USHORT nGridX, USHORT nGridY );
+ GridId GetUnoccupiedGrid( BOOL bOccupyFound=TRUE );
+
+ void OccupyGrids( const Rectangle&, BOOL bOccupy = TRUE );
+ void OccupyGrids( const SvxIconChoiceCtrlEntry*, BOOL bOccupy = TRUE );
+ void OccupyGrid( GridId nId, BOOL bOccupy = TRUE )
+ {
+ DBG_ASSERT(!_pGridMap || nId<(ULONG)(_nGridCols*_nGridRows),"OccupyGrid: Bad GridId");
+ if(_pGridMap && nId < (ULONG)(_nGridCols *_nGridRows) )
+ _pGridMap[ nId ] = bOccupy;
+ }
+
+ Rectangle GetGridRect( GridId );
+ void GetGridCoord( GridId, USHORT& rGridX, USHORT& rGridY );
+ static ULONG GetGridCount( const Size& rSizePixel, USHORT nGridWidth, USHORT nGridHeight );
+
+ void OutputSizeChanged();
+};
+
+
+
+
+
+#endif
+
+
diff --git a/svtools/source/contnr/imivctl1.cxx b/svtools/source/contnr/imivctl1.cxx
new file mode 100644
index 000000000000..dd2ed992536e
--- /dev/null
+++ b/svtools/source/contnr/imivctl1.cxx
@@ -0,0 +1,4681 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <limits.h>
+#include <tools/debug.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/help.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/poly.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/controllayout.hxx>
+
+#include "ivctrl.hxx"
+#include "imivctl.hxx"
+#include <svtools/svmedit.hxx>
+
+#include <algorithm>
+#include <memory>
+
+#define DD_SCROLL_PIXEL 24
+#define IMPICNVIEW_ACC_RETURN 1
+#define IMPICNVIEW_ACC_ESCAPE 2
+
+#define DRAWTEXT_FLAGS_ICON \
+ ( TEXT_DRAW_CENTER | TEXT_DRAW_TOP | TEXT_DRAW_ENDELLIPSIS | \
+ TEXT_DRAW_CLIP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MNEMONIC )
+
+#define DRAWTEXT_FLAGS_SMALLICON (TEXT_DRAW_LEFT|TEXT_DRAW_ENDELLIPSIS|TEXT_DRAW_CLIP)
+
+#define EVENTID_SHOW_CURSOR ((void*)1)
+#define EVENTID_ADJUST_SCROLLBARS ((void*)2)
+
+struct SvxIconChoiceCtrlEntry_Impl
+{
+ SvxIconChoiceCtrlEntry* _pEntry;
+ Point _aPos;
+ SvxIconChoiceCtrlEntry_Impl( SvxIconChoiceCtrlEntry* pEntry, const Rectangle& rBoundRect )
+ : _pEntry( pEntry), _aPos( rBoundRect.TopLeft()) {}
+};
+
+static BOOL bEndScrollInvalidate = TRUE;
+
+// ----------------------------------------------------------------------------------------------
+
+class IcnViewEdit_Impl : public MultiLineEdit
+{
+ Link aCallBackHdl;
+ Accelerator aAccReturn;
+ Accelerator aAccEscape;
+ Timer aTimer;
+ BOOL bCanceled;
+ BOOL bAlreadyInCallback;
+ BOOL bGrabFocus;
+
+ void CallCallBackHdl_Impl();
+ DECL_LINK( Timeout_Impl, Timer * );
+ DECL_LINK( ReturnHdl_Impl, Accelerator * );
+ DECL_LINK( EscapeHdl_Impl, Accelerator * );
+
+public:
+
+ IcnViewEdit_Impl(
+ SvtIconChoiceCtrl* pParent,
+ const Point& rPos,
+ const Size& rSize,
+ const XubString& rData,
+ const Link& rNotifyEditEnd );
+
+ ~IcnViewEdit_Impl();
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ BOOL EditingCanceled() const { return bCanceled; }
+ void StopEditing( BOOL bCancel = FALSE );
+ BOOL IsGrabFocus() const { return bGrabFocus; }
+};
+
+// ----------------------------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------------------------
+
+SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl( SvtIconChoiceCtrl* pCurView,
+ WinBits nWinStyle ) :
+ aEntries( this ),
+ aVerSBar( pCurView, WB_DRAG | WB_VSCROLL ),
+ aHorSBar( pCurView, WB_DRAG | WB_HSCROLL ),
+ aScrBarBox( pCurView ),
+ aImageSize( 32, 32 ),
+ pColumns( 0 )
+{
+ bChooseWithCursor=FALSE;
+ pEntryPaintDev = 0;
+ pCurEditedEntry = 0;
+ pCurHighlightFrame = 0;
+ pEdit = 0;
+ pAnchor = 0;
+ pDraggedSelection = 0;
+ pPrevDropTarget = 0;
+ pHdlEntry = 0;
+ pHead = NULL;
+ pCursor = NULL;
+ bUpdateMode = TRUE;
+ bEntryEditingEnabled = FALSE;
+ bInDragDrop = FALSE;
+ bHighlightFramePressed = FALSE;
+ eSelectionMode = MULTIPLE_SELECTION;
+ pView = pCurView;
+ pZOrderList = new List; //SvPtrarr;
+ ePositionMode = IcnViewPositionModeFree;
+ SetStyle( nWinStyle );
+ nFlags = 0;
+ nUserEventAdjustScrBars = 0;
+ nUserEventShowCursor = 0;
+ nMaxVirtWidth = DEFAULT_MAX_VIRT_WIDTH;
+ nMaxVirtHeight = DEFAULT_MAX_VIRT_HEIGHT;
+ pDDRefEntry = 0;
+ pDDDev = 0;
+ pDDBufDev = 0;
+ pDDTempDev = 0;
+ eTextMode = IcnShowTextShort;
+ pImpCursor = new IcnCursor_Impl( this );
+ pGridMap = new IcnGridMap_Impl( this );
+
+ aVerSBar.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, ScrollUpDownHdl ) );
+ aHorSBar.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, ScrollLeftRightHdl ) );
+ Link aEndScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, EndScrollHdl ) );
+ aVerSBar.SetEndScrollHdl( aEndScrollHdl );
+ aHorSBar.SetEndScrollHdl( aEndScrollHdl );
+
+ nHorSBarHeight = aHorSBar.GetSizePixel().Height();
+ nVerSBarWidth = aVerSBar.GetSizePixel().Width();
+
+ aEditTimer.SetTimeout( 800 );
+ aEditTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,EditTimeoutHdl));
+ aAutoArrangeTimer.SetTimeout( 100 );
+ aAutoArrangeTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,AutoArrangeHdl));
+ aCallSelectHdlTimer.SetTimeout( 500 );
+ aCallSelectHdlTimer.SetTimeoutHdl( LINK(this,SvxIconChoiceCtrl_Impl,CallSelectHdlHdl));
+
+ aDocRectChangedTimer.SetTimeout( 50 );
+ aDocRectChangedTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,DocRectChangedHdl));
+ aVisRectChangedTimer.SetTimeout( 50 );
+ aVisRectChangedTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,VisRectChangedHdl));
+
+ Clear( TRUE );
+
+ SetGrid( Size(100, 70) );
+}
+
+SvxIconChoiceCtrl_Impl::~SvxIconChoiceCtrl_Impl()
+{
+ pCurEditedEntry = 0;
+ DELETEZ(pEdit);
+ Clear();
+ StopEditTimer();
+ CancelUserEvents();
+ delete pZOrderList;
+ delete pImpCursor;
+ delete pGridMap;
+ delete pDDDev;
+ delete pDDBufDev;
+ delete pDDTempDev;
+ delete pDraggedSelection;
+ delete pEntryPaintDev;
+ ClearSelectedRectList();
+ ClearColumnList();
+}
+
+void SvxIconChoiceCtrl_Impl::Clear( BOOL bInCtor )
+{
+ StopEntryEditing( TRUE );
+ nSelectionCount = 0;
+ DELETEZ(pDraggedSelection);
+ bInDragDrop = FALSE;
+ pCurHighlightFrame = 0;
+ StopEditTimer();
+ CancelUserEvents();
+ ShowCursor( FALSE );
+ bBoundRectsDirty = FALSE;
+ nMaxBoundHeight = 0;
+
+ nFlags &= ~(F_PAINTED | F_MOVED_ENTRIES);
+ pCursor = 0;
+ if( !bInCtor )
+ {
+ pImpCursor->Clear();
+ pGridMap->Clear();
+ aVirtOutputSize.Width() = 0;
+ aVirtOutputSize.Height() = 0;
+ Size aSize( pView->GetOutputSizePixel() );
+ nMaxVirtWidth = aSize.Width() - nVerSBarWidth;
+ if( nMaxVirtWidth <= 0 )
+ nMaxVirtWidth = DEFAULT_MAX_VIRT_WIDTH;
+ nMaxVirtHeight = aSize.Height() - nHorSBarHeight;
+ if( nMaxVirtHeight <= 0 )
+ nMaxVirtHeight = DEFAULT_MAX_VIRT_HEIGHT;
+ pZOrderList->Clear(); //Remove(0,pZOrderList->Count());
+ SetOrigin( Point() );
+ if( bUpdateMode )
+ pView->Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ AdjustScrollBars();
+ ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ delete pCur;
+ }
+ aEntries.Clear();
+ DocRectChanged();
+ VisRectChanged();
+}
+
+void SvxIconChoiceCtrl_Impl::SetStyle( WinBits nWinStyle )
+{
+ nWinBits = nWinStyle;
+ nCurTextDrawFlags = DRAWTEXT_FLAGS_ICON;
+ if( nWinBits & (WB_SMALLICON | WB_DETAILS) )
+ nCurTextDrawFlags = DRAWTEXT_FLAGS_SMALLICON;
+ if( nWinBits & WB_NOSELECTION )
+ eSelectionMode = NO_SELECTION;
+ if( !(nWinStyle & (WB_ALIGN_TOP | WB_ALIGN_LEFT)))
+ nWinBits |= WB_ALIGN_LEFT;
+ if( (nWinStyle & WB_DETAILS))
+ {
+ if( !pColumns )
+ SetColumn( 0, SvxIconChoiceCtrlColumnInfo( 0, 100, IcnViewAlignLeft ));
+ }
+}
+
+IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollUpDownHdl, ScrollBar*, pScrollBar )
+{
+ StopEntryEditing( TRUE );
+ // Pfeil hoch: delta=-1; Pfeil runter: delta=+1
+ Scroll( 0, pScrollBar->GetDelta(), TRUE );
+ bEndScrollInvalidate = TRUE;
+ return 0;
+}
+
+IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollLeftRightHdl, ScrollBar*, pScrollBar )
+{
+ StopEntryEditing( TRUE );
+ // Pfeil links: delta=-1; Pfeil rechts: delta=+1
+ Scroll( pScrollBar->GetDelta(), 0, TRUE );
+ bEndScrollInvalidate = TRUE;
+ return 0;
+}
+
+IMPL_LINK( SvxIconChoiceCtrl_Impl, EndScrollHdl, void*, EMPTYARG )
+{
+ if( pView->HasBackground() && !pView->GetBackground().IsScrollable() &&
+ bEndScrollInvalidate )
+ {
+ pView->Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ return 0;
+}
+
+void SvxIconChoiceCtrl_Impl::FontModified()
+{
+ StopEditTimer();
+ DELETEZ(pDDDev);
+ DELETEZ(pDDBufDev);
+ DELETEZ(pDDTempDev);
+ DELETEZ(pEntryPaintDev);
+ SetDefaultTextSize();
+ ShowCursor( FALSE );
+ ShowCursor( TRUE );
+}
+
+void SvxIconChoiceCtrl_Impl::InsertEntry( SvxIconChoiceCtrlEntry* pEntry, ULONG nPos,
+ const Point* pPos )
+{
+ StopEditTimer();
+ aEntries.Insert( pEntry, nPos );
+ if( (nFlags & F_ENTRYLISTPOS_VALID) && nPos >= aEntries.Count() - 1 )
+ pEntry->nPos = aEntries.Count() - 1;
+ else
+ nFlags &= ~F_ENTRYLISTPOS_VALID;
+
+ pZOrderList->Insert( (void*)pEntry, LIST_APPEND ); //pZOrderList->Count() );
+ pImpCursor->Clear();
+// pGridMap->Clear();
+ if( pPos )
+ {
+ Size aSize( CalcBoundingSize( pEntry ) );
+ SetBoundingRect_Impl( pEntry, *pPos, aSize );
+ SetEntryPos( pEntry, *pPos, FALSE, TRUE, TRUE /*keep grid map*/ );
+ pEntry->nFlags |= ICNVIEW_FLAG_POS_MOVED;
+ SetEntriesMoved( TRUE );
+ }
+ else
+ {
+ // wenn der UpdateMode TRUE ist, wollen wir nicht pauschal alle
+ // BoundRects auf 'zu ueberpruefen' setzen, sondern nur das des
+ // neuen Eintrags. Deshalb kein InvalidateBoundingRect aufrufen!
+ pEntry->aRect.Right() = LONG_MAX;
+ if( bUpdateMode )
+ {
+ FindBoundingRect( pEntry );
+ Rectangle aOutputArea( GetOutputRect() );
+ pGridMap->OccupyGrids( pEntry );
+ if( !aOutputArea.IsOver( pEntry->aRect ) )
+ return; // ist nicht sichtbar
+ pView->Invalidate( pEntry->aRect );
+ }
+ else
+ InvalidateBoundingRect( pEntry->aRect );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::CreateAutoMnemonics( MnemonicGenerator* _pGenerator )
+{
+ ::std::auto_ptr< MnemonicGenerator > pAutoDeleteOwnGenerator;
+ if ( !_pGenerator )
+ {
+ _pGenerator = new MnemonicGenerator;
+ pAutoDeleteOwnGenerator.reset( _pGenerator );
+ }
+
+ ULONG nEntryCount = GetEntryCount();
+ ULONG i;
+
+ // insert texts in generator
+ for( i = 0; i < nEntryCount; ++i )
+ {
+ DBG_ASSERT( GetEntry( i ), "-SvxIconChoiceCtrl_Impl::CreateAutoMnemonics(): more expected than provided!" );
+
+ _pGenerator->RegisterMnemonic( GetEntry( i )->GetText() );
+ }
+
+ // exchange texts with generated mnemonics
+ for( i = 0; i < nEntryCount; ++i )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry( i );
+ String aTxt = pEntry->GetText();
+
+ if( _pGenerator->CreateMnemonic( aTxt ) )
+ pEntry->SetText( aTxt );
+ }
+}
+
+Rectangle SvxIconChoiceCtrl_Impl::GetOutputRect() const
+{
+ Point aOrigin( pView->GetMapMode().GetOrigin() );
+ aOrigin *= -1;
+ return Rectangle( aOrigin, aOutputSize );
+}
+
+void SvxIconChoiceCtrl_Impl::SetListPositions()
+{
+ if( nFlags & F_ENTRYLISTPOS_VALID )
+ return;
+
+ ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ pEntry->nPos = nCur;
+ }
+ nFlags |= F_ENTRYLISTPOS_VALID;
+}
+
+void SvxIconChoiceCtrl_Impl::RemoveEntry( SvxIconChoiceCtrlEntry* pEntry )
+{
+ BOOL bSyncSingleSelection;
+ // bei Single-Selection wird die Selektion beim Umsetzen des Cursors
+ // mitgefuehrt. Das soll aber nur erfolgen, wenn ueberhaupt ein
+ // Eintrag selektiert ist.
+ if( GetSelectionCount() )
+ bSyncSingleSelection = TRUE;
+ else
+ bSyncSingleSelection = FALSE;
+
+ if( pEntry == pCurHighlightFrame )
+ pCurHighlightFrame = 0;
+
+ if( bInDragDrop )
+ {
+ DELETEZ(pDraggedSelection);
+ bInDragDrop = FALSE;
+ }
+
+ if( pEntry->IsSelected() )
+ CallSelectHandler( 0 );
+
+ if( aEntries.Count() == 1 && aEntries.GetObject(0) == pEntry )
+ {
+ Clear();
+ return;
+ }
+
+ StopEditTimer();
+ if( pEntry == pAnchor )
+ pAnchor = 0;
+ if( pEntry->IsSelected() )
+ nSelectionCount--;
+ BOOL bEntryBoundValid = IsBoundingRectValid( pEntry->aRect );
+ if( bEntryBoundValid )
+ pView->Invalidate( pEntry->aRect );
+
+ BOOL bSetNewCursor = FALSE;
+ SvxIconChoiceCtrlEntry* pNewCursor = NULL;
+
+ if( pEntry == pCursor )
+ {
+ bSetNewCursor = TRUE;
+ pNewCursor = FindNewCursor();
+ ShowCursor( FALSE );
+ pCursor = 0;
+ }
+
+ BOOL bCurEntryPosValid = (nFlags & F_ENTRYLISTPOS_VALID) ? TRUE : FALSE;
+ if( bCurEntryPosValid && aEntries.GetObject(aEntries.Count()-1) != pEntry )
+ nFlags &= ~F_ENTRYLISTPOS_VALID;
+ ULONG nPos = pZOrderList->GetPos( (void*)pEntry );
+ pZOrderList->Remove( nPos );
+ if( bCurEntryPosValid )
+ {
+ DBG_ASSERT(aEntries.GetObject(pEntry->nPos)==pEntry,"RemoveEntry: Wrong nPos in entry");
+ aEntries.Remove( pEntry->nPos );
+ }
+ else
+ aEntries.Remove( pEntry );
+ pImpCursor->Clear();
+ pGridMap->Clear();
+ delete pEntry;
+ if( IsAutoArrange() && aEntries.Count() )
+ aAutoArrangeTimer.Start();
+ if( bSetNewCursor )
+ {
+ // Fokusrechteck asynchron einblenden, um das Loeschen einer
+ // Multiselektion zu beschleunigen.
+ SetCursor( pNewCursor, bSyncSingleSelection, TRUE );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::SelectEntry( SvxIconChoiceCtrlEntry* pEntry, BOOL bSelect,
+ BOOL bCallHdl, BOOL bAdd, BOOL bSyncPaint )
+{
+ if( eSelectionMode == NO_SELECTION )
+ return;
+
+ if( !bAdd )
+ {
+ if ( 0 == ( nFlags & F_CLEARING_SELECTION ) )
+ {
+ nFlags |= F_CLEARING_SELECTION;
+ DeselectAllBut( pEntry, sal_True );
+ nFlags &= ~F_CLEARING_SELECTION;
+ }
+ }
+ if( pEntry->IsSelected() != bSelect )
+ {
+ pHdlEntry = pEntry;
+ USHORT nEntryFlags = pEntry->GetFlags();
+ if( bSelect )
+ {
+ nEntryFlags |= ICNVIEW_FLAG_SELECTED;
+ pEntry->AssignFlags( nEntryFlags );
+ nSelectionCount++;
+ if( bCallHdl )
+ CallSelectHandler( pEntry );
+ }
+ else
+ {
+ nEntryFlags &= ~( ICNVIEW_FLAG_SELECTED);
+ pEntry->AssignFlags( nEntryFlags );
+ nSelectionCount--;
+ if( bCallHdl )
+ CallSelectHandler( 0 );
+ }
+ EntrySelected( pEntry, bSelect, bSyncPaint );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::EntrySelected( SvxIconChoiceCtrlEntry* pEntry, BOOL bSelect,
+ BOOL bSyncPaint )
+{
+ // bei SingleSelection dafuer sorgen, dass der Cursor immer
+ // auf dem (einzigen) selektierten Eintrag steht. Aber nur,
+ // wenn es bereits einen Cursor gibt
+ if( bSelect && pCursor &&
+ eSelectionMode == SINGLE_SELECTION &&
+ pEntry != pCursor )
+ {
+ SetCursor( pEntry );
+ //DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?")
+ }
+
+ // beim Aufziehen nicht, da sonst die Schleife in SelectRect
+ // nicht richtig funktioniert!
+ if( !(nFlags & F_SELECTING_RECT) )
+ ToTop( pEntry );
+ if( bUpdateMode )
+ {
+ if( pEntry == pCursor )
+ ShowCursor( FALSE );
+ if( pView->IsTracking() && (bSelect || !pView->HasBackground()) ) // beim Tracken immer synchron
+ PaintEntry( pEntry );
+ else if( bSyncPaint ) // synchron & mit virtuellem OutDev!
+ PaintEntryVirtOutDev( pEntry );
+ else
+ {
+ pView->Invalidate( CalcFocusRect( pEntry ) );
+ }
+ if( pEntry == pCursor )
+ ShowCursor( TRUE );
+ } // if( bUpdateMode )
+
+ // --> OD 2009-05-27 #i101012#
+ // emit vcl event LISTBOX_SELECT only in case that the given entry is selected.
+ if ( bSelect )
+ {
+ CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );
+ }
+ // <--
+}
+
+void SvxIconChoiceCtrl_Impl::ResetVirtSize()
+{
+ StopEditTimer();
+ aVirtOutputSize.Width() = 0;
+ aVirtOutputSize.Height() = 0;
+ BOOL bLockedEntryFound = FALSE;
+ const ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ pCur->ClearFlags( ICNVIEW_FLAG_POS_MOVED );
+ if( pCur->IsPosLocked() )
+ {
+ // VirtSize u.a. anpassen
+ if( !IsBoundingRectValid( pCur->aRect ) )
+ FindBoundingRect( pCur );
+ else
+ AdjustVirtSize( pCur->aRect );
+ bLockedEntryFound = TRUE;
+ }
+ else
+ InvalidateBoundingRect( pCur->aRect );
+ }
+
+ if( !(nWinBits & (WB_NOVSCROLL | WB_NOHSCROLL)) )
+ {
+ Size aRealOutputSize( pView->GetOutputSizePixel() );
+ if( aVirtOutputSize.Width() < aRealOutputSize.Width() ||
+ aVirtOutputSize.Height() < aRealOutputSize.Height() )
+ {
+ ULONG nGridCount = IcnGridMap_Impl::GetGridCount(
+ aRealOutputSize, (USHORT)nGridDX, (USHORT)nGridDY );
+ if( nGridCount < nCount )
+ {
+ if( nWinBits & WB_ALIGN_TOP )
+ nMaxVirtWidth = aRealOutputSize.Width() - nVerSBarWidth;
+ else // WB_ALIGN_LEFT
+ nMaxVirtHeight = aRealOutputSize.Height() - nHorSBarHeight;
+ }
+ }
+ }
+
+ pImpCursor->Clear();
+ pGridMap->Clear();
+ VisRectChanged();
+}
+
+void SvxIconChoiceCtrl_Impl::AdjustVirtSize( const Rectangle& rRect )
+{
+ long nHeightOffs = 0;
+ long nWidthOffs = 0;
+
+ if( aVirtOutputSize.Width() < (rRect.Right()+LROFFS_WINBORDER) )
+ nWidthOffs = (rRect.Right()+LROFFS_WINBORDER) - aVirtOutputSize.Width();
+
+ if( aVirtOutputSize.Height() < (rRect.Bottom()+TBOFFS_WINBORDER) )
+ nHeightOffs = (rRect.Bottom()+TBOFFS_WINBORDER) - aVirtOutputSize.Height();
+
+ if( nWidthOffs || nHeightOffs )
+ {
+ Range aRange;
+ aVirtOutputSize.Width() += nWidthOffs;
+ aRange.Max() = aVirtOutputSize.Width();
+ aHorSBar.SetRange( aRange );
+
+ aVirtOutputSize.Height() += nHeightOffs;
+ aRange.Max() = aVirtOutputSize.Height();
+ aVerSBar.SetRange( aRange );
+
+ pImpCursor->Clear();
+ pGridMap->OutputSizeChanged();
+ AdjustScrollBars();
+ DocRectChanged();
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::InitPredecessors()
+{
+ DBG_ASSERT(!pHead,"SvxIconChoiceCtrl_Impl::InitPredecessors() >> Already initialized");
+ ULONG nCount = aEntries.Count();
+ if( nCount )
+ {
+ SvxIconChoiceCtrlEntry* pPrev = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 );
+ for( ULONG nCur = 1; nCur <= nCount; nCur++ )
+ {
+ pPrev->ClearFlags( ICNVIEW_FLAG_POS_LOCKED | ICNVIEW_FLAG_POS_MOVED |
+ ICNVIEW_FLAG_PRED_SET);
+
+ SvxIconChoiceCtrlEntry* pNext;
+ if( nCur == nCount )
+ pNext = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 );
+ else
+ pNext = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ pPrev->pflink = pNext;
+ pNext->pblink = pPrev;
+ pPrev = pNext;
+ }
+ pHead = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 );
+ }
+ else
+ pHead = 0;
+ nFlags &= ~F_MOVED_ENTRIES;
+}
+
+void SvxIconChoiceCtrl_Impl::ClearPredecessors()
+{
+ if( pHead )
+ {
+ ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ pCur->pflink = 0;
+ pCur->pblink = 0;
+ pCur->ClearFlags( ICNVIEW_FLAG_PRED_SET );
+ }
+ pHead = 0;
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::Arrange( BOOL bKeepPredecessors, long nSetMaxVirtWidth, long nSetMaxVirtHeight )
+{
+ if ( nSetMaxVirtWidth != 0 )
+ nMaxVirtWidth = nSetMaxVirtWidth;
+ else
+ nMaxVirtWidth = aOutputSize.Width();
+
+ if ( nSetMaxVirtHeight != 0 )
+ nMaxVirtHeight = nSetMaxVirtHeight;
+ else
+ nMaxVirtHeight = aOutputSize.Height();
+
+ ImpArrange( bKeepPredecessors );
+}
+
+void SvxIconChoiceCtrl_Impl::ImpArrange( BOOL bKeepPredecessors )
+{
+ static Point aEmptyPoint;
+
+ BOOL bOldUpdate = bUpdateMode;
+ Rectangle aCurOutputArea( GetOutputRect() );
+ if( (nWinBits & WB_SMART_ARRANGE) && aCurOutputArea.TopLeft() != aEmptyPoint )
+ bUpdateMode = FALSE;
+ aAutoArrangeTimer.Stop();
+ nFlags &= ~F_MOVED_ENTRIES;
+ nFlags |= F_ARRANGING;
+ StopEditTimer();
+ ShowCursor( FALSE );
+ ResetVirtSize();
+ if( !bKeepPredecessors )
+ ClearPredecessors();
+ bBoundRectsDirty = FALSE;
+ SetOrigin( Point() );
+ VisRectChanged();
+ RecalcAllBoundingRectsSmart();
+ // in der Detailsview muss das Invalidieren intelligenter erfolgen
+ //if( !(nWinBits & WB_DETAILS ))
+ pView->Invalidate( INVALIDATE_NOCHILDREN );
+ nFlags &= ~F_ARRANGING;
+ if( (nWinBits & WB_SMART_ARRANGE) && aCurOutputArea.TopLeft() != aEmptyPoint )
+ {
+ MakeVisible( aCurOutputArea );
+ SetUpdateMode( bOldUpdate );
+ }
+ ShowCursor( TRUE );
+}
+
+void SvxIconChoiceCtrl_Impl::Paint( const Rectangle& rRect )
+{
+ bEndScrollInvalidate = FALSE;
+
+#if defined(OV_DRAWGRID)
+ Color aOldColor ( pView->GetLineColor() );
+ Color aColor( COL_BLACK );
+ pView->SetLineColor( aColor );
+ Point aOffs( pView->GetMapMode().GetOrigin());
+ Size aXSize( pView->GetOutputSizePixel() );
+
+ {
+ Point aStart( LROFFS_WINBORDER, 0 );
+ Point aEnd( LROFFS_WINBORDER, aXSize.Height());
+ aStart -= aOffs;
+ aEnd -= aOffs;
+ pView->DrawLine( aStart, aEnd );
+ }
+ {
+ Point aStart( 0, TBOFFS_WINBORDER );
+ Point aEnd( aXSize.Width(), TBOFFS_WINBORDER );
+ aStart -= aOffs;
+ aEnd -= aOffs;
+ pView->DrawLine( aStart, aEnd );
+ }
+
+ for( long nDX = nGridDX; nDX <= aXSize.Width(); nDX += nGridDX )
+ {
+ Point aStart( nDX+LROFFS_WINBORDER, 0 );
+ Point aEnd( nDX+LROFFS_WINBORDER, aXSize.Height());
+ aStart -= aOffs;
+ aEnd -= aOffs;
+ pView->DrawLine( aStart, aEnd );
+ }
+ for( long nDY = nGridDY; nDY <= aXSize.Height(); nDY += nGridDY )
+ {
+ Point aStart( 0, nDY+TBOFFS_WINBORDER );
+ Point aEnd( aXSize.Width(), nDY+TBOFFS_WINBORDER );
+ aStart -= aOffs;
+ aEnd -= aOffs;
+ pView->DrawLine( aStart, aEnd );
+ }
+ pView->SetLineColor( aOldColor );
+#endif
+ nFlags |= F_PAINTED;
+
+ if( !aEntries.Count() )
+ return;
+ if( !pCursor )
+ {
+ // set cursor to item with focus-flag
+ BOOL bfound = FALSE;
+ for ( ULONG i = 0; i < pView->GetEntryCount() && !bfound; i++)
+ {
+ SvxIconChoiceCtrlEntry* pEntry = pView->GetEntry ( i );
+ if( pEntry->IsFocused() )
+ {
+ pCursor = pEntry;
+ bfound=TRUE;
+ }
+ }
+
+ if( !bfound )
+ pCursor = (SvxIconChoiceCtrlEntry*)aEntries.First();
+ }
+
+ // Show Focus at Init-Time
+ if ( pView->HasFocus() )
+ GetFocus();
+
+ ULONG nCount = pZOrderList->Count();
+ if( !nCount )
+ return;
+
+ BOOL bResetClipRegion = FALSE;
+ if( !pView->IsClipRegion() )
+ {
+ Rectangle aOutputArea( GetOutputRect() );
+ bResetClipRegion = TRUE;
+ pView->SetClipRegion( aOutputArea );
+ }
+
+ const USHORT nListInitSize = aEntries.Count() > USHRT_MAX ?
+ USHRT_MAX : (USHORT)aEntries.Count();
+ List* pNewZOrderList = new List( nListInitSize );
+ List* pPaintedEntries = new List( nListInitSize );
+
+ ULONG nPos = 0;
+ while( nCount )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nPos ));
+ const Rectangle& rBoundRect = GetEntryBoundRect( pEntry );
+ if( rRect.IsOver( rBoundRect ) )
+ {
+ PaintEntry( pEntry, rBoundRect.TopLeft(), pView, TRUE );
+ // Eintraege, die neu gezeichnet werden, auf Top setzen
+ pPaintedEntries->Insert( pEntry, LIST_APPEND );
+ }
+ else
+ pNewZOrderList->Insert( pEntry, LIST_APPEND );
+
+ nCount--;
+ nPos++;
+ }
+ delete pZOrderList;
+ pZOrderList = pNewZOrderList;
+ nCount = pPaintedEntries->Count();
+ if( nCount )
+ {
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ pZOrderList->Insert( pPaintedEntries->GetObject(nCur), LIST_APPEND);
+ }
+ delete pPaintedEntries;
+
+ if( bResetClipRegion )
+ pView->SetClipRegion();
+}
+
+void SvxIconChoiceCtrl_Impl::RepaintEntries( USHORT nEntryFlagsMask )
+{
+ const ULONG nCount = pZOrderList->Count();
+ if( !nCount )
+ return;
+
+ BOOL bResetClipRegion = FALSE;
+ Rectangle aOutRect( GetOutputRect() );
+ if( !pView->IsClipRegion() )
+ {
+ bResetClipRegion = TRUE;
+ pView->SetClipRegion( aOutRect );
+ }
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nCur));
+ if( pEntry->GetFlags() & nEntryFlagsMask )
+ {
+ const Rectangle& rBoundRect = GetEntryBoundRect( pEntry );
+ if( aOutRect.IsOver( rBoundRect ) )
+ PaintEntry( pEntry, rBoundRect.TopLeft() );
+ }
+ }
+ if( bResetClipRegion )
+ pView->SetClipRegion();
+}
+
+
+void SvxIconChoiceCtrl_Impl::InitScrollBarBox()
+{
+ aScrBarBox.SetSizePixel( Size(nVerSBarWidth-1, nHorSBarHeight-1) );
+ Size aSize( pView->GetOutputSizePixel() );
+ aScrBarBox.SetPosPixel( Point(aSize.Width()-nVerSBarWidth+1, aSize.Height()-nHorSBarHeight+1));
+}
+
+IcnViewFieldType SvxIconChoiceCtrl_Impl::GetItem( SvxIconChoiceCtrlEntry* pEntry,
+ const Point& rAbsPos )
+{
+ Rectangle aRect( CalcTextRect( pEntry ) );
+ if( aRect.IsInside( rAbsPos ) )
+ return IcnViewFieldTypeText;
+
+ aRect = CalcBmpRect( pEntry );
+ if( aRect.IsInside( rAbsPos ) )
+ return IcnViewFieldTypeImage;
+
+ return IcnViewFieldTypeDontknow;
+}
+
+BOOL SvxIconChoiceCtrl_Impl::MouseButtonDown( const MouseEvent& rMEvt)
+{
+ BOOL bHandled = TRUE;
+ bHighlightFramePressed = FALSE;
+ StopEditTimer();
+ BOOL bGotFocus = (BOOL)(!pView->HasFocus() && !(nWinBits & WB_NOPOINTERFOCUS));
+ if( !(nWinBits & WB_NOPOINTERFOCUS) )
+ pView->GrabFocus();
+
+ Point aDocPos( rMEvt.GetPosPixel() );
+ if(aDocPos.X()>=aOutputSize.Width() || aDocPos.Y()>=aOutputSize.Height())
+ return FALSE;
+ ToDocPos( aDocPos );
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, TRUE );
+ if( pEntry )
+ MakeEntryVisible( pEntry, FALSE );
+
+ if( rMEvt.IsShift() && eSelectionMode != SINGLE_SELECTION )
+ {
+ if( pEntry )
+ SetCursor_Impl( pCursor, pEntry, rMEvt.IsMod1(), rMEvt.IsShift(), TRUE);
+ return TRUE;
+ }
+
+ if( pAnchor && (rMEvt.IsShift() || rMEvt.IsMod1())) // Tastaturselektion?
+ {
+ DBG_ASSERT(eSelectionMode != SINGLE_SELECTION,"Invalid selection mode");
+ if( rMEvt.IsMod1() )
+ nFlags |= F_ADD_MODE;
+
+ if( rMEvt.IsShift() )
+ {
+ Rectangle aRect( GetEntryBoundRect( pAnchor ));
+ if( pEntry )
+ aRect.Union( GetEntryBoundRect( pEntry ) );
+ else
+ {
+ Rectangle aTempRect( aDocPos, Size(1,1));
+ aRect.Union( aTempRect );
+ }
+ aCurSelectionRect = aRect;
+ SelectRect( aRect, (nFlags & F_ADD_MODE)!=0, &aSelectedRectList );
+ }
+ else if( rMEvt.IsMod1() )
+ {
+ AddSelectedRect( aCurSelectionRect );
+ pAnchor = 0;
+ aCurSelectionRect.SetPos( aDocPos );
+ }
+
+ if( !pEntry && !(nWinBits & WB_NODRAGSELECTION))
+ pView->StartTracking( STARTTRACK_SCROLLREPEAT );
+ return TRUE;
+ }
+ else
+ {
+ if( !pEntry )
+ {
+ if( eSelectionMode == MULTIPLE_SELECTION )
+ {
+ if( !rMEvt.IsMod1() ) // Ctrl
+ {
+ if( !bGotFocus )
+ {
+ SetNoSelection();
+ ClearSelectedRectList();
+ }
+ }
+ else
+ nFlags |= F_ADD_MODE;
+ aCurSelectionRect.SetPos( aDocPos );
+ pView->StartTracking( STARTTRACK_SCROLLREPEAT );
+ }
+ else
+ bHandled = FALSE;
+ return bHandled;
+ }
+ }
+ BOOL bSelected = pEntry->IsSelected();
+ BOOL bEditingEnabled = IsEntryEditingEnabled();
+
+ if( rMEvt.GetClicks() == 2 )
+ {
+ DeselectAllBut( pEntry );
+ SelectEntry( pEntry, TRUE, TRUE, FALSE, TRUE );
+ pHdlEntry = pEntry;
+ pView->ClickIcon();
+ }
+ else
+ {
+ // Inplace-Editing ?
+ if( rMEvt.IsMod2() ) // Alt?
+ {
+ if( bEntryEditingEnabled && pEntry &&
+ pEntry->IsSelected())
+ {
+ if( pView->EditingEntry( pEntry ))
+ EditEntry( pEntry );
+ }
+ }
+ else if( eSelectionMode == SINGLE_SELECTION )
+ {
+ DeselectAllBut( pEntry );
+ SetCursor( pEntry );
+ if( bEditingEnabled && bSelected && !rMEvt.GetModifier() &&
+ rMEvt.IsLeft() && IsTextHit( pEntry, aDocPos ) )
+ {
+ nFlags |= F_START_EDITTIMER_IN_MOUSEUP;
+ }
+ }
+ else if( eSelectionMode == NO_SELECTION )
+ {
+ if( rMEvt.IsLeft() && (nWinBits & WB_HIGHLIGHTFRAME) )
+ {
+ pCurHighlightFrame = 0; // Neues painten des Frames erzwingen
+ bHighlightFramePressed = TRUE;
+ SetEntryHighlightFrame( pEntry, TRUE );
+ }
+ }
+ else
+ {
+ if( !rMEvt.GetModifier() && rMEvt.IsLeft() )
+ {
+ if( !bSelected )
+ {
+ DeselectAllBut( pEntry, TRUE /* Synchron painten */ );
+ SetCursor( pEntry );
+ SelectEntry( pEntry, TRUE, TRUE, FALSE, TRUE );
+ }
+ else
+ {
+ // erst im Up deselektieren, falls Move per D&D!
+ nFlags |= F_DOWN_DESELECT;
+ if( bEditingEnabled && IsTextHit( pEntry, aDocPos ) &&
+ rMEvt.IsLeft())
+ {
+ nFlags |= F_START_EDITTIMER_IN_MOUSEUP;
+ }
+ }
+ }
+ else if( rMEvt.IsMod1() )
+ nFlags |= F_DOWN_CTRL;
+ }
+ }
+ return bHandled;
+}
+
+BOOL SvxIconChoiceCtrl_Impl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ BOOL bHandled = FALSE;
+ if( rMEvt.IsRight() && (nFlags & (F_DOWN_CTRL | F_DOWN_DESELECT) ))
+ {
+ nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
+ bHandled = TRUE;
+ }
+
+ Point aDocPos( rMEvt.GetPosPixel() );
+ ToDocPos( aDocPos );
+ SvxIconChoiceCtrlEntry* pDocEntry = GetEntry( aDocPos );
+ if( pDocEntry )
+ {
+ if( nFlags & F_DOWN_CTRL )
+ {
+ // Ctrl & MultiSelection
+ ToggleSelection( pDocEntry );
+ SetCursor( pDocEntry );
+ bHandled = TRUE;
+ }
+ else if( nFlags & F_DOWN_DESELECT )
+ {
+ DeselectAllBut( pDocEntry );
+ SetCursor( pDocEntry );
+ SelectEntry( pDocEntry, TRUE, TRUE, FALSE, TRUE );
+ bHandled = TRUE;
+ }
+ }
+
+ nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
+ if( nFlags & F_START_EDITTIMER_IN_MOUSEUP )
+ {
+ bHandled = TRUE;
+ StartEditTimer();
+ nFlags &= ~F_START_EDITTIMER_IN_MOUSEUP;
+ }
+
+ if((nWinBits & WB_HIGHLIGHTFRAME) && bHighlightFramePressed && pCurHighlightFrame)
+ {
+ bHandled = TRUE;
+ SvxIconChoiceCtrlEntry* pEntry = pCurHighlightFrame;
+ pCurHighlightFrame = 0; // Neues painten des Frames erzwingen
+ bHighlightFramePressed = FALSE;
+ SetEntryHighlightFrame( pEntry, TRUE );
+#if 0
+ CallSelectHandler( pCurHighlightFrame );
+#else
+ pHdlEntry = pCurHighlightFrame;
+ pView->ClickIcon();
+
+ // set focus on Icon
+ SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
+ SetCursor_Impl( pOldCursor, pHdlEntry, FALSE, FALSE, TRUE );
+#endif
+ pHdlEntry = 0;
+ }
+ return bHandled;
+}
+
+BOOL SvxIconChoiceCtrl_Impl::MouseMove( const MouseEvent& rMEvt )
+{
+ const Point aDocPos( pView->PixelToLogic(rMEvt.GetPosPixel()) );
+
+ if( pView->IsTracking() )
+ return FALSE;
+ else if( nWinBits & WB_HIGHLIGHTFRAME )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, TRUE );
+ SetEntryHighlightFrame( pEntry );
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+void SvxIconChoiceCtrl_Impl::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ // Das Rechteck darf nicht "justified" sein, da seine
+ // TopLeft-Position u.U. zur Berechnung eines Ankers
+ // benutzt wird.
+ AddSelectedRect( aCurSelectionRect );
+ pView->HideTracking();
+ nFlags &= ~(F_ADD_MODE);
+ if( rTEvt.IsTrackingCanceled() )
+ SetNoSelection();
+ }
+ else
+ {
+ Point aPosPixel = rTEvt.GetMouseEvent().GetPosPixel();
+ Point aDocPos( aPosPixel );
+ ToDocPos( aDocPos );
+
+ long nScrollDX, nScrollDY;
+
+ CalcScrollOffsets( aPosPixel, nScrollDX, nScrollDY, FALSE );
+ if( nScrollDX || nScrollDY )
+ {
+ pView->HideTracking();
+ pView->Scroll( nScrollDX, nScrollDY );
+ }
+ Rectangle aRect( aCurSelectionRect.TopLeft(), aDocPos );
+ if( aRect != aCurSelectionRect )
+ {
+ pView->HideTracking();
+ BOOL bAdd = (nFlags & F_ADD_MODE) ? TRUE : FALSE;
+ SelectRect( aRect, bAdd, &aSelectedRectList );
+ }
+ pView->ShowTracking( aRect, SHOWTRACK_SMALL | SHOWTRACK_CLIP );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::SetCursor_Impl( SvxIconChoiceCtrlEntry* pOldCursor,
+ SvxIconChoiceCtrlEntry* pNewCursor, BOOL bMod1, BOOL bShift, BOOL bPaintSync )
+{
+ if( pNewCursor )
+ {
+ SvxIconChoiceCtrlEntry* pFilterEntry = 0;
+ BOOL bDeselectAll = FALSE;
+ if( eSelectionMode != SINGLE_SELECTION )
+ {
+ if( !bMod1 && !bShift )
+ bDeselectAll = TRUE;
+ else if( bShift && !bMod1 && !pAnchor )
+ {
+ bDeselectAll = TRUE;
+ pFilterEntry = pOldCursor;
+ }
+ }
+ if( bDeselectAll )
+ DeselectAllBut( pFilterEntry, bPaintSync );
+ ShowCursor( FALSE );
+ MakeEntryVisible( pNewCursor );
+ SetCursor( pNewCursor );
+ if( bMod1 && !bShift )
+ {
+ if( pAnchor )
+ {
+ AddSelectedRect( pAnchor, pOldCursor );
+ pAnchor = 0;
+ }
+ }
+ else if( bShift )
+ {
+ if( !pAnchor )
+ pAnchor = pOldCursor;
+ if ( nWinBits & WB_ALIGN_LEFT )
+ SelectRange( pAnchor, pNewCursor, (nFlags & F_ADD_MODE)!=0 );
+ else
+ SelectRect(pAnchor,pNewCursor,(nFlags & F_ADD_MODE)!=0,&aSelectedRectList);
+ }
+ else
+ {
+ SelectEntry( pCursor, TRUE, TRUE, FALSE, bPaintSync );
+ aCurSelectionRect = GetEntryBoundRect( pCursor );
+ }
+ }
+}
+
+BOOL SvxIconChoiceCtrl_Impl::KeyInput( const KeyEvent& rKEvt )
+{
+ StopEditTimer();
+
+ BOOL bMod2 = rKEvt.GetKeyCode().IsMod2();
+ sal_Unicode cChar = rKEvt.GetCharCode();
+ ULONG nPos = (ULONG)-1;
+ if ( bMod2 && cChar && IsMnemonicChar( cChar, nPos ) )
+ {
+ // shortcut is clicked
+ SvxIconChoiceCtrlEntry* pNewCursor = GetEntry( nPos );
+ SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
+ if ( pNewCursor != pOldCursor )
+ SetCursor_Impl( pOldCursor, pNewCursor, FALSE, FALSE, FALSE );
+ return TRUE;
+ }
+
+ if ( bMod2 )
+ // no actions with <ALT>
+ return FALSE;
+
+ BOOL bKeyUsed = TRUE;
+ BOOL bMod1 = rKEvt.GetKeyCode().IsMod1();
+ BOOL bShift = rKEvt.GetKeyCode().IsShift();
+
+ if( eSelectionMode == SINGLE_SELECTION || eSelectionMode == NO_SELECTION)
+ {
+ bShift = FALSE;
+ bMod1 = FALSE;
+ }
+
+ if( bMod1 )
+ nFlags |= F_ADD_MODE;
+ BOOL bDeselectAll = FALSE;
+ if( eSelectionMode != SINGLE_SELECTION )
+ {
+ if( !bMod1 && !bShift )
+ bDeselectAll = TRUE;
+ if( bShift && !bMod1 && !pAnchor )
+ bDeselectAll = TRUE;
+ }
+
+ SvxIconChoiceCtrlEntry* pNewCursor;
+ SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
+
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+ switch( nCode )
+ {
+ case KEY_UP:
+ case KEY_PAGEUP:
+ if( pCursor )
+ {
+ MakeEntryVisible( pCursor );
+ if( nCode == KEY_UP )
+ pNewCursor = pImpCursor->GoUpDown(pCursor,FALSE);
+ else
+ pNewCursor = pImpCursor->GoPageUpDown(pCursor,FALSE);
+ SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, TRUE );
+ if( !pNewCursor )
+ {
+ Rectangle aRect( GetEntryBoundRect( pCursor ) );
+ if( aRect.Top())
+ {
+ aRect.Bottom() -= aRect.Top();
+ aRect.Top() = 0;
+ MakeVisible( aRect );
+ }
+ }
+
+ if ( bChooseWithCursor && pNewCursor != NULL )
+ {
+ pHdlEntry = pNewCursor;//GetCurEntry();
+ pCurHighlightFrame = pHdlEntry;
+ pView->ClickIcon();
+ pCurHighlightFrame = NULL;
+ }
+ }
+ break;
+
+ case KEY_DOWN:
+ case KEY_PAGEDOWN:
+ if( pCursor )
+ {
+ if( nCode == KEY_DOWN )
+ pNewCursor=pImpCursor->GoUpDown( pCursor,TRUE );
+ else
+ pNewCursor=pImpCursor->GoPageUpDown( pCursor,TRUE );
+ SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, TRUE );
+
+ if ( bChooseWithCursor && pNewCursor != NULL)
+ {
+ pHdlEntry = pNewCursor;//GetCurEntry();
+ pCurHighlightFrame = pHdlEntry;
+ pView->ClickIcon();
+ pCurHighlightFrame = NULL;
+ }
+ }
+ break;
+
+ case KEY_RIGHT:
+ if( pCursor )
+ {
+ pNewCursor=pImpCursor->GoLeftRight(pCursor,TRUE );
+ SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, TRUE );
+ }
+ break;
+
+ case KEY_LEFT:
+ if( pCursor )
+ {
+ MakeEntryVisible( pCursor );
+ pNewCursor = pImpCursor->GoLeftRight(pCursor,FALSE );
+ SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, TRUE );
+ if( !pNewCursor )
+ {
+ Rectangle aRect( GetEntryBoundRect(pCursor));
+ if( aRect.Left() )
+ {
+ aRect.Right() -= aRect.Left();
+ aRect.Left() = 0;
+ MakeVisible( aRect );
+ }
+ }
+ }
+ break;
+
+// wird vom VCL-Tracking gesteuert
+#if 0
+ case KEY_ESCAPE:
+ if( pView->IsTracking() )
+ {
+ HideSelectionRect();
+ //SelectAll( FALSE );
+ SetNoSelection();
+ ClearSelectedRectList();
+ nFlags &= ~F_TRACKING;
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+#endif
+
+
+ case KEY_F2:
+ if( !bMod1 && !bShift )
+ EditTimeoutHdl( 0 );
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_F8:
+ if( rKEvt.GetKeyCode().IsShift() )
+ {
+ if( nFlags & F_ADD_MODE )
+ nFlags &= (~F_ADD_MODE);
+ else
+ nFlags |= F_ADD_MODE;
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_SPACE:
+ if( pCursor && eSelectionMode != SINGLE_SELECTION )
+ {
+ if( !bMod1 )
+ {
+ //SelectAll( FALSE );
+ SetNoSelection();
+ ClearSelectedRectList();
+
+ // click Icon with spacebar
+ SetEntryHighlightFrame( GetCurEntry(), TRUE );
+ pView->ClickIcon();
+ pHdlEntry = pCurHighlightFrame;
+ pCurHighlightFrame=0;
+ }
+ else
+ ToggleSelection( pCursor );
+ }
+ break;
+
+#ifdef DBG_UTIL
+ case KEY_F10:
+ if( rKEvt.GetKeyCode().IsShift() )
+ {
+ if( pCursor )
+ pView->SetEntryTextMode( IcnShowTextFull, pCursor );
+ }
+ if( rKEvt.GetKeyCode().IsMod1() )
+ {
+ if( pCursor )
+ pView->SetEntryTextMode( IcnShowTextShort, pCursor );
+ }
+ break;
+#endif
+
+ case KEY_ADD:
+ case KEY_DIVIDE :
+ case KEY_A:
+ if( bMod1 && (eSelectionMode != SINGLE_SELECTION))
+ SelectAll( TRUE );
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_SUBTRACT:
+ case KEY_COMMA :
+ if( bMod1 )
+ SetNoSelection();
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_RETURN:
+ if( bMod1 )
+ {
+ if( pCursor && bEntryEditingEnabled )
+ /*pView->*/EditEntry( pCursor );
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_END:
+ if( pCursor )
+ {
+ pNewCursor = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( aEntries.Count() - 1 );
+ SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, TRUE );
+ }
+ break;
+
+ case KEY_HOME:
+ if( pCursor )
+ {
+ pNewCursor = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 );
+ SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, TRUE );
+ }
+ break;
+
+ default:
+ bKeyUsed = FALSE;
+
+ }
+ return bKeyUsed;
+}
+
+// Berechnet TopLeft der Scrollbars (nicht ihre Groessen!)
+void SvxIconChoiceCtrl_Impl::PositionScrollBars( long nRealWidth, long nRealHeight )
+{
+ // hor scrollbar
+ Point aPos( 0, nRealHeight );
+ aPos.Y() -= nHorSBarHeight;
+
+ if( aHorSBar.GetPosPixel() != aPos )
+ aHorSBar.SetPosPixel( aPos );
+
+ // ver scrollbar
+ aPos.X() = nRealWidth; aPos.Y() = 0;
+ aPos.X() -= nVerSBarWidth;
+ aPos.X()++;
+ aPos.Y()--;
+
+ if( aVerSBar.GetPosPixel() != aPos )
+ aVerSBar.SetPosPixel( aPos );
+}
+
+void SvxIconChoiceCtrl_Impl::AdjustScrollBars( BOOL )
+{
+ Rectangle aOldOutRect( GetOutputRect() );
+ long nVirtHeight = aVirtOutputSize.Height();
+ long nVirtWidth = aVirtOutputSize.Width();
+
+ Size aOSize( pView->Control::GetOutputSizePixel() );
+ long nRealHeight = aOSize.Height();
+ long nRealWidth = aOSize.Width();
+
+ PositionScrollBars( nRealWidth, nRealHeight );
+
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+
+ long nVisibleWidth;
+ if( nRealWidth > nVirtWidth )
+ nVisibleWidth = nVirtWidth + aOrigin.X();
+ else
+ nVisibleWidth = nRealWidth;
+
+ long nVisibleHeight;
+ if( nRealHeight > nVirtHeight )
+ nVisibleHeight = nVirtHeight + aOrigin.Y();
+ else
+ nVisibleHeight = nRealHeight;
+
+ sal_Bool bVerSBar = ( nWinBits & WB_VSCROLL ) != 0;
+ sal_Bool bHorSBar = ( nWinBits & WB_HSCROLL ) != 0;
+ sal_Bool bNoVerSBar = ( nWinBits & WB_NOVSCROLL ) != 0;
+ sal_Bool bNoHorSBar = ( nWinBits & WB_NOHSCROLL ) != 0;
+
+ USHORT nResult = 0;
+ if( nVirtHeight )
+ {
+ // activate ver scrollbar ?
+ if( !bNoVerSBar && (bVerSBar || ( nVirtHeight > nVisibleHeight)) )
+ {
+ nResult = 0x0001;
+ nRealWidth -= nVerSBarWidth;
+
+ if( nRealWidth > nVirtWidth )
+ nVisibleWidth = nVirtWidth + aOrigin.X();
+ else
+ nVisibleWidth = nRealWidth;
+
+ nFlags |= F_HOR_SBARSIZE_WITH_VBAR;
+ }
+ // activate hor scrollbar ?
+ if( !bNoHorSBar && (bHorSBar || (nVirtWidth > nVisibleWidth)) )
+ {
+ nResult |= 0x0002;
+ nRealHeight -= nHorSBarHeight;
+
+ if( nRealHeight > nVirtHeight )
+ nVisibleHeight = nVirtHeight + aOrigin.Y();
+ else
+ nVisibleHeight = nRealHeight;
+
+ // brauchen wir jetzt doch eine senkrechte Scrollbar ?
+ if( !(nResult & 0x0001) && // nur wenn nicht schon da
+ ( !bNoVerSBar && ((nVirtHeight > nVisibleHeight) || bVerSBar)) )
+ {
+ nResult = 3; // beide sind an
+ nRealWidth -= nVerSBarWidth;
+
+ if( nRealWidth > nVirtWidth )
+ nVisibleWidth = nVirtWidth + aOrigin.X();
+ else
+ nVisibleWidth = nRealWidth;
+
+ nFlags |= F_VER_SBARSIZE_WITH_HBAR;
+ }
+ }
+ }
+
+ // size ver scrollbar
+ long nThumb = aVerSBar.GetThumbPos();
+ Size aSize( nVerSBarWidth, nRealHeight );
+ aSize.Height() += 2;
+ if( aSize != aVerSBar.GetSizePixel() )
+ aVerSBar.SetSizePixel( aSize );
+ aVerSBar.SetVisibleSize( nVisibleHeight );
+ aVerSBar.SetPageSize( GetScrollBarPageSize( nVisibleHeight ));
+
+ if( nResult & 0x0001 )
+ {
+ aVerSBar.SetThumbPos( nThumb );
+ aVerSBar.Show();
+ }
+ else
+ {
+ aVerSBar.SetThumbPos( 0 );
+ aVerSBar.Hide();
+ }
+
+ // size hor scrollbar
+ nThumb = aHorSBar.GetThumbPos();
+ aSize.Width() = nRealWidth;
+ aSize.Height() = nHorSBarHeight;
+ aSize.Width()++;
+ if( nResult & 0x0001 ) // vertikale Scrollbar ?
+ {
+ aSize.Width()++;
+ nRealWidth++;
+ }
+ if( aSize != aHorSBar.GetSizePixel() )
+ aHorSBar.SetSizePixel( aSize );
+ aHorSBar.SetVisibleSize( nVisibleWidth );
+ aHorSBar.SetPageSize( GetScrollBarPageSize(nVisibleWidth ));
+ if( nResult & 0x0002 )
+ {
+ aHorSBar.SetThumbPos( nThumb );
+ aHorSBar.Show();
+ }
+ else
+ {
+ aHorSBar.SetThumbPos( 0 );
+ aHorSBar.Hide();
+ }
+
+ aOutputSize.Width() = nRealWidth;
+ if( nResult & 0x0002 ) // hor scrollbar ?
+ nRealHeight++; // weil unterer Rand geclippt wird
+ aOutputSize.Height() = nRealHeight;
+
+ Rectangle aNewOutRect( GetOutputRect() );
+ if( aNewOutRect != aOldOutRect && pView->HasBackground() )
+ {
+ Wallpaper aPaper( pView->GetBackground() );
+ aPaper.SetRect( aNewOutRect );
+ pView->SetBackground( aPaper );
+ }
+
+ if( (nResult & (0x0001|0x0002)) == (0x0001|0x0002) )
+ aScrBarBox.Show();
+ else
+ aScrBarBox.Hide();
+}
+
+void SvxIconChoiceCtrl_Impl::Resize()
+{
+ StopEditTimer();
+ InitScrollBarBox();
+ aOutputSize = pView->GetOutputSizePixel();
+ pImpCursor->Clear();
+ pGridMap->OutputSizeChanged();
+
+ const Size& rSize = pView->Control::GetOutputSizePixel();
+ PositionScrollBars( rSize.Width(), rSize.Height() );
+ // Die ScrollBars werden asynchron ein/ausgeblendet, damit abgeleitete
+ // Klassen im Resize ein Arrange durchfuehren koennen, ohne dass
+ // die ScrollBars aufblitzen
+ // Wenn schon ein Event unterwegs ist, dann braucht kein neues verschickt werden,
+ // zumindest, solange es nur einen EventTypen gibt
+ if ( ! nUserEventAdjustScrBars )
+ nUserEventAdjustScrBars =
+ Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl, UserEventHdl),
+ EVENTID_ADJUST_SCROLLBARS);
+
+ if( pView->HasBackground() && !pView->GetBackground().IsScrollable() )
+ {
+ Rectangle aRect( GetOutputRect());
+ Wallpaper aPaper( pView->GetBackground() );
+ aPaper.SetRect( aRect );
+ pView->SetBackground( aPaper );
+ }
+ VisRectChanged();
+}
+
+BOOL SvxIconChoiceCtrl_Impl::CheckHorScrollBar()
+{
+ if( !pZOrderList || !aHorSBar.IsVisible() )
+ return FALSE;
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+ if(!( nWinBits & WB_HSCROLL) && !aOrigin.X() )
+ {
+ long nWidth = aOutputSize.Width();
+ const ULONG nCount = pZOrderList->Count();
+ long nMostRight = 0;
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pZOrderList->GetObject(nCur);
+ long nRight = GetEntryBoundRect(pEntry).Right();
+ if( nRight > nWidth )
+ return FALSE;
+ if( nRight > nMostRight )
+ nMostRight = nRight;
+ }
+ aHorSBar.Hide();
+ aOutputSize.Height() += nHorSBarHeight;
+ aVirtOutputSize.Width() = nMostRight;
+ aHorSBar.SetThumbPos( 0 );
+ Range aRange;
+ aRange.Max() = nMostRight - 1;
+ aHorSBar.SetRange( aRange );
+ if( aVerSBar.IsVisible() )
+ {
+ Size aSize( aVerSBar.GetSizePixel());
+ aSize.Height() += nHorSBarHeight;
+ aVerSBar.SetSizePixel( aSize );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SvxIconChoiceCtrl_Impl::CheckVerScrollBar()
+{
+ if( !pZOrderList || !aVerSBar.IsVisible() )
+ return FALSE;
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+ if(!( nWinBits & WB_VSCROLL) && !aOrigin.Y() )
+ {
+ long nDeepest = 0;
+ long nHeight = aOutputSize.Height();
+ const ULONG nCount = pZOrderList->Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pZOrderList->GetObject(nCur);
+ long nBottom = GetEntryBoundRect(pEntry).Bottom();
+ if( nBottom > nHeight )
+ return FALSE;
+ if( nBottom > nDeepest )
+ nDeepest = nBottom;
+ }
+ aVerSBar.Hide();
+ aOutputSize.Width() += nVerSBarWidth;
+ aVirtOutputSize.Height() = nDeepest;
+ aVerSBar.SetThumbPos( 0 );
+ Range aRange;
+ aRange.Max() = nDeepest - 1;
+ aVerSBar.SetRange( aRange );
+ if( aHorSBar.IsVisible() )
+ {
+ Size aSize( aHorSBar.GetSizePixel());
+ aSize.Width() += nVerSBarWidth;
+ aHorSBar.SetSizePixel( aSize );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+// blendet Scrollbars aus, wenn sie nicht mehr benoetigt werden
+void SvxIconChoiceCtrl_Impl::CheckScrollBars()
+{
+ CheckVerScrollBar();
+ if( CheckHorScrollBar() )
+ CheckVerScrollBar();
+ if( aVerSBar.IsVisible() && aHorSBar.IsVisible() )
+ aScrBarBox.Show();
+ else
+ aScrBarBox.Hide();
+}
+
+
+void SvxIconChoiceCtrl_Impl::GetFocus()
+{
+ RepaintEntries( ICNVIEW_FLAG_SELECTED );
+ if( pCursor )
+ {
+ pCursor->SetFlags( ICNVIEW_FLAG_FOCUSED );
+ ShowCursor( TRUE );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::LoseFocus()
+{
+ StopEditTimer();
+ if( pCursor )
+ pCursor->ClearFlags( ICNVIEW_FLAG_FOCUSED );
+ ShowCursor( FALSE );
+
+// HideFocus ();
+// pView->Invalidate ( aFocus.aRect );
+
+ RepaintEntries( ICNVIEW_FLAG_SELECTED );
+}
+
+void SvxIconChoiceCtrl_Impl::SetUpdateMode( BOOL bUpdate )
+{
+ if( bUpdate != bUpdateMode )
+ {
+ bUpdateMode = bUpdate;
+ if( bUpdate )
+ {
+ AdjustScrollBars();
+ pImpCursor->Clear();
+ pGridMap->Clear();
+ pView->Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry* pEntry, BOOL bIsBackgroundPainted )
+{
+ Point aPos( GetEntryPos( pEntry ) );
+ PaintEntry( pEntry, aPos, 0, bIsBackgroundPainted );
+}
+
+// Prios der Emphasis: bDropTarget => bCursored => bSelected
+void SvxIconChoiceCtrl_Impl::PaintEmphasis(
+ const Rectangle& rTextRect, const Rectangle& rImageRect,
+ BOOL bSelected, BOOL bDropTarget, BOOL bCursored, OutputDevice* pOut,
+ BOOL bIsBackgroundPainted )
+{
+ static Color aTransparent( COL_TRANSPARENT );
+
+ if( !pOut )
+ pOut = pView;
+
+#ifdef OV_CHECK_EMPH_RECTS
+ {
+ Color aXOld( pOut->GetFillColor() );
+ pOut->SetFillColor( Color( COL_GREEN ));
+ pOut->DrawRect( rTextRect );
+ pOut->DrawRect( rImageRect );
+ pOut->SetFillColor( aXOld );
+ }
+#endif
+
+ const StyleSettings& rSettings = pOut->GetSettings().GetStyleSettings();
+ Color aOldFillColor( pOut->GetFillColor() );
+
+ BOOL bSolidTextRect = FALSE;
+ BOOL bSolidImageRect = FALSE;
+
+ if( bDropTarget && ( eSelectionMode != NO_SELECTION ) )
+ {
+ pOut->SetFillColor( rSettings.GetHighlightColor() );
+ bSolidTextRect = TRUE;
+ bSolidImageRect = TRUE;
+ }
+ else
+ {
+ if ( !bSelected || bCursored )
+ {
+ if( !pView->HasFontFillColor() )
+ pOut->SetFillColor( pOut->GetBackground().GetColor() );
+ else
+ {
+ const Color& rFillColor = pView->GetFont().GetFillColor();
+ pOut->SetFillColor( rFillColor );
+ if( rFillColor != aTransparent )
+ bSolidTextRect = TRUE;
+ }
+ }
+ }
+
+ // Textrechteck zeichnen
+ if( !bSolidTextRect )
+ {
+ if( !bIsBackgroundPainted )
+ pOut->Erase( rTextRect );
+ }
+ else
+ {
+ Color aOldLineColor;
+ if( bCursored )
+ {
+ aOldLineColor = pOut->GetLineColor();
+ pOut->SetLineColor( Color( COL_GRAY ) );
+ }
+ pOut->DrawRect( rTextRect );
+ if( bCursored )
+ pOut->SetLineColor( aOldLineColor );
+ }
+
+ // Bildrechteck zeichnen
+ if( !bSolidImageRect )
+ {
+ if( !bIsBackgroundPainted )
+ pOut->Erase( rImageRect );
+ }
+// die Emphasis des Images muss von der abgeleiteten Klasse gezeichnet werden
+// (in der virtuellen Funktion DrawEntryImage)
+// else
+// pOut->DrawRect( rImageRect );
+
+ pOut->SetFillColor( aOldFillColor );
+}
+
+
+void SvxIconChoiceCtrl_Impl::PaintItem( const Rectangle& rRect,
+ IcnViewFieldType eItem, SvxIconChoiceCtrlEntry* pEntry, USHORT nPaintFlags,
+ OutputDevice* pOut, const String* pStr, ::vcl::ControlLayoutData* _pLayoutData )
+{
+ if( eItem == IcnViewFieldTypeText )
+ {
+ String aText;
+ if( !pStr )
+ aText = pView->GetEntryText( pEntry, FALSE );
+ else
+ aText = *pStr;
+
+ if ( _pLayoutData )
+ {
+ pOut->DrawText( rRect, aText, nCurTextDrawFlags,
+ &_pLayoutData->m_aUnicodeBoundRects, &_pLayoutData->m_aDisplayText );
+ }
+ else
+ {
+ Color aOldFontColor = pOut->GetTextColor();
+ if ( pView->AutoFontColor() )
+ {
+ Color aBkgColor( pOut->GetBackground().GetColor() );
+ Color aFontColor;
+ USHORT nColor = ( aBkgColor.GetRed() + aBkgColor.GetGreen() + aBkgColor.GetBlue() ) / 3;
+ if ( nColor > 127 )
+ aFontColor.SetColor ( COL_BLACK );
+ else
+ aFontColor.SetColor( COL_WHITE );
+ pOut->SetTextColor( aFontColor );
+ }
+
+ pOut->DrawText( rRect, aText, nCurTextDrawFlags );
+
+ if ( pView->AutoFontColor() )
+ pOut->SetTextColor( aOldFontColor );
+
+ if( pEntry->IsFocused() )
+ {
+ Rectangle aRect ( CalcFocusRect( (SvxIconChoiceCtrlEntry*)pEntry ) );
+ /*pView->*/ShowFocus( aRect );
+ DrawFocusRect( pOut );
+ }
+ }
+ }
+ else
+ {
+ Point aPos( rRect.TopLeft() );
+ if( nPaintFlags & PAINTFLAG_HOR_CENTERED )
+ aPos.X() += (rRect.GetWidth() - aImageSize.Width() ) / 2;
+ if( nPaintFlags & PAINTFLAG_VER_CENTERED )
+ aPos.Y() += (rRect.GetHeight() - aImageSize.Height() ) / 2;
+ pView->DrawEntryImage( pEntry, aPos, *pOut );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::PaintEntryVirtOutDev( SvxIconChoiceCtrlEntry* pEntry )
+{
+#ifdef OV_NO_VIRT_OUTDEV
+ PaintEntry( pEntry );
+#else
+ if( !pEntryPaintDev )
+ {
+ pEntryPaintDev = new VirtualDevice( *pView );
+ pEntryPaintDev->SetFont( pView->GetFont() );
+ pEntryPaintDev->SetLineColor();
+ //pEntryPaintDev->SetBackground( pView->GetBackground() );
+ }
+ const Rectangle& rRect = GetEntryBoundRect( pEntry );
+ Rectangle aOutRect( GetOutputRect() );
+ if( !rRect.IsOver( aOutRect ) )
+ return;
+ Wallpaper aPaper( pView->GetBackground() );
+ Rectangle aRect( aPaper.GetRect() );
+
+ // Rechteck verschieben, so dass das Boundrect des Entries im
+ // VirtOut-Dev bei 0,0 liegt.
+ aRect.Move( -rRect.Left(), -rRect.Top() );
+ aPaper.SetRect( aRect );
+ pEntryPaintDev->SetBackground( aPaper );
+ pEntryPaintDev->SetFont( pView->GetFont() );
+ Rectangle aPix ( pEntryPaintDev->LogicToPixel(aRect) );
+
+
+ Size aSize( rRect.GetSize() );
+ pEntryPaintDev->SetOutputSizePixel( aSize );
+ pEntryPaintDev->DrawOutDev(
+ Point(), aSize, rRect.TopLeft(), aSize, *pView );
+
+ PaintEntry( pEntry, Point(), pEntryPaintDev );
+
+ pView->DrawOutDev(
+ rRect.TopLeft(),
+ aSize,
+ Point(),
+ aSize,
+ *pEntryPaintDev );
+#endif
+}
+
+
+void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos,
+ OutputDevice* pOut, BOOL bIsBackgroundPainted )
+{
+ if( !pOut )
+ pOut = pView;
+
+ BOOL bSelected = FALSE;
+
+ if( eSelectionMode != NO_SELECTION )
+ bSelected = pEntry->IsSelected();
+
+ BOOL bCursored = pEntry->IsCursored();
+ BOOL bDropTarget = pEntry->IsDropTarget();
+ BOOL bNoEmphasis = pEntry->IsBlockingEmphasis();
+
+ Font aTempFont( pOut->GetFont() );
+
+ // AutoFontColor
+ /*
+ if ( pView->AutoFontColor() )
+ {
+ aTempFont.SetColor ( aFontColor );
+ }
+ */
+
+ String aEntryText( pView->GetEntryText( pEntry, FALSE ) );
+ Rectangle aTextRect( CalcTextRect(pEntry,&rPos,FALSE,&aEntryText));
+ Rectangle aBmpRect( CalcBmpRect(pEntry, &rPos ) );
+
+ sal_Bool bShowSelection =
+ ( ( ( bSelected && !bCursored )
+ || bDropTarget
+ )
+ && !bNoEmphasis
+ && ( eSelectionMode != NO_SELECTION )
+ );
+ sal_Bool bActiveSelection = ( 0 != ( nWinBits & WB_NOHIDESELECTION ) ) || pView->HasFocus();
+
+ if ( bShowSelection )
+ {
+ const StyleSettings& rSettings = pOut->GetSettings().GetStyleSettings();
+ Font aNewFont( aTempFont );
+
+ // bei hart attributierter Font-Fuellcolor muessen wir diese
+ // hart auf die Highlight-Color setzen
+ if( pView->HasFontFillColor() )
+ {
+ if( (nWinBits & WB_NOHIDESELECTION) || pView->HasFocus() )
+ aNewFont.SetFillColor( rSettings.GetHighlightColor() );
+ else
+ aNewFont.SetFillColor( rSettings.GetDeactiveColor() );
+ }
+
+ Color aWinCol = rSettings.GetWindowTextColor();
+ if ( !bActiveSelection && rSettings.GetFaceColor().IsBright() == aWinCol.IsBright() )
+ aNewFont.SetColor( rSettings.GetWindowTextColor() );
+ else
+ aNewFont.SetColor( rSettings.GetHighlightTextColor() );
+
+ pOut->SetFont( aNewFont );
+
+ pOut->SetFillColor( pOut->GetBackground().GetColor() );
+ pOut->DrawRect( CalcFocusRect( pEntry ) );
+ pOut->SetFillColor( );
+ }
+
+ BOOL bResetClipRegion = FALSE;
+ if( !pView->IsClipRegion() && (aVerSBar.IsVisible() || aHorSBar.IsVisible()) )
+ {
+ Rectangle aOutputArea( GetOutputRect() );
+ if( aOutputArea.IsOver(aTextRect) || aOutputArea.IsOver(aBmpRect) )
+ {
+ pView->SetClipRegion( aOutputArea );
+ bResetClipRegion = TRUE;
+ }
+ }
+
+#ifdef OV_DRAWBOUNDRECT
+ {
+ Color aXOldColor = pOut->GetLineColor();
+ pOut->SetLineColor( Color( COL_LIGHTRED ) );
+ Rectangle aXRect( pEntry->aRect );
+ aXRect.SetPos( rPos );
+ pOut->DrawRect( aXRect );
+ pOut->SetLineColor( aXOldColor );
+ }
+#endif
+
+ sal_Bool bLargeIconMode = WB_ICON == ( nWinBits & (VIEWMODE_MASK) );
+ USHORT nBmpPaintFlags = PAINTFLAG_VER_CENTERED;
+ if ( bLargeIconMode )
+ nBmpPaintFlags |= PAINTFLAG_HOR_CENTERED;
+ USHORT nTextPaintFlags = bLargeIconMode ? PAINTFLAG_HOR_CENTERED : PAINTFLAG_VER_CENTERED;
+
+ if( !bNoEmphasis )
+ PaintEmphasis(aTextRect,aBmpRect,bSelected,bDropTarget,bCursored,pOut,bIsBackgroundPainted);
+
+ if ( bShowSelection )
+ pView->DrawSelectionBackground( CalcFocusRect( pEntry ),
+ bActiveSelection ? 1 : 2 /* highlight */, sal_False /* check */, sal_True /* border */, sal_False /* ext border only */ );
+
+ PaintItem( aBmpRect, IcnViewFieldTypeImage, pEntry, nBmpPaintFlags, pOut );
+
+ PaintItem( aTextRect, IcnViewFieldTypeText, pEntry,
+ nTextPaintFlags, pOut );
+
+ // Highlight-Frame zeichnen
+ if( pEntry == pCurHighlightFrame && !bNoEmphasis )
+ DrawHighlightFrame( pOut, CalcFocusRect( pEntry ), FALSE );
+
+ pOut->SetFont( aTempFont );
+ if( bResetClipRegion )
+ pView->SetClipRegion();
+}
+
+void SvxIconChoiceCtrl_Impl::SetEntryPos( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos,
+ BOOL bAdjustAtGrid, BOOL bCheckScrollBars, BOOL bKeepGridMap )
+{
+ ShowCursor( FALSE );
+ Rectangle aBoundRect( GetEntryBoundRect( pEntry ));
+ pView->Invalidate( aBoundRect );
+ ToTop( pEntry );
+ if( !IsAutoArrange() )
+ {
+ BOOL bAdjustVirtSize = FALSE;
+ if( rPos != aBoundRect.TopLeft() )
+ {
+ Point aGridOffs(
+ pEntry->aGridRect.TopLeft() - pEntry->aRect.TopLeft() );
+ pImpCursor->Clear();
+ if( !bKeepGridMap )
+ pGridMap->Clear();
+ aBoundRect.SetPos( rPos );
+ pEntry->aRect = aBoundRect;
+ pEntry->aGridRect.SetPos( rPos + aGridOffs );
+ bAdjustVirtSize = TRUE;
+ }
+ if( bAdjustAtGrid )
+ {
+ if( bAdjustVirtSize )
+ {
+ // Durch das Ausrichten des (ggf. gerade neu positionierten) Eintrags,
+ // kann er wieder komplett
+ // in den sichtbaren Bereich rutschen, so dass u.U. doch keine Scrollbar
+ // eingeblendet werden muss. Um deshalb ein 'Aufblitzen' der
+ // Scrollbar(s) zu vermeiden, wird zum Aufplustern der virtuellen
+ // Ausgabegroesse bereits das ausgerichtete Boundrect des
+ // Eintrags genommen. Die virtuelle Groesse muss angepasst werden,
+ // da AdjustEntryAtGrid von ihr abhaengt.
+ const Rectangle& rBoundRect = GetEntryBoundRect( pEntry );
+ Rectangle aCenterRect( CalcBmpRect( pEntry, 0 ));
+ Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) );
+ Rectangle aNewBoundRect( aNewPos, pEntry->aRect.GetSize());
+ AdjustVirtSize( aNewBoundRect );
+ bAdjustVirtSize = FALSE;
+ }
+ AdjustEntryAtGrid( pEntry );
+ ToTop( pEntry );
+ }
+ if( bAdjustVirtSize )
+ AdjustVirtSize( pEntry->aRect );
+
+ if( bCheckScrollBars && bUpdateMode )
+ CheckScrollBars();
+
+ pView->Invalidate( pEntry->aRect );
+ pGridMap->OccupyGrids( pEntry );
+ }
+ else
+ {
+ SvxIconChoiceCtrlEntry* pPrev = FindEntryPredecessor( pEntry, rPos );
+ SetEntryPredecessor( pEntry, pPrev );
+ aAutoArrangeTimer.Start();
+ }
+ ShowCursor( TRUE );
+}
+
+void SvxIconChoiceCtrl_Impl::SetNoSelection()
+{
+ // rekursive Aufrufe ueber SelectEntry abblocken
+ if( !(nFlags & F_CLEARING_SELECTION ))
+ {
+ nFlags |= F_CLEARING_SELECTION;
+ DeselectAllBut( 0, TRUE );
+ nFlags &= ~F_CLEARING_SELECTION;
+ }
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetEntry( const Point& rDocPos, BOOL bHit )
+{
+ CheckBoundingRects();
+ // Z-Order-Liste vom Ende her absuchen
+ ULONG nCount = pZOrderList->Count();
+ while( nCount )
+ {
+ nCount--;
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nCount));
+ if( pEntry->aRect.IsInside( rDocPos ) )
+ {
+ if( bHit )
+ {
+ Rectangle aRect = CalcBmpRect( pEntry );
+ aRect.Top() -= 3;
+ aRect.Bottom() += 3;
+ aRect.Left() -= 3;
+ aRect.Right() += 3;
+ if( aRect.IsInside( rDocPos ) )
+ return pEntry;
+ aRect = CalcTextRect( pEntry );
+ if( aRect.IsInside( rDocPos ) )
+ return pEntry;
+ }
+ else
+ return pEntry;
+ }
+ }
+ return 0;
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetNextEntry( const Point& rDocPos, SvxIconChoiceCtrlEntry* pCurEntry )
+{
+ CheckBoundingRects();
+ SvxIconChoiceCtrlEntry* pTarget = 0;
+ const ULONG nStartPos = pZOrderList->GetPos( (void*)pCurEntry );
+ if( nStartPos != LIST_ENTRY_NOTFOUND )
+ {
+ const ULONG nCount = pZOrderList->Count();
+ for( ULONG nCur = nStartPos+1; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nCur));
+ if( pEntry->aRect.IsInside( rDocPos ) )
+ {
+ pTarget = pEntry;
+ break;
+ }
+ }
+ }
+ return pTarget;
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetPrevEntry( const Point& rDocPos, SvxIconChoiceCtrlEntry* pCurEntry )
+{
+ CheckBoundingRects();
+ SvxIconChoiceCtrlEntry* pTarget = 0;
+ ULONG nStartPos = pZOrderList->GetPos( (void*)pCurEntry );
+ if( nStartPos != LIST_ENTRY_NOTFOUND && nStartPos != 0 )
+ {
+ nStartPos--;
+ do
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nStartPos));
+ if( pEntry->aRect.IsInside( rDocPos ) )
+ {
+ pTarget = pEntry;
+ break;
+ }
+ } while( nStartPos > 0 );
+ }
+ return pTarget;
+}
+
+Point SvxIconChoiceCtrl_Impl::GetEntryPos( SvxIconChoiceCtrlEntry* pEntry )
+{
+ return pEntry->aRect.TopLeft();
+}
+
+void SvxIconChoiceCtrl_Impl::MakeEntryVisible( SvxIconChoiceCtrlEntry* pEntry, BOOL bBound )
+{
+ if ( bBound )
+ {
+ const Rectangle& rRect = GetEntryBoundRect( pEntry );
+ MakeVisible( rRect );
+ }
+ else
+ {
+ Rectangle aRect = CalcBmpRect( pEntry );
+ aRect.Union( CalcTextRect( pEntry ) );
+ aRect.Top() += TBOFFS_BOUND;
+ aRect.Bottom() += TBOFFS_BOUND;
+ aRect.Left() += LROFFS_BOUND;
+ aRect.Right() += LROFFS_BOUND;
+ MakeVisible( aRect );
+ }
+}
+
+const Rectangle& SvxIconChoiceCtrl_Impl::GetEntryBoundRect( SvxIconChoiceCtrlEntry* pEntry )
+{
+ if( !IsBoundingRectValid( pEntry->aRect ))
+ FindBoundingRect( pEntry );
+ return pEntry->aRect;
+}
+
+Rectangle SvxIconChoiceCtrl_Impl::CalcBmpRect( SvxIconChoiceCtrlEntry* pEntry, const Point* pPos )
+{
+ Rectangle aBound = GetEntryBoundRect( pEntry );
+ if( pPos )
+ aBound.SetPos( *pPos );
+ Point aPos( aBound.TopLeft() );
+
+ switch( nWinBits & (VIEWMODE_MASK) )
+ {
+ case WB_ICON:
+ {
+ aPos.X() += ( aBound.GetWidth() - aImageSize.Width() ) / 2;
+ return Rectangle( aPos, aImageSize );
+ }
+
+ case WB_SMALLICON:
+ case WB_DETAILS:
+ aPos.Y() += ( aBound.GetHeight() - aImageSize.Height() ) / 2;
+ //todo: hor. Abstand zum BoundRect?
+ return Rectangle( aPos, aImageSize );
+
+ default:
+ DBG_ERROR("IconView: Viewmode not set");
+ return aBound;
+ }
+}
+
+Rectangle SvxIconChoiceCtrl_Impl::CalcTextRect( SvxIconChoiceCtrlEntry* pEntry,
+ const Point* pEntryPos, BOOL bEdit, const String* pStr )
+{
+ String aEntryText;
+ if( !pStr )
+ aEntryText = pView->GetEntryText( pEntry, bEdit );
+ else
+ aEntryText = *pStr;
+
+ const Rectangle aMaxTextRect( CalcMaxTextRect( pEntry ) );
+ Rectangle aBound( GetEntryBoundRect( pEntry ) );
+ if( pEntryPos )
+ aBound.SetPos( *pEntryPos );
+
+ Rectangle aTextRect( aMaxTextRect );
+ if( !bEdit )
+ aTextRect = pView->GetTextRect( aTextRect, aEntryText, nCurTextDrawFlags );
+
+ Size aTextSize( aTextRect.GetSize() );
+
+ Point aPos( aBound.TopLeft() );
+ long nBoundWidth = aBound.GetWidth();
+ long nBoundHeight = aBound.GetHeight();
+
+ switch( nWinBits & (VIEWMODE_MASK) )
+ {
+ case WB_ICON:
+ aPos.Y() += aImageSize.Height();
+ aPos.Y() += VER_DIST_BMP_STRING;
+ // beim Editieren etwas mehr Platz
+ if( bEdit )
+ {
+ // 20% rauf
+ long nMinWidth = (( (aImageSize.Width()*10) / 100 ) * 2 ) +
+ aImageSize.Width();
+ if( nMinWidth > nBoundWidth )
+ nMinWidth = nBoundWidth;
+
+ if( aTextSize.Width() < nMinWidth )
+ aTextSize.Width() = nMinWidth;
+
+ // beim Editieren ist Ueberlappung nach unten erlaubt
+ Size aOptSize = aMaxTextRect.GetSize();
+ if( aOptSize.Height() > aTextSize.Height() )
+ aTextSize.Height() = aOptSize.Height();
+ }
+ aPos.X() += (nBoundWidth - aTextSize.Width()) / 2;
+ break;
+
+ case WB_SMALLICON:
+ case WB_DETAILS:
+ aPos.X() += aImageSize.Width();
+ aPos.X() += HOR_DIST_BMP_STRING;
+ aPos.Y() += (nBoundHeight - aTextSize.Height()) / 2;
+ break;
+ }
+ return Rectangle( aPos, aTextSize );
+}
+
+
+long SvxIconChoiceCtrl_Impl::CalcBoundingWidth( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ long nStringWidth = GetItemSize( pEntry, IcnViewFieldTypeText ).Width();
+// nStringWidth += 2*LROFFS_TEXT;
+ long nWidth = 0;
+
+ switch( nWinBits & (VIEWMODE_MASK) )
+ {
+ case WB_ICON:
+ nWidth = Max( nStringWidth, aImageSize.Width() );
+ break;
+
+ case WB_SMALLICON:
+ case WB_DETAILS:
+ nWidth = aImageSize.Width();
+ nWidth += HOR_DIST_BMP_STRING;
+ nWidth += nStringWidth;
+ break;
+ }
+ return nWidth;
+}
+
+long SvxIconChoiceCtrl_Impl::CalcBoundingHeight( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ long nStringHeight = GetItemSize( pEntry, IcnViewFieldTypeText).Height();
+ long nHeight = 0;
+
+ switch( nWinBits & (VIEWMODE_MASK) )
+ {
+ case WB_ICON:
+ nHeight = aImageSize.Height();
+ nHeight += VER_DIST_BMP_STRING;
+ nHeight += nStringHeight;
+ break;
+
+ case WB_SMALLICON:
+ case WB_DETAILS:
+ nHeight = Max( aImageSize.Height(), nStringHeight );
+ break;
+ }
+ if( nHeight > nMaxBoundHeight )
+ {
+ ((SvxIconChoiceCtrl_Impl*)this)->nMaxBoundHeight = nHeight;
+ ((SvxIconChoiceCtrl_Impl*)this)->aHorSBar.SetLineSize( GetScrollBarLineSize() );
+ ((SvxIconChoiceCtrl_Impl*)this)->aVerSBar.SetLineSize( GetScrollBarLineSize() );
+ }
+ return nHeight;
+}
+
+Size SvxIconChoiceCtrl_Impl::CalcBoundingSize( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ return Size( CalcBoundingWidth( pEntry ),
+ CalcBoundingHeight( pEntry ) );
+}
+
+void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRects()
+{
+ nMaxBoundHeight = 0;
+ pZOrderList->Clear();
+ ULONG nCount = aEntries.Count();
+ ULONG nCur;
+ SvxIconChoiceCtrlEntry* pEntry;
+
+ if( !IsAutoArrange() || !pHead )
+ {
+ for( nCur = 0; nCur < nCount; nCur++ )
+ {
+ pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ FindBoundingRect( pEntry );
+ pZOrderList->Insert( pEntry, LIST_APPEND );
+ }
+ }
+ else
+ {
+ nCur = 0;
+ pEntry = pHead;
+ while( nCur != nCount )
+ {
+ DBG_ASSERT(pEntry->pflink&&pEntry->pblink,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)");
+ FindBoundingRect( pEntry );
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ pEntry = pEntry->pflink;
+ nCur++;
+ }
+ }
+ bBoundRectsDirty = FALSE;
+ AdjustScrollBars();
+}
+
+void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRectsSmart()
+{
+ nMaxBoundHeight = 0;
+ pZOrderList->Clear();
+ ULONG nCur;
+ SvxIconChoiceCtrlEntry* pEntry;
+ const ULONG nCount = aEntries.Count();
+
+ if( !IsAutoArrange() || !pHead )
+ {
+ for( nCur = 0; nCur < nCount; nCur++ )
+ {
+ pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ if( IsBoundingRectValid( pEntry->aRect ))
+ {
+ Size aBoundSize( pEntry->aRect.GetSize() );
+ if( aBoundSize.Height() > nMaxBoundHeight )
+ nMaxBoundHeight = aBoundSize.Height();
+ }
+ else
+ FindBoundingRect( pEntry );
+ pZOrderList->Insert( pEntry, LIST_APPEND );
+ }
+ }
+ else
+ {
+ nCur = 0;
+ pEntry = pHead;
+ while( nCur != nCount )
+ {
+ DBG_ASSERT(pEntry->pflink&&pEntry->pblink,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)");
+ if( IsBoundingRectValid( pEntry->aRect ))
+ {
+ Size aBoundSize( pEntry->aRect.GetSize() );
+ if( aBoundSize.Height() > nMaxBoundHeight )
+ nMaxBoundHeight = aBoundSize.Height();
+ }
+ else
+ FindBoundingRect( pEntry );
+ pZOrderList->Insert( pEntry, LIST_APPEND );
+ pEntry = pEntry->pflink;
+ nCur++;
+ }
+ }
+ AdjustScrollBars();
+}
+
+void SvxIconChoiceCtrl_Impl::UpdateBoundingRects()
+{
+ const ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ GetEntryBoundRect( pEntry );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::FindBoundingRect( SvxIconChoiceCtrlEntry* pEntry )
+{
+ DBG_ASSERT(!pEntry->IsPosLocked(),"Locked entry pos in FindBoundingRect");
+ if( pEntry->IsPosLocked() && IsBoundingRectValid( pEntry->aRect) )
+ {
+ AdjustVirtSize( pEntry->aRect );
+ return;
+ }
+ Size aSize( CalcBoundingSize( pEntry ) );
+ Point aPos(pGridMap->GetGridRect(pGridMap->GetUnoccupiedGrid(TRUE)).TopLeft());
+ SetBoundingRect_Impl( pEntry, aPos, aSize );
+}
+
+void SvxIconChoiceCtrl_Impl::SetBoundingRect_Impl( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos,
+ const Size& /*rBoundingSize*/ )
+{
+ Rectangle aGridRect( rPos, Size(nGridDX, nGridDY) );
+ pEntry->aGridRect = aGridRect;
+ Center( pEntry );
+ AdjustVirtSize( pEntry->aRect );
+ pGridMap->OccupyGrids( pEntry );
+}
+
+
+void SvxIconChoiceCtrl_Impl::SetCursor( SvxIconChoiceCtrlEntry* pEntry, BOOL bSyncSingleSelection,
+ BOOL bShowFocusAsync )
+{
+ if( pEntry == pCursor )
+ {
+ if( pCursor && eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection &&
+ !pCursor->IsSelected() )
+ SelectEntry( pCursor, TRUE, TRUE );
+ return;
+ }
+ ShowCursor( FALSE );
+ SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
+ pCursor = pEntry;
+ if( pOldCursor )
+ {
+ pOldCursor->ClearFlags( ICNVIEW_FLAG_FOCUSED );
+ if( eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection )
+ SelectEntry( pOldCursor, FALSE, TRUE ); // alten Cursor deselektieren
+ }
+ if( pCursor )
+ {
+ ToTop( pCursor );
+ pCursor->SetFlags( ICNVIEW_FLAG_FOCUSED );
+ if( eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection )
+ SelectEntry( pCursor, TRUE, TRUE );
+ if( !bShowFocusAsync )
+ ShowCursor( TRUE );
+ else
+ {
+ if( !nUserEventShowCursor )
+ nUserEventShowCursor =
+ Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl, UserEventHdl),
+ EVENTID_SHOW_CURSOR );
+ }
+ }
+}
+
+
+void SvxIconChoiceCtrl_Impl::ShowCursor( BOOL bShow )
+{
+ if( !pCursor || !bShow || !pView->HasFocus() )
+ {
+ pView->HideFocus();
+ return;
+ }
+ Rectangle aRect ( CalcFocusRect( pCursor ) );
+ /*pView->*/ShowFocus( aRect );
+}
+
+
+void SvxIconChoiceCtrl_Impl::HideDDIcon()
+{
+ pView->Update();
+ ImpHideDDIcon();
+ pDDBufDev = pDDDev;
+ pDDDev = 0;
+}
+
+void SvxIconChoiceCtrl_Impl::ImpHideDDIcon()
+{
+ if( pDDDev )
+ {
+ Size aSize( pDDDev->GetOutputSizePixel() );
+ // pView restaurieren
+ pView->DrawOutDev( aDDLastRectPos, aSize, Point(), aSize, *pDDDev );
+ }
+}
+
+
+void SvxIconChoiceCtrl_Impl::ShowDDIcon( SvxIconChoiceCtrlEntry* pRefEntry, const Point& rPosPix )
+{
+ pView->Update();
+ if( pRefEntry != pDDRefEntry )
+ {
+ DELETEZ(pDDDev);
+ DELETEZ(pDDBufDev);
+ }
+ BOOL bSelected = pRefEntry->IsSelected();
+ pRefEntry->ClearFlags( ICNVIEW_FLAG_SELECTED );
+ if( !pDDDev )
+ {
+ if( pDDBufDev )
+ {
+ // nicht bei jedem Move ein Device anlegen, da dies besonders
+ // auf Remote-Clients zu langsam ist
+ pDDDev = pDDBufDev;
+ pDDBufDev = 0;
+ }
+ else
+ {
+ pDDDev = new VirtualDevice( *pView );
+ pDDDev->SetFont( pView->GetFont() );
+ }
+ }
+ else
+ {
+ ImpHideDDIcon();
+ }
+ const Rectangle& rRect = GetEntryBoundRect( pRefEntry );
+ pDDDev->SetOutputSizePixel( rRect.GetSize() );
+
+ Point aPos( rPosPix );
+ ToDocPos( aPos );
+
+ Size aSize( pDDDev->GetOutputSizePixel() );
+ pDDRefEntry = pRefEntry;
+ aDDLastEntryPos = aPos;
+ aDDLastRectPos = aPos;
+
+ // Hintergrund sichern
+ pDDDev->DrawOutDev( Point(), aSize, aPos, aSize, *pView );
+ // Icon in pView malen
+ pRefEntry->SetFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS );
+ PaintEntry( pRefEntry, aPos );
+ pRefEntry->ClearFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS );
+ if( bSelected )
+ pRefEntry->SetFlags( ICNVIEW_FLAG_SELECTED );
+}
+
+void SvxIconChoiceCtrl_Impl::HideShowDDIcon( SvxIconChoiceCtrlEntry* pRefEntry, const Point& rPosPix )
+{
+/* In Notfaellen folgenden flackernden Code aktivieren:
+
+ HideDDIcon();
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+*/
+ if( !pDDDev )
+ {
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+ }
+
+ if( pRefEntry != pDDRefEntry )
+ {
+ HideDDIcon();
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+ }
+
+ Point aEmptyPoint;
+
+ Point aCurEntryPos( rPosPix );
+ ToDocPos( aCurEntryPos );
+
+ const Rectangle& rRect = GetEntryBoundRect( pRefEntry );
+ Size aEntrySize( rRect.GetSize() );
+ Rectangle aPrevEntryRect( aDDLastEntryPos, aEntrySize );
+ Rectangle aCurEntryRect( aCurEntryPos, aEntrySize );
+
+ if( !aPrevEntryRect.IsOver( aCurEntryRect ) )
+ {
+ HideDDIcon();
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+ }
+
+ // Ueberlappung des neuen und alten D&D-Pointers!
+
+ Rectangle aFullRect( aPrevEntryRect.Union( aCurEntryRect ) );
+ if( !pDDTempDev )
+ {
+ pDDTempDev = new VirtualDevice( *pView );
+ pDDTempDev->SetFont( pView->GetFont() );
+ }
+
+ Size aFullSize( aFullRect.GetSize() );
+ Point aFullPos( aFullRect.TopLeft() );
+
+ pDDTempDev->SetOutputSizePixel( aFullSize );
+
+ // Hintergrund (mit dem alten D&D-Pointer!) sichern
+ pDDTempDev->DrawOutDev( aEmptyPoint, aFullSize, aFullPos, aFullSize, *pView );
+ // den alten Buffer in den neuen Buffer pasten
+ aDDLastRectPos = aDDLastRectPos - aFullPos;
+
+ pDDTempDev->DrawOutDev(
+ aDDLastRectPos,
+ pDDDev->GetOutputSizePixel(),
+ aEmptyPoint,
+ pDDDev->GetOutputSizePixel(),
+ *pDDDev );
+
+ // Swap
+ VirtualDevice* pTemp = pDDDev;
+ pDDDev = pDDTempDev;
+ pDDTempDev = pTemp;
+
+ // in den restaurierten Hintergrund den neuen D&D-Pointer zeichnen
+ pDDTempDev->SetOutputSizePixel( pDDDev->GetOutputSizePixel() );
+ pDDTempDev->DrawOutDev(
+ aEmptyPoint, aFullSize, aEmptyPoint, aFullSize, *pDDDev );
+ Point aRelPos = aCurEntryPos - aFullPos;
+ pRefEntry->SetFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS );
+ PaintEntry( pRefEntry, aRelPos, pDDTempDev );
+ pRefEntry->ClearFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS );
+
+ aDDLastRectPos = aFullPos;
+ aDDLastEntryPos = aCurEntryPos;
+
+ pView->DrawOutDev(
+ aDDLastRectPos,
+ pDDDev->GetOutputSizePixel(),
+ aEmptyPoint,
+ pDDDev->GetOutputSizePixel(),
+ *pDDTempDev );
+}
+
+void SvxIconChoiceCtrl_Impl::InvalidateBoundingRect( SvxIconChoiceCtrlEntry* pEntry )
+{
+ InvalidateBoundingRect( pEntry->aRect );
+}
+
+
+BOOL SvxIconChoiceCtrl_Impl::HandleScrollCommand( const CommandEvent& rCmd )
+{
+ Rectangle aDocRect( GetDocumentRect() );
+ Rectangle aVisRect( GetVisibleRect() );
+ if( aVisRect.IsInside( aDocRect ))
+ return FALSE;
+ Size aDocSize( aDocRect.GetSize() );
+ Size aVisSize( aVisRect.GetSize() );
+ BOOL bHor = aDocSize.Width() > aVisSize.Width();
+ BOOL bVer = aDocSize.Height() > aVisSize.Height();
+
+ long nScrollDX = 0, nScrollDY = 0;
+
+ switch( rCmd.GetCommand() )
+ {
+ case COMMAND_STARTAUTOSCROLL:
+ {
+ pView->EndTracking();
+ USHORT nScrollFlags = 0;
+ if( bHor )
+ nScrollFlags |= AUTOSCROLL_HORZ;
+ if( bVer )
+ nScrollFlags |= AUTOSCROLL_VERT;
+ if( nScrollFlags )
+ {
+ pView->StartAutoScroll( nScrollFlags );
+ return TRUE;
+ }
+ }
+ break;
+
+ case COMMAND_WHEEL:
+ {
+ const CommandWheelData* pData = rCmd.GetWheelData();
+ if( pData && (COMMAND_WHEEL_SCROLL == pData->GetMode()) && !pData->IsHorz() )
+ {
+ ULONG nScrollLines = pData->GetScrollLines();
+ if( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
+ {
+ nScrollDY = GetScrollBarPageSize( aVisSize.Width() );
+ if( pData->GetDelta() < 0 )
+ nScrollDY *= -1;
+ }
+ else
+ {
+ nScrollDY = pData->GetNotchDelta() * (long)nScrollLines;
+ nScrollDY *= GetScrollBarLineSize();
+ }
+ }
+ }
+ break;
+
+ case COMMAND_AUTOSCROLL:
+ {
+ const CommandScrollData* pData = rCmd.GetAutoScrollData();
+ if( pData )
+ {
+ nScrollDX = pData->GetDeltaX() * GetScrollBarLineSize();
+ nScrollDY = pData->GetDeltaY() * GetScrollBarLineSize();
+ }
+ }
+ break;
+ }
+
+ if( nScrollDX || nScrollDY )
+ {
+ aVisRect.Top() -= nScrollDY;
+ aVisRect.Bottom() -= nScrollDY;
+ aVisRect.Left() -= nScrollDX;
+ aVisRect.Right() -= nScrollDX;
+ MakeVisible( aVisRect );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void SvxIconChoiceCtrl_Impl::Command( const CommandEvent& rCEvt )
+{
+ // Rollmaus-Event?
+ if( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
+ {
+#if 1
+ if( HandleScrollCommand( rCEvt ) )
+ return;
+#else
+ ScrollBar* pHor = aHorSBar.IsVisible() ? &aHorSBar : 0;
+ ScrollBar* pVer = aVerSBar.IsVisible() ? &aVerSBar : 0;
+ if( pView->HandleScrollCommand( rCEvt, pHor, pVer ) )
+ return;
+#endif
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::ToTop( SvxIconChoiceCtrlEntry* pEntry )
+{
+ if( pZOrderList->GetObject( pZOrderList->Count() - 1 ) != pEntry )
+ {
+ ULONG nPos = pZOrderList->GetPos( (void*)pEntry );
+ pZOrderList->Remove( nPos );
+ pZOrderList->Insert( pEntry, LIST_APPEND );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::ClipAtVirtOutRect( Rectangle& rRect ) const
+{
+ if( rRect.Bottom() >= aVirtOutputSize.Height() )
+ rRect.Bottom() = aVirtOutputSize.Height() - 1;
+ if( rRect.Right() >= aVirtOutputSize.Width() )
+ rRect.Right() = aVirtOutputSize.Width() - 1;
+ if( rRect.Top() < 0 )
+ rRect.Top() = 0;
+ if( rRect.Left() < 0 )
+ rRect.Left() = 0;
+}
+
+// rRect: Bereich des Dokumentes (in Dokumentkoordinaten), der
+// sichtbar gemacht werden soll.
+// bScrBar == TRUE: Das Rect wurde aufgrund eines ScrollBar-Events berechnet
+
+void SvxIconChoiceCtrl_Impl::MakeVisible( const Rectangle& rRect, BOOL bScrBar,
+ BOOL bCallRectChangedHdl )
+{
+ Rectangle aVirtRect( rRect );
+ ClipAtVirtOutRect( aVirtRect );
+ Point aOrigin( pView->GetMapMode().GetOrigin() );
+ // in Dokumentkoordinate umwandeln
+ aOrigin *= -1;
+ Rectangle aOutputArea( GetOutputRect() );
+ if( aOutputArea.IsInside( aVirtRect ) )
+ return; // ist schon sichtbar
+
+ long nDy;
+ if( aVirtRect.Top() < aOutputArea.Top() )
+ {
+ // nach oben scrollen (nDy < 0)
+ nDy = aVirtRect.Top() - aOutputArea.Top();
+ }
+ else if( aVirtRect.Bottom() > aOutputArea.Bottom() )
+ {
+ // nach unten scrollen (nDy > 0)
+ nDy = aVirtRect.Bottom() - aOutputArea.Bottom();
+ }
+ else
+ nDy = 0;
+
+ long nDx;
+ if( aVirtRect.Left() < aOutputArea.Left() )
+ {
+ // nach links scrollen (nDx < 0)
+ nDx = aVirtRect.Left() - aOutputArea.Left();
+ }
+ else if( aVirtRect.Right() > aOutputArea.Right() )
+ {
+ // nach rechts scrollen (nDx > 0)
+ nDx = aVirtRect.Right() - aOutputArea.Right();
+ }
+ else
+ nDx = 0;
+
+ aOrigin.X() += nDx;
+ aOrigin.Y() += nDy;
+ aOutputArea.SetPos( aOrigin );
+ if( GetUpdateMode() )
+ {
+ HideDDIcon();
+ pView->Update();
+ ShowCursor( FALSE );
+ }
+
+ // Origin fuer SV invertieren (damit wir in
+ // Dokumentkoordinaten scrollen/painten koennen)
+ aOrigin *= -1;
+ SetOrigin( aOrigin );
+
+ BOOL bScrollable = pView->GetBackground().IsScrollable();
+ if( pView->HasBackground() && !bScrollable )
+ {
+ Rectangle aRect( GetOutputRect());
+ Wallpaper aPaper( pView->GetBackground() );
+ aPaper.SetRect( aRect );
+ pView->SetBackground( aPaper );
+ }
+
+ if( bScrollable && GetUpdateMode() )
+ {
+ // in umgekehrte Richtung scrollen!
+ pView->Control::Scroll( -nDx, -nDy, aOutputArea,
+ SCROLL_NOCHILDREN | SCROLL_USECLIPREGION | SCROLL_CLIP );
+ }
+ else
+ pView->Invalidate(INVALIDATE_NOCHILDREN);
+
+ if( aHorSBar.IsVisible() || aVerSBar.IsVisible() )
+ {
+ if( !bScrBar )
+ {
+ aOrigin *= -1;
+ // Thumbs korrigieren
+ if(aHorSBar.IsVisible() && aHorSBar.GetThumbPos() != aOrigin.X())
+ aHorSBar.SetThumbPos( aOrigin.X() );
+ if(aVerSBar.IsVisible() && aVerSBar.GetThumbPos() != aOrigin.Y())
+ aVerSBar.SetThumbPos( aOrigin.Y() );
+ }
+ }
+
+ if( GetUpdateMode() )
+ ShowCursor( TRUE );
+
+ // pruefen, ob ScrollBars noch benoetigt werden
+ CheckScrollBars();
+ if( bScrollable && GetUpdateMode() )
+ pView->Update();
+
+ // kann der angeforderte Bereich nicht komplett sichtbar gemacht werden,
+ // wird auf jeden Fall der Vis-Rect-Changed-Handler gerufen. Eintreten kann der
+ // Fall z.B. wenn nur wenige Pixel des unteren Randes nicht sichtbar sind,
+ // eine ScrollBar aber eine groessere Line-Size eingestellt hat.
+ if( bCallRectChangedHdl || GetOutputRect() != rRect )
+ VisRectChanged();
+}
+
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::FindNewCursor()
+{
+ SvxIconChoiceCtrlEntry* pNewCursor;
+ if( pCursor )
+ {
+ pNewCursor = pImpCursor->GoLeftRight( pCursor, FALSE );
+ if( !pNewCursor )
+ {
+ pNewCursor = pImpCursor->GoLeftRight( pCursor, TRUE );
+ if( !pNewCursor )
+ {
+ pNewCursor = pImpCursor->GoUpDown( pCursor, FALSE );
+ if( !pNewCursor )
+ pNewCursor = pImpCursor->GoUpDown( pCursor, TRUE );
+ }
+ }
+ }
+ else
+ pNewCursor = (SvxIconChoiceCtrlEntry*)aEntries.First();
+ DBG_ASSERT(!pNewCursor|| (pCursor&&pCursor!=pNewCursor),"FindNewCursor failed");
+ return pNewCursor;
+}
+
+ULONG SvxIconChoiceCtrl_Impl::GetSelectionCount() const
+{
+ if( (nWinBits & WB_HIGHLIGHTFRAME) && pCurHighlightFrame )
+ return 1;
+ return nSelectionCount;
+}
+
+void SvxIconChoiceCtrl_Impl::ToggleSelection( SvxIconChoiceCtrlEntry* pEntry )
+{
+ BOOL bSel;
+ if( pEntry->IsSelected() )
+ bSel = FALSE;
+ else
+ bSel = TRUE;
+ SelectEntry( pEntry, bSel, TRUE, TRUE );
+}
+
+void SvxIconChoiceCtrl_Impl::DeselectAllBut( SvxIconChoiceCtrlEntry* pThisEntryNot,
+ BOOL bPaintSync )
+{
+ ClearSelectedRectList();
+ //
+ // !!!!!!! Todo: Evtl. Z-Orderlist abarbeiten !!!!!!!
+ //
+ ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ if( pEntry != pThisEntryNot && pEntry->IsSelected() )
+ SelectEntry( pEntry, FALSE, TRUE, TRUE, bPaintSync );
+ }
+ pAnchor = 0;
+ nFlags &= (~F_ADD_MODE);
+}
+
+Size SvxIconChoiceCtrl_Impl::GetMinGrid() const
+{
+ Size aMinSize( aImageSize );
+ aMinSize.Width() += 2 * LROFFS_BOUND;
+ aMinSize.Height() += TBOFFS_BOUND; // PB: einmal Offset reicht (FileDlg)
+ String aStrDummy( RTL_CONSTASCII_USTRINGPARAM( "XXX" ) );
+ Size aTextSize( pView->GetTextWidth( aStrDummy ), pView->GetTextHeight() );
+ if( nWinBits & WB_ICON )
+ {
+ aMinSize.Height() += VER_DIST_BMP_STRING;
+ aMinSize.Height() += aTextSize.Height();
+ }
+ else
+ {
+ aMinSize.Width() += HOR_DIST_BMP_STRING;
+ aMinSize.Width() += aTextSize.Width();
+ }
+ return aMinSize;
+}
+
+void SvxIconChoiceCtrl_Impl::SetGrid( const Size& rSize )
+{
+ Size aSize( rSize );
+ Size aMinSize( GetMinGrid() );
+ if( aSize.Width() < aMinSize.Width() )
+ aSize.Width() = aMinSize.Width();
+ if( aSize.Height() < aMinSize.Height() )
+ aSize.Height() = aMinSize.Height();
+
+ nGridDX = aSize.Width();
+ // HACK(Detail-Modus ist noch nicht vollstaendig implementiert!)
+ // dieses Workaround bringts mit einer Spalte zum Fliegen
+ if( nWinBits & WB_DETAILS )
+ {
+ const SvxIconChoiceCtrlColumnInfo* pCol = GetColumn( 0 );
+ if( pCol )
+ ((SvxIconChoiceCtrlColumnInfo*)pCol)->SetWidth( nGridDX );
+ }
+ nGridDY = aSize.Height();
+ SetDefaultTextSize();
+}
+
+// berechnet die maximale Groesse, die das Textrechteck innerhalb des
+// umschliessenden Rechtecks einnehmen kann. Im Modus WB_ICON und
+// IcnShowTextFull wird Bottom auf LONG_MAX gesetzt
+
+Rectangle SvxIconChoiceCtrl_Impl::CalcMaxTextRect( const SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ Rectangle aBoundRect;
+ // keine Endlosrekursion! deshalb das Bound-Rect hier nicht berechnen
+ if( IsBoundingRectValid( pEntry->aRect ) )
+ aBoundRect = pEntry->aRect;
+ else
+ aBoundRect = pEntry->aGridRect;
+
+ Rectangle aBmpRect( ((SvxIconChoiceCtrl_Impl*)this)->CalcBmpRect(
+ (SvxIconChoiceCtrlEntry*)pEntry ) );
+ if( nWinBits & WB_ICON )
+ {
+ aBoundRect.Top() = aBmpRect.Bottom();
+ aBoundRect.Top() += VER_DIST_BMP_STRING;
+ if( aBoundRect.Top() > aBoundRect.Bottom())
+ aBoundRect.Top() = aBoundRect.Bottom();
+ aBoundRect.Left() += LROFFS_BOUND;
+ aBoundRect.Left()++;
+ aBoundRect.Right() -= LROFFS_BOUND;
+ aBoundRect.Right()--;
+ if( aBoundRect.Left() > aBoundRect.Right())
+ aBoundRect.Left() = aBoundRect.Right();
+ if( GetEntryTextModeSmart( pEntry ) == IcnShowTextFull )
+ aBoundRect.Bottom() = LONG_MAX;
+ }
+ else
+ {
+ aBoundRect.Left() = aBmpRect.Right();
+ aBoundRect.Left() += HOR_DIST_BMP_STRING;
+ aBoundRect.Right() -= LROFFS_BOUND;
+ if( aBoundRect.Left() > aBoundRect.Right() )
+ aBoundRect.Left() = aBoundRect.Right();
+ long nHeight = aBoundRect.GetSize().Height();
+ nHeight = nHeight - aDefaultTextSize.Height();
+ nHeight /= 2;
+ aBoundRect.Top() += nHeight;
+ aBoundRect.Bottom() -= nHeight;
+ }
+ return aBoundRect;
+}
+
+void SvxIconChoiceCtrl_Impl::SetDefaultTextSize()
+{
+ long nDY = nGridDY;
+ nDY -= aImageSize.Height();
+ nDY -= VER_DIST_BMP_STRING;
+ nDY -= 2*TBOFFS_BOUND;
+ if( nDY <= 0 )
+ nDY = 2;
+
+ long nDX = nGridDX;
+ nDX -= 2*LROFFS_BOUND;
+ nDX -= 2;
+ if( nDX <= 0 )
+ nDX = 2;
+
+ String aStrDummy( RTL_CONSTASCII_USTRINGPARAM( "X" ) );
+ long nHeight = pView->GetTextHeight();
+ if( nDY < nHeight )
+ nDY = nHeight;
+ aDefaultTextSize = Size( nDX, nDY );
+}
+
+
+void SvxIconChoiceCtrl_Impl::Center( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ pEntry->aRect = pEntry->aGridRect;
+ Size aSize( CalcBoundingSize( pEntry ) );
+ if( nWinBits & WB_ICON )
+ {
+ // horizontal zentrieren
+ long nBorder = pEntry->aGridRect.GetWidth() - aSize.Width();
+ pEntry->aRect.Left() += nBorder / 2;
+ pEntry->aRect.Right() -= nBorder / 2;
+ }
+ // vertikal zentrieren
+ pEntry->aRect.Bottom() = pEntry->aRect.Top() + aSize.Height();
+}
+
+
+// Die Deltas entsprechen Offsets, um die die View auf dem Doc verschoben wird
+// links, hoch: Offsets < 0
+// rechts, runter: Offsets > 0
+void SvxIconChoiceCtrl_Impl::Scroll( long nDeltaX, long nDeltaY, BOOL bScrollBar )
+{
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+ // in Dokumentkoordinate umwandeln
+ aOrigin *= -1;
+ aOrigin.Y() += nDeltaY;
+ aOrigin.X() += nDeltaX;
+ Rectangle aRect( aOrigin, aOutputSize );
+ MakeVisible( aRect, bScrollBar );
+}
+
+
+const Size& SvxIconChoiceCtrl_Impl::GetItemSize( SvxIconChoiceCtrlEntry*,
+ IcnViewFieldType eItem ) const
+{
+ if( eItem == IcnViewFieldTypeText )
+ return aDefaultTextSize;
+ return aImageSize;
+}
+
+Rectangle SvxIconChoiceCtrl_Impl::CalcFocusRect( SvxIconChoiceCtrlEntry* pEntry )
+{
+ Rectangle aBmpRect( CalcBmpRect( pEntry ) );
+ Rectangle aTextRect( CalcTextRect( pEntry ) );
+ Rectangle aBoundRect( GetEntryBoundRect( pEntry ) );
+ Rectangle aFocusRect( aBoundRect.Left(), aBmpRect.Top() - 1,
+ aBoundRect.Right() - 4, aTextRect.Bottom() + 1 );
+ // Das Fokusrechteck soll nicht den Text beruehren
+ if( aFocusRect.Left() - 1 >= pEntry->aRect.Left() )
+ aFocusRect.Left()--;
+ if( aFocusRect.Right() + 1 <= pEntry->aRect.Right() )
+ aFocusRect.Right()++;
+
+ return aFocusRect;
+}
+
+// Der 'Hot Spot' sind die inneren 50% der Rechteckflaeche
+static Rectangle GetHotSpot( const Rectangle& rRect )
+{
+ Rectangle aResult( rRect );
+ aResult.Justify();
+ Size aSize( rRect.GetSize() );
+ long nDelta = aSize.Width() / 4;
+ aResult.Left() += nDelta;
+ aResult.Right() -= nDelta;
+ nDelta = aSize.Height() / 4;
+ aResult.Top() += nDelta;
+ aResult.Bottom() -= nDelta;
+ return aResult;
+}
+
+void SvxIconChoiceCtrl_Impl::SelectRect( SvxIconChoiceCtrlEntry* pEntry1, SvxIconChoiceCtrlEntry* pEntry2,
+ BOOL bAdd, SvPtrarr* pOtherRects )
+{
+ DBG_ASSERT(pEntry1 && pEntry2,"SelectEntry: Invalid Entry-Ptr");
+ Rectangle aRect( GetEntryBoundRect( pEntry1 ) );
+ aRect.Union( GetEntryBoundRect( pEntry2 ) );
+ SelectRect( aRect, bAdd, pOtherRects );
+}
+
+void SvxIconChoiceCtrl_Impl::SelectRect( const Rectangle& rRect, BOOL bAdd,
+ SvPtrarr* pOtherRects )
+{
+ aCurSelectionRect = rRect;
+ if( !pZOrderList || !pZOrderList->Count() )
+ return;
+
+ // Flag setzen, damit im Select kein ToTop gerufen wird
+ BOOL bAlreadySelectingRect = nFlags & F_SELECTING_RECT ? TRUE : FALSE;
+ nFlags |= F_SELECTING_RECT;
+
+ CheckBoundingRects();
+ pView->Update();
+ const ULONG nCount = pZOrderList->Count();
+
+ Rectangle aRect( rRect );
+ aRect.Justify();
+ BOOL bCalcOverlap = (bAdd && pOtherRects && pOtherRects->Count()) ? TRUE : FALSE;
+
+ BOOL bResetClipRegion = FALSE;
+ if( !pView->IsClipRegion() )
+ {
+ bResetClipRegion = TRUE;
+ pView->SetClipRegion( GetOutputRect() );
+ }
+
+ for( ULONG nPos = 0; nPos < nCount; nPos++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nPos ));
+
+ if( !IsBoundingRectValid( pEntry->aRect ))
+ FindBoundingRect( pEntry );
+ Rectangle aBoundRect( GetHotSpot( pEntry->aRect ) );
+ BOOL bSelected = pEntry->IsSelected();
+
+ BOOL bOverlaps;
+ if( bCalcOverlap )
+ bOverlaps = IsOver( pOtherRects, aBoundRect );
+ else
+ bOverlaps = FALSE;
+ BOOL bOver = aRect.IsOver( aBoundRect );
+
+ if( bOver && !bOverlaps )
+ {
+ // Ist im neuen Selektionsrechteck und in keinem alten
+ // => selektieren
+ if( !bSelected )
+ SelectEntry( pEntry, TRUE, TRUE, TRUE );
+ }
+ else if( !bAdd )
+ {
+ // ist ausserhalb des Selektionsrechtecks
+ // => Selektion entfernen
+ if( bSelected )
+ SelectEntry( pEntry, FALSE, TRUE, TRUE );
+ }
+ else if( bAdd && bOverlaps )
+ {
+ // Der Eintrag befindet sich in einem alten (=>Aufspannen
+ // mehrerer Rechtecke mit Ctrl!) Selektionsrechteck
+
+ // Hier ist noch ein Bug! Der Selektionsstatus eines Eintrags
+ // in einem vorherigen Rechteck, muss restauriert werden, wenn
+ // er vom aktuellen Selektionsrechteck beruehrt wurde, jetzt aber
+ // nicht mehr in ihm liegt. Ich gehe hier der Einfachheit halber
+ // pauschal davon aus, dass die Eintraege in den alten Rechtecken
+ // alle selektiert sind. Ebenso ist es falsch, die Schnittmenge
+ // nur zu deselektieren.
+ // Loesungsmoeglichkeit: Snapshot der Selektion vor dem Auf-
+ // spannen des Rechtecks merken
+ if( aBoundRect.IsOver( rRect))
+ {
+ // Schnittmenge zwischen alten Rects & aktuellem Rect desel.
+ if( bSelected )
+ SelectEntry( pEntry, FALSE, TRUE, TRUE );
+ }
+ else
+ {
+ // Eintrag eines alten Rects selektieren
+ if( !bSelected )
+ SelectEntry( pEntry, TRUE, TRUE, TRUE );
+ }
+ }
+ else if( !bOver && bSelected )
+ {
+ // Der Eintrag liegt voellig ausserhalb und wird deshalb desel.
+ SelectEntry( pEntry, FALSE, TRUE, TRUE );
+ }
+ }
+
+ if( !bAlreadySelectingRect )
+ nFlags &= ~F_SELECTING_RECT;
+
+ pView->Update();
+ if( bResetClipRegion )
+ pView->SetClipRegion();
+}
+
+void SvxIconChoiceCtrl_Impl::SelectRange(
+ SvxIconChoiceCtrlEntry* pStart,
+ SvxIconChoiceCtrlEntry* pEnd,
+ BOOL bAdd )
+{
+ ULONG nFront = GetEntryListPos( pStart );
+ ULONG nBack = GetEntryListPos( pEnd );
+ ULONG nFirst = std::min( nFront, nBack );
+ ULONG nLast = std::max( nFront, nBack );
+ ULONG i;
+ SvxIconChoiceCtrlEntry* pEntry;
+
+ if ( ! bAdd )
+ {
+ // deselect everything before the first entry if not in
+ // adding mode
+ for ( i=0; i<nFirst; i++ )
+ {
+ pEntry = GetEntry( i );
+ if( pEntry->IsSelected() )
+ SelectEntry( pEntry, FALSE, TRUE, TRUE, TRUE );
+ }
+ }
+
+ // select everything between nFirst and nLast
+ for ( i=nFirst; i<=nLast; i++ )
+ {
+ pEntry = GetEntry( i );
+ if( ! pEntry->IsSelected() )
+ SelectEntry( pEntry, TRUE, TRUE, TRUE, TRUE );
+ }
+
+ if ( ! bAdd )
+ {
+ // deselect everything behind the last entry if not in
+ // adding mode
+ ULONG nEnd = GetEntryCount();
+ for ( ; i<nEnd; i++ )
+ {
+ pEntry = GetEntry( i );
+ if( pEntry->IsSelected() )
+ SelectEntry( pEntry, FALSE, TRUE, TRUE, TRUE );
+ }
+ }
+}
+
+BOOL SvxIconChoiceCtrl_Impl::IsOver( SvPtrarr* pRectList, const Rectangle& rBoundRect ) const
+{
+ const USHORT nCount = pRectList->Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ Rectangle* pRect = (Rectangle*)pRectList->GetObject( nCur );
+ if( rBoundRect.IsOver( *pRect ))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SvxIconChoiceCtrl_Impl::AddSelectedRect( SvxIconChoiceCtrlEntry* pEntry1,
+ SvxIconChoiceCtrlEntry* pEntry2 )
+{
+ DBG_ASSERT(pEntry1 && pEntry2,"SelectEntry: Invalid Entry-Ptr");
+ Rectangle aRect( GetEntryBoundRect( pEntry1 ) );
+ aRect.Union( GetEntryBoundRect( pEntry2 ) );
+ AddSelectedRect( aRect );
+}
+
+void SvxIconChoiceCtrl_Impl::AddSelectedRect( const Rectangle& rRect )
+{
+ Rectangle* pRect = new Rectangle( rRect );
+ pRect->Justify();
+ aSelectedRectList.Insert( (void*)pRect, aSelectedRectList.Count() );
+}
+
+void SvxIconChoiceCtrl_Impl::ClearSelectedRectList()
+{
+ const USHORT nCount = aSelectedRectList.Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ Rectangle* pRect = (Rectangle*)aSelectedRectList.GetObject( nCur );
+ delete pRect;
+ }
+ aSelectedRectList.Remove( 0, aSelectedRectList.Count() );
+}
+
+void SvxIconChoiceCtrl_Impl::CalcScrollOffsets( const Point& rPosPixel,
+ long& rX, long& rY, BOOL isInDragDrop, USHORT nBorderWidth)
+{
+ // Scrolling der View, falls sich der Mauszeiger im Grenzbereich des
+ // Fensters befindet
+ long nPixelToScrollX = 0;
+ long nPixelToScrollY = 0;
+ Size aWndSize = aOutputSize;
+
+ nBorderWidth = (USHORT)(Min( (long)(aWndSize.Height()-1), (long)nBorderWidth ));
+ nBorderWidth = (USHORT)(Min( (long)(aWndSize.Width()-1), (long)nBorderWidth ));
+
+ if ( rPosPixel.X() < nBorderWidth )
+ {
+ if( isInDragDrop )
+ nPixelToScrollX = -DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollX = rPosPixel.X()- nBorderWidth;
+ }
+ else if ( rPosPixel.X() > aWndSize.Width() - nBorderWidth )
+ {
+ if( isInDragDrop )
+ nPixelToScrollX = DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollX = rPosPixel.X() - (aWndSize.Width() - nBorderWidth);
+ }
+ if ( rPosPixel.Y() < nBorderWidth )
+ {
+ if( isInDragDrop )
+ nPixelToScrollY = -DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollY = rPosPixel.Y() - nBorderWidth;
+ }
+ else if ( rPosPixel.Y() > aWndSize.Height() - nBorderWidth )
+ {
+ if( isInDragDrop )
+ nPixelToScrollY = DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollY = rPosPixel.Y() - (aWndSize.Height() - nBorderWidth);
+ }
+
+ rX = nPixelToScrollX;
+ rY = nPixelToScrollY;
+}
+
+IMPL_LINK(SvxIconChoiceCtrl_Impl, AutoArrangeHdl, void*, EMPTYARG )
+{
+ aAutoArrangeTimer.Stop();
+ Arrange( IsAutoArrange() );
+ return 0;
+}
+
+IMPL_LINK(SvxIconChoiceCtrl_Impl, VisRectChangedHdl, void*, EMPTYARG )
+{
+ aVisRectChangedTimer.Stop();
+ pView->VisibleRectChanged();
+ return 0;
+}
+
+IMPL_LINK(SvxIconChoiceCtrl_Impl, DocRectChangedHdl, void*, EMPTYARG )
+{
+ aDocRectChangedTimer.Stop();
+ pView->DocumentRectChanged();
+ return 0;
+}
+
+void SvxIconChoiceCtrl_Impl::PrepareCommandEvent( const CommandEvent& rCEvt )
+{
+ StopEditTimer();
+ SvxIconChoiceCtrlEntry* pEntry = pView->GetEntry( rCEvt.GetMousePosPixel() );
+ if( (nFlags & F_DOWN_CTRL) && pEntry && !pEntry->IsSelected() )
+ SelectEntry( pEntry, TRUE, TRUE );
+ nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
+}
+
+BOOL SvxIconChoiceCtrl_Impl::IsTextHit( SvxIconChoiceCtrlEntry* pEntry, const Point& rDocPos )
+{
+ Rectangle aRect( CalcTextRect( pEntry ));
+ if( aRect.IsInside( rDocPos ) )
+ return TRUE;
+ return FALSE;
+}
+
+IMPL_LINK(SvxIconChoiceCtrl_Impl, EditTimeoutHdl, Timer*, EMPTYARG )
+{
+ SvxIconChoiceCtrlEntry* pEntry = GetCurEntry();
+ if( bEntryEditingEnabled && pEntry &&
+ pEntry->IsSelected())
+ {
+ if( pView->EditingEntry( pEntry ))
+ EditEntry( pEntry );
+ }
+ return 0;
+}
+
+
+//
+// Funktionen zum Ausrichten der Eintraege am Grid
+//
+
+// pStart == 0: Alle Eintraege werden ausgerichtet
+// sonst: Alle Eintraege der Zeile ab einschliesslich pStart werden ausgerichtet
+void SvxIconChoiceCtrl_Impl::AdjustEntryAtGrid( SvxIconChoiceCtrlEntry* pStart )
+{
+ SvPtrarr aLists;
+ pImpCursor->CreateGridAjustData( aLists, pStart );
+ const USHORT nCount = aLists.Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ AdjustAtGrid( *(SvPtrarr*)aLists[ nCur ], pStart );
+ IcnCursor_Impl::DestroyGridAdjustData( aLists );
+ CheckScrollBars();
+}
+
+// Richtet eine Zeile aus, erweitert ggf. die Breite; Bricht die Zeile nicht um
+void SvxIconChoiceCtrl_Impl::AdjustAtGrid( const SvPtrarr& rRow, SvxIconChoiceCtrlEntry* pStart )
+{
+ if( !rRow.Count() )
+ return;
+
+ BOOL bGo;
+ if( !pStart )
+ bGo = TRUE;
+ else
+ bGo = FALSE;
+
+ long nCurRight = 0;
+ for( USHORT nCur = 0; nCur < rRow.Count(); nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)rRow[ nCur ];
+ if( !bGo && pCur == pStart )
+ bGo = TRUE;
+
+ //SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur);
+ // Massgebend (fuer unser Auge) ist die Bitmap, da sonst
+ // durch lange Texte der Eintrag stark springen kann
+ const Rectangle& rBoundRect = GetEntryBoundRect( pCur );
+ Rectangle aCenterRect( CalcBmpRect( pCur, 0 ));
+ if( bGo && !pCur->IsPosLocked() )
+ {
+ long nWidth = aCenterRect.GetSize().Width();
+ Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) );
+ while( aNewPos.X() < nCurRight )
+ aNewPos.X() += nGridDX;
+ if( aNewPos != rBoundRect.TopLeft() )
+ {
+ SetEntryPos( pCur, aNewPos );
+ pCur->SetFlags( ICNVIEW_FLAG_POS_MOVED );
+ nFlags |= F_MOVED_ENTRIES;
+ }
+ nCurRight = aNewPos.X() + nWidth;
+ }
+ else
+ {
+ nCurRight = rBoundRect.Right();
+ }
+ }
+}
+
+// Richtet Rect am Grid aus, garantiert jedoch nicht, dass die
+// neue Pos. frei ist. Die Pos. kann fuer SetEntryPos verwendet werden.
+// Das CenterRect beschreibt den Teil des BoundRects, der fuer
+// die Berechnung des Ziel-Rechtecks verwendet wird.
+Point SvxIconChoiceCtrl_Impl::AdjustAtGrid( const Rectangle& rCenterRect,
+ const Rectangle& rBoundRect ) const
+{
+ Point aPos( rCenterRect.TopLeft() );
+ Size aSize( rCenterRect.GetSize() );
+
+ aPos.X() -= LROFFS_WINBORDER;
+ aPos.Y() -= TBOFFS_WINBORDER;
+
+ // align (ref ist mitte des rects)
+ short nGridX = (short)((aPos.X()+(aSize.Width()/2)) / nGridDX);
+ short nGridY = (short)((aPos.Y()+(aSize.Height()/2)) / nGridDY);
+ aPos.X() = nGridX * nGridDX;
+ aPos.Y() = nGridY * nGridDY;
+ // hor. center
+ aPos.X() += (nGridDX - rBoundRect.GetSize().Width() ) / 2;
+
+ aPos.X() += LROFFS_WINBORDER;
+ aPos.Y() += TBOFFS_WINBORDER;
+
+ return aPos;
+}
+
+void SvxIconChoiceCtrl_Impl::SetEntryTextMode( SvxIconChoiceCtrlTextMode eMode, SvxIconChoiceCtrlEntry* pEntry )
+{
+ if( !pEntry )
+ {
+ if( eTextMode != eMode )
+ {
+ if( eTextMode == IcnShowTextDontKnow )
+ eTextMode = IcnShowTextShort;
+ eTextMode = eMode;
+ Arrange( TRUE );
+ }
+ }
+ else
+ {
+ if( pEntry->eTextMode != eMode )
+ {
+ pEntry->eTextMode = eMode;
+ InvalidateEntry( pEntry );
+ pView->Invalidate( GetEntryBoundRect( pEntry ) );
+ AdjustVirtSize( pEntry->aRect );
+ }
+ }
+}
+
+SvxIconChoiceCtrlTextMode SvxIconChoiceCtrl_Impl::GetTextMode( const SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ if( !pEntry )
+ return eTextMode;
+ return pEntry->GetTextMode();
+}
+
+SvxIconChoiceCtrlTextMode SvxIconChoiceCtrl_Impl::GetEntryTextModeSmart( const SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ DBG_ASSERT(pEntry,"GetEntryTextModeSmart: Entry not set");
+ SvxIconChoiceCtrlTextMode eMode = pEntry->GetTextMode();
+ if( eMode == IcnShowTextDontKnow )
+ return eTextMode;
+ return eMode;
+}
+
+void SvxIconChoiceCtrl_Impl::ShowEntryFocusRect( const SvxIconChoiceCtrlEntry* pEntry )
+{
+ if( !pEntry )
+ {
+ pView->HideFocus();
+ }
+ else
+ {
+ Rectangle aRect ( CalcFocusRect( (SvxIconChoiceCtrlEntry*)pEntry ) );
+ /*pView->*/ShowFocus( aRect );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Draw my own focusrect, because the focusrect of the outputdevice has got the inverted color
+// of the background. But what will we see, if the the backgroundcolor is gray ? - We will see
+// a gray focusrect on a gray background !!!
+//
+void SvxIconChoiceCtrl_Impl::ShowFocus ( Rectangle& rRect )
+{
+ Color aBkgColor ( pView->GetBackground().GetColor() );
+ Color aPenColor;
+ USHORT nColor = ( aBkgColor.GetRed() + aBkgColor.GetGreen() + aBkgColor.GetBlue() ) / 3;
+ if ( nColor > 128 )
+ aPenColor.SetColor ( COL_BLACK );
+ else
+ aPenColor.SetColor( COL_WHITE );
+
+ aFocus.bOn = TRUE;
+ aFocus.aPenColor = aPenColor;
+ aFocus.aRect = rRect;
+}
+
+void SvxIconChoiceCtrl_Impl::HideFocus ()
+{
+ aFocus.bOn = FALSE;
+}
+
+void SvxIconChoiceCtrl_Impl::DrawFocusRect ( OutputDevice* pOut )
+{
+ pOut->SetLineColor( aFocus.aPenColor );
+ pOut->SetFillColor();
+ Polygon aPolygon ( aFocus.aRect );
+
+ LineInfo aLineInfo ( LINE_DASH );
+
+ aLineInfo.SetDashLen ( 1 );
+
+ aLineInfo.SetDotLen ( 1L );
+ aLineInfo.SetDistance ( 1L );
+ aLineInfo.SetDotCount ( 1 );
+
+ pOut->DrawPolyLine ( aPolygon, aLineInfo );
+}
+
+sal_Bool SvxIconChoiceCtrl_Impl::IsMnemonicChar( sal_Unicode cChar, ULONG& rPos ) const
+{
+ sal_Bool bRet = sal_False;
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+ ULONG nEntryCount = GetEntryCount();
+ for ( ULONG i = 0; i < nEntryCount; ++i )
+ {
+ if ( rI18nHelper.MatchMnemonic( GetEntry( i )->GetText(), cChar ) )
+ {
+ bRet = sal_True;
+ rPos = i;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+//
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+IMPL_LINK(SvxIconChoiceCtrl_Impl, UserEventHdl, void*, nId )
+{
+ if( nId == EVENTID_ADJUST_SCROLLBARS )
+ {
+ nUserEventAdjustScrBars = 0;
+ AdjustScrollBars();
+ }
+ else if( nId == EVENTID_SHOW_CURSOR )
+ {
+ nUserEventShowCursor = 0;
+ ShowCursor( TRUE );
+ }
+ return 0;
+}
+
+void SvxIconChoiceCtrl_Impl::CancelUserEvents()
+{
+ if( nUserEventAdjustScrBars )
+ {
+ Application::RemoveUserEvent( nUserEventAdjustScrBars );
+ nUserEventAdjustScrBars = 0;
+ }
+ if( nUserEventShowCursor )
+ {
+ Application::RemoveUserEvent( nUserEventShowCursor );
+ nUserEventShowCursor = 0;
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::InvalidateEntry( SvxIconChoiceCtrlEntry* pEntry )
+{
+ if( pEntry == pCursor )
+ ShowCursor( FALSE );
+ pView->Invalidate( pEntry->aRect );
+ Center( pEntry );
+ pView->Invalidate( pEntry->aRect );
+ if( pEntry == pCursor )
+ ShowCursor( TRUE );
+}
+
+void SvxIconChoiceCtrl_Impl::EditEntry( SvxIconChoiceCtrlEntry* pEntry )
+{
+ DBG_ASSERT(pEntry,"EditEntry: Entry not set");
+ if( !pEntry )
+ return;
+
+ StopEntryEditing( TRUE );
+ DELETEZ(pEdit);
+ SetNoSelection();
+
+ pCurEditedEntry = pEntry;
+ String aEntryText( pView->GetEntryText( pEntry, TRUE ) );
+ Rectangle aRect( CalcTextRect( pEntry, 0, TRUE, &aEntryText ) );
+ MakeVisible( aRect );
+ Point aPos( aRect.TopLeft() );
+ aPos = pView->GetPixelPos( aPos );
+ aRect.SetPos( aPos );
+ pView->HideFocus();
+ pEdit = new IcnViewEdit_Impl(
+ pView,
+ aRect.TopLeft(),
+ aRect.GetSize(),
+ aEntryText,
+ LINK( this, SvxIconChoiceCtrl_Impl, TextEditEndedHdl ) );
+}
+
+IMPL_LINK( SvxIconChoiceCtrl_Impl, TextEditEndedHdl, IcnViewEdit_Impl*, EMPTYARG )
+{
+ DBG_ASSERT(pEdit,"TextEditEnded: pEdit not set");
+ if( !pEdit )
+ {
+ pCurEditedEntry = 0;
+ return 0;
+ }
+ DBG_ASSERT(pCurEditedEntry,"TextEditEnded: pCurEditedEntry not set");
+
+ if( !pCurEditedEntry )
+ {
+ pEdit->Hide();
+ if( pEdit->IsGrabFocus() )
+ pView->GrabFocus();
+ return 0;
+ }
+
+ String aText;
+ if ( !pEdit->EditingCanceled() )
+ aText = pEdit->GetText();
+ else
+ aText = pEdit->GetSavedValue();
+
+ if( pView->EditedEntry( pCurEditedEntry, aText, pEdit->EditingCanceled() ) )
+ InvalidateEntry( pCurEditedEntry );
+ if( !GetSelectionCount() )
+ SelectEntry( pCurEditedEntry, TRUE );
+
+ pEdit->Hide();
+ if( pEdit->IsGrabFocus() )
+ pView->GrabFocus();
+ // Das Edit kann nicht hier geloescht werden, weil es noch in einem
+ // Handler steht. Es wird im Dtor oder im naechsten EditEntry geloescht.
+ pCurEditedEntry = 0;
+ return 0;
+}
+
+void SvxIconChoiceCtrl_Impl::StopEntryEditing( BOOL bCancel )
+{
+ if( pEdit )
+ pEdit->StopEditing( bCancel );
+}
+
+void SvxIconChoiceCtrl_Impl::LockEntryPos( SvxIconChoiceCtrlEntry* pEntry, BOOL bLock )
+{
+ if( bLock )
+ pEntry->SetFlags( ICNVIEW_FLAG_POS_LOCKED );
+ else
+ pEntry->ClearFlags( ICNVIEW_FLAG_POS_LOCKED );
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry( ULONG& rPos ) const
+{
+ if( !GetSelectionCount() )
+ return 0;
+
+ if( (nWinBits & WB_HIGHLIGHTFRAME) && (eSelectionMode == NO_SELECTION) )
+ {
+ rPos = pView->GetEntryListPos( pCurHighlightFrame );
+ return pCurHighlightFrame;
+ }
+
+ ULONG nCount = aEntries.Count();
+ if( !pHead )
+ {
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ if( pEntry->IsSelected() )
+ {
+ rPos = nCur;
+ return pEntry;
+ }
+ }
+ }
+ else
+ {
+ SvxIconChoiceCtrlEntry* pEntry = pHead;
+ while( nCount-- )
+ {
+ if( pEntry->IsSelected() )
+ {
+ rPos = GetEntryListPos( pEntry );
+ return pEntry;
+ }
+ pEntry = pEntry->pflink;
+ if( nCount && pEntry == pHead )
+ {
+ DBG_ERROR("SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry > Endlosschleife!");
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+// kein Round Robin!
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetNextSelectedEntry( ULONG& rStartPos ) const
+{
+ ULONG nCount = aEntries.Count();
+ if( rStartPos > nCount || !GetSelectionCount() )
+ return 0;
+ if( !pHead )
+ {
+ for( ULONG nCur = rStartPos+1; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ if( pEntry->IsSelected() )
+ {
+ rStartPos = nCur;
+ return pEntry;
+ }
+ }
+ }
+ else
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( rStartPos );
+ pEntry = pEntry->pflink;
+ while( pEntry != pHead )
+ {
+ if( pEntry->IsSelected() )
+ {
+ rStartPos = GetEntryListPos( pEntry );
+ return pEntry;
+ }
+ pEntry = pEntry->pflink;
+ }
+ }
+
+ rStartPos = 0xffffffff;
+ return 0;
+}
+
+void SvxIconChoiceCtrl_Impl::SelectAll( BOOL bSelect, BOOL bPaint )
+{
+ bPaint = TRUE;
+
+ ULONG nCount = aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount && (bSelect || GetSelectionCount() ); nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ SelectEntry( pEntry, bSelect, TRUE, TRUE, bPaint );
+ }
+ nFlags &= (~F_ADD_MODE);
+ pAnchor = 0;
+}
+
+void SvxIconChoiceCtrl_Impl::SaveSelection( List** ppList )
+{
+ if( !*ppList )
+ *ppList = new List;
+ ULONG nPos;
+ SvxIconChoiceCtrlEntry* pEntry = GetFirstSelectedEntry( nPos );
+ while( pEntry && GetSelectionCount() != (*ppList)->Count() )
+ {
+ (*ppList)->Insert( pEntry, LIST_APPEND );
+ pEntry = GetNextSelectedEntry( nPos );
+ }
+}
+
+IcnViewEdit_Impl::IcnViewEdit_Impl( SvtIconChoiceCtrl* pParent, const Point& rPos,
+ const Size& rSize, const XubString& rData, const Link& rNotifyEditEnd ) :
+ MultiLineEdit( pParent, (pParent->GetStyle() & WB_ICON) ? WB_CENTER : WB_LEFT),
+ aCallBackHdl( rNotifyEditEnd ),
+ bCanceled( FALSE ),
+ bAlreadyInCallback( FALSE ),
+ bGrabFocus( FALSE )
+{
+ Font aFont( pParent->GetPointFont() );
+ aFont.SetTransparent( FALSE );
+ SetControlFont( aFont );
+ if( !pParent->HasFontFillColor() )
+ {
+ Color aColor( pParent->GetBackground().GetColor() );
+ SetControlBackground( aColor );
+ }
+ else
+ SetControlBackground( aFont.GetFillColor() );
+ SetControlForeground( aFont.GetColor() );
+ SetPosPixel( rPos );
+ SetSizePixel( CalcAdjustedSize(rSize) );
+ SetText( rData );
+ SaveValue();
+
+ aAccReturn.InsertItem( IMPICNVIEW_ACC_RETURN, KeyCode(KEY_RETURN) );
+ aAccEscape.InsertItem( IMPICNVIEW_ACC_ESCAPE, KeyCode(KEY_ESCAPE) );
+
+ aAccReturn.SetActivateHdl( LINK( this, IcnViewEdit_Impl, ReturnHdl_Impl) );
+ aAccEscape.SetActivateHdl( LINK( this, IcnViewEdit_Impl, EscapeHdl_Impl) );
+ GetpApp()->InsertAccel( &aAccReturn);//, ACCEL_ALWAYS );
+ GetpApp()->InsertAccel( &aAccEscape);//, ACCEL_ALWAYS );
+ Show();
+ GrabFocus();
+}
+
+IcnViewEdit_Impl::~IcnViewEdit_Impl()
+{
+ if( !bAlreadyInCallback )
+ {
+ GetpApp()->RemoveAccel( &aAccReturn );
+ GetpApp()->RemoveAccel( &aAccEscape );
+ }
+}
+
+void IcnViewEdit_Impl::CallCallBackHdl_Impl()
+{
+ aTimer.Stop();
+ if ( !bAlreadyInCallback )
+ {
+ bAlreadyInCallback = TRUE;
+ GetpApp()->RemoveAccel( &aAccReturn );
+ GetpApp()->RemoveAccel( &aAccEscape );
+ Hide();
+ aCallBackHdl.Call( this );
+ }
+}
+
+IMPL_LINK( IcnViewEdit_Impl, Timeout_Impl, Timer*, EMPTYARG )
+{
+ CallCallBackHdl_Impl();
+ return 0;
+}
+
+IMPL_LINK( IcnViewEdit_Impl, ReturnHdl_Impl, Accelerator*, EMPTYARG )
+{
+ bCanceled = FALSE;
+ bGrabFocus = TRUE;
+ CallCallBackHdl_Impl();
+ return 1;
+}
+
+IMPL_LINK( IcnViewEdit_Impl, EscapeHdl_Impl, Accelerator*, EMPTYARG )
+{
+ bCanceled = TRUE;
+ bGrabFocus = TRUE;
+ CallCallBackHdl_Impl();
+ return 1;
+}
+
+void IcnViewEdit_Impl::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aCode = rKEvt.GetKeyCode();
+ USHORT nCode = aCode.GetCode();
+
+ switch ( nCode )
+ {
+ case KEY_ESCAPE:
+ bCanceled = TRUE;
+ bGrabFocus = TRUE;
+ CallCallBackHdl_Impl();
+ break;
+
+ case KEY_RETURN:
+ bCanceled = FALSE;
+ bGrabFocus = TRUE;
+ CallCallBackHdl_Impl();
+ break;
+
+ default:
+ MultiLineEdit::KeyInput( rKEvt );
+ }
+}
+
+long IcnViewEdit_Impl::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( !bAlreadyInCallback &&
+ ((!Application::GetFocusWindow()) || !IsChild(Application::GetFocusWindow())))
+ {
+ bCanceled = FALSE;
+ aTimer.SetTimeout(10);
+ aTimer.SetTimeoutHdl(LINK(this,IcnViewEdit_Impl,Timeout_Impl));
+ aTimer.Start();
+ }
+ }
+ return 0;
+}
+
+void IcnViewEdit_Impl::StopEditing( BOOL bCancel )
+{
+ if ( !bAlreadyInCallback )
+ {
+ bCanceled = bCancel;
+ CallCallBackHdl_Impl();
+ }
+}
+
+ULONG SvxIconChoiceCtrl_Impl::GetEntryListPos( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ if( !(nFlags & F_ENTRYLISTPOS_VALID ))
+ ((SvxIconChoiceCtrl_Impl*)this)->SetListPositions();
+ return pEntry->nPos;
+}
+
+void SvxIconChoiceCtrl_Impl::SetEntryListPos( SvxIconChoiceCtrlEntry* pListEntry, ULONG nNewPos )
+{
+ ULONG nCurPos = GetEntryListPos( pListEntry );
+ if( nCurPos == nNewPos )
+ return;
+ aEntries.List::Remove( nCurPos );
+ aEntries.List::Insert( (void*)pListEntry, nNewPos );
+ // Eintragspositionen anpassen
+ ULONG nStart, nEnd;
+ if( nNewPos < nCurPos )
+ {
+ nStart = nNewPos;
+ nEnd = nCurPos;
+ }
+ else
+ {
+ nStart = nCurPos;
+ nEnd = nNewPos;
+ }
+ for( ; nStart <= nEnd; nStart++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nStart );
+ pEntry->nPos = nStart;
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::SetEntryFlags( SvxIconChoiceCtrlEntry* pEntry, USHORT nEntryFlags )
+{
+ pEntry->nFlags = nEntryFlags;
+ if( nEntryFlags & ICNVIEW_FLAG_POS_MOVED )
+ nFlags |= F_MOVED_ENTRIES;
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GoLeftRight( SvxIconChoiceCtrlEntry* pStart, BOOL bRight )
+{
+ return pImpCursor->GoLeftRight( pStart, bRight );
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GoUpDown( SvxIconChoiceCtrlEntry* pStart, BOOL bDown )
+{
+ return pImpCursor->GoUpDown( pStart, bDown );
+}
+
+void SvxIconChoiceCtrl_Impl::InitSettings()
+{
+ const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings();
+
+ if( !pView->HasFont() )
+ {
+ // Unit aus den Settings ist Point
+ Font aFont( rStyleSettings.GetFieldFont() );
+ //const Font& rFont = pView->GetFont();
+ //if( pView->HasFontTextColor() )
+ aFont.SetColor( rStyleSettings.GetWindowTextColor() );
+ //if( pView->HasFontFillColor() )
+ //aFont.SetFillColor( rFont.GetFillColor() );
+ pView->SetPointFont( aFont );
+ SetDefaultTextSize();
+ }
+
+ //if( !pView->HasFontTextColor() )
+ pView->SetTextColor( rStyleSettings.GetFieldTextColor() );
+ //if( !pView->HasFontFillColor() )
+ pView->SetTextFillColor();
+
+ //if( !pView->HasBackground() )
+ pView->SetBackground( rStyleSettings.GetFieldColor());
+
+ long nScrBarSize = rStyleSettings.GetScrollBarSize();
+ if( nScrBarSize != nHorSBarHeight || nScrBarSize != nVerSBarWidth )
+ {
+ nHorSBarHeight = nScrBarSize;
+ Size aSize( aHorSBar.GetSizePixel() );
+ aSize.Height() = nScrBarSize;
+ aHorSBar.Hide();
+ aHorSBar.SetSizePixel( aSize );
+
+ nVerSBarWidth = nScrBarSize;
+ aSize = aVerSBar.GetSizePixel();
+ aSize.Width() = nScrBarSize;
+ aVerSBar.Hide();
+ aVerSBar.SetSizePixel( aSize );
+
+ Size aOSize( pView->Control::GetOutputSizePixel() );
+ PositionScrollBars( aOSize.Width(), aOSize.Height() );
+ AdjustScrollBars();
+ }
+}
+
+EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl* pOwner, USHORT _nInitSize , USHORT _nReSize ) :
+ List( _nInitSize, _nReSize ),
+ _pOwner( pOwner )
+{
+ _pOwner->pHead = 0;
+}
+
+EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl* pOwner, USHORT _nBlockSize, USHORT _nInitSize, USHORT _nReSize ) :
+ List( _nBlockSize, _nInitSize, _nReSize ),
+ _pOwner( pOwner )
+{
+ _pOwner->pHead = 0;
+}
+
+EntryList_Impl::~EntryList_Impl()
+{
+ _pOwner->pHead = 0;
+}
+
+void EntryList_Impl::Clear()
+{
+ _pOwner->pHead = 0;
+ List::Clear();
+}
+
+void EntryList_Impl::Insert( SvxIconChoiceCtrlEntry* pEntry, ULONG nPos )
+{
+ List::Insert( pEntry, nPos );
+ if( _pOwner->pHead )
+ pEntry->SetBacklink( _pOwner->pHead->pblink );
+}
+
+SvxIconChoiceCtrlEntry* EntryList_Impl::Remove( ULONG nPos )
+{
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)List::Remove( nPos );
+ DBG_ASSERT(pEntry,"EntryList_Impl::Remove > Entry not found");
+ Removed_Impl( pEntry );
+ return pEntry;
+}
+
+void EntryList_Impl::Remove( SvxIconChoiceCtrlEntry* pEntry )
+{
+ List::Remove( (void*)pEntry );
+ Removed_Impl( pEntry );
+}
+
+void EntryList_Impl::Removed_Impl( SvxIconChoiceCtrlEntry* pEntry )
+{
+ if( _pOwner->pHead )
+ {
+ if( _pOwner->pHead == pEntry )
+ {
+ if( _pOwner->pHead != pEntry->pflink )
+ _pOwner->pHead = pEntry->pflink;
+ else
+ {
+ DBG_ASSERT(!Count(),"EntryList_Impl::Remove > Invalid predecessor" );
+ _pOwner->pHead = 0;
+ }
+ }
+ pEntry->Unlink();
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::SetPositionMode( SvxIconChoiceCtrlPositionMode eMode )
+{
+ ULONG nCur;
+
+ if( eMode == ePositionMode )
+ return;
+
+ SvxIconChoiceCtrlPositionMode eOldMode = ePositionMode;
+ ePositionMode = eMode;
+ ULONG nCount = aEntries.Count();
+
+ if( eOldMode == IcnViewPositionModeAutoArrange )
+ {
+ // positionieren wir verschobene Eintraege 'hart' gibts noch Probleme
+ // mit ungewollten Ueberlappungen, da diese Eintrage im Arrange
+ // nicht beruecksichtigt werden.
+#if 1
+ if( aEntries.Count() )
+ aAutoArrangeTimer.Start();
+#else
+ if( pHead )
+ {
+ // verschobene Eintraege 'hart' auf ihre Position setzen
+ nCur = nCount;
+ SvxIconChoiceCtrlEntry* pEntry = pHead;
+ while( nCur )
+ {
+ SvxIconChoiceCtrlEntry* pPred;
+ if( GetEntryPredecessor( pEntry, &pPred ))
+ SetEntryFlags( pEntry, ICNVIEW_FLAG_POS_MOVED );
+ pEntry = pEntry->pflink;
+ nCur--;
+ }
+ ClearPredecessors();
+ }
+#endif
+ return;
+ }
+
+ if( ePositionMode == IcnViewPositionModeAutoArrange )
+ {
+ List aMovedEntries;
+ for( nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur );
+ if( pEntry->GetFlags() & (ICNVIEW_FLAG_POS_LOCKED | ICNVIEW_FLAG_POS_MOVED))
+ {
+ SvxIconChoiceCtrlEntry_Impl* pE = new SvxIconChoiceCtrlEntry_Impl(
+ pEntry, GetEntryBoundRect( pEntry ));
+ aMovedEntries.Insert( pE, LIST_APPEND );
+ }
+ }
+ nCount = aMovedEntries.Count();
+ for( nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry_Impl* pE = (SvxIconChoiceCtrlEntry_Impl*)aMovedEntries.GetObject(nCur);
+ SetEntryPos( pE->_pEntry, pE->_aPos );
+ }
+ for( nCur = 0; nCur < nCount; nCur++ )
+ delete (SvxIconChoiceCtrlEntry_Impl*)aMovedEntries.GetObject( nCur );
+ if( aEntries.Count() )
+ aAutoArrangeTimer.Start();
+ }
+ else if( ePositionMode == IcnViewPositionModeAutoAdjust )
+ {
+ AdjustEntryAtGrid( 0 );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::SetEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry,
+ SvxIconChoiceCtrlEntry* pPredecessor )
+{
+ if( !IsAutoArrange() )
+ return;
+
+ if( pEntry == pPredecessor )
+ return;
+
+ ULONG nPos1 = GetEntryListPos( pEntry );
+ if( !pHead )
+ {
+ if( pPredecessor )
+ {
+ ULONG nPos2 = GetEntryListPos( pPredecessor );
+ if( nPos1 == (nPos2 + 1) )
+ return; // ist schon Vorgaenger
+ }
+ else if( !nPos1 )
+ return;
+ }
+
+ if( !pHead )
+ InitPredecessors();
+
+ if( !pPredecessor && pHead == pEntry )
+ return; // ist schon der Erste
+
+ BOOL bSetHead = FALSE;
+ if( !pPredecessor )
+ {
+ bSetHead = TRUE;
+ pPredecessor = pHead->pblink;
+ }
+ if( pEntry == pHead )
+ {
+ pHead = pHead->pflink;
+ bSetHead = FALSE;
+ }
+ if( pEntry != pPredecessor )
+ {
+ pEntry->Unlink();
+ pEntry->SetBacklink( pPredecessor );
+ }
+ if( bSetHead )
+ pHead = pEntry;
+ pEntry->SetFlags( ICNVIEW_FLAG_PRED_SET );
+ aAutoArrangeTimer.Start();
+}
+
+BOOL SvxIconChoiceCtrl_Impl::GetEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry,
+ SvxIconChoiceCtrlEntry** ppPredecessor )
+{
+ *ppPredecessor = 0;
+ if( !pHead )
+ return FALSE;
+ DBG_ASSERT(pEntry->pblink,"GetEntryPredecessor: Backward link not set");
+ DBG_ASSERT(pEntry->pflink,"GetEntryPredecessor: Forward link not set");
+
+ if( pEntry == pHead )
+ {
+ SvxIconChoiceCtrlEntry* pFirst = (SvxIconChoiceCtrlEntry*)aEntries.GetObject(0);
+ if( pFirst != pEntry )
+ return TRUE;
+ return FALSE;
+ }
+ *ppPredecessor = pEntry->pblink;
+ if( !(pEntry->nFlags & ICNVIEW_FLAG_PRED_SET) &&
+ (GetEntryListPos( *ppPredecessor ) + 1) == GetEntryListPos( pEntry ))
+ return FALSE;
+ return TRUE;
+}
+
+SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::FindEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry,
+ const Point& rPosTopLeft )
+{
+ Point aPos( rPosTopLeft ); //TopLeft
+ Rectangle aCenterRect( CalcBmpRect( pEntry, &aPos ));
+ Point aNewPos( aCenterRect.Center() );
+ ULONG nGrid = GetPredecessorGrid( aNewPos );
+ ULONG nCount = aEntries.Count();
+ if( nGrid == ULONG_MAX )
+ return 0;
+ if( nGrid >= nCount )
+ nGrid = nCount - 1;
+ if( !pHead )
+ return (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nGrid );
+
+ SvxIconChoiceCtrlEntry* pCur = pHead; // Grid 0
+ // todo: Liste von hinten aufrollen wenn nGrid > nCount/2
+ for( ULONG nCur = 0; nCur < nGrid; nCur++ )
+ pCur = pCur->pflink;
+
+ return pCur;
+}
+
+ULONG SvxIconChoiceCtrl_Impl::GetPredecessorGrid( const Point& rPos) const
+{
+ Point aPos( rPos );
+ aPos.X() -= LROFFS_WINBORDER;
+ aPos.Y() -= TBOFFS_WINBORDER;
+ USHORT nMaxCol = (USHORT)(aVirtOutputSize.Width() / nGridDX);
+ if( nMaxCol )
+ nMaxCol--;
+ USHORT nGridX = (USHORT)(aPos.X() / nGridDX);
+ if( nGridX > nMaxCol )
+ nGridX = nMaxCol;
+ USHORT nGridY = (USHORT)(aPos.Y() / nGridDY);
+ USHORT nGridsX = (USHORT)(aOutputSize.Width() / nGridDX);
+ ULONG nGrid = (nGridY * nGridsX) + nGridX;
+ long nMiddle = (nGridX * nGridDX) + (nGridDX / 2);
+ if( rPos.X() < nMiddle )
+ {
+ if( !nGrid )
+ nGrid = ULONG_MAX;
+ else
+ nGrid--;
+ }
+ return nGrid;
+}
+
+void SvxIconChoiceCtrl_Impl::Flush()
+{
+ if( aAutoArrangeTimer.IsActive() )
+ {
+ AutoArrangeHdl( 0 );
+ }
+}
+
+BOOL SvxIconChoiceCtrl_Impl::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( !(rHEvt.GetMode() & HELPMODE_QUICK ) )
+ return FALSE;
+
+ Point aPos( pView->ScreenToOutputPixel(rHEvt.GetMousePosPixel() ) );
+ aPos -= pView->GetMapMode().GetOrigin();
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry( aPos, TRUE );
+
+ if ( !pEntry )
+ return FALSE;
+
+ String sQuickHelpText = pEntry->GetQuickHelpText();
+ String aEntryText( pView->GetEntryText( pEntry, FALSE ) );
+ Rectangle aTextRect( CalcTextRect( pEntry, 0, FALSE, &aEntryText ) );
+ if ( ( !aTextRect.IsInside( aPos ) || !aEntryText.Len() ) && !sQuickHelpText.Len() )
+ return FALSE;
+
+ Rectangle aOptTextRect( aTextRect );
+ aOptTextRect.Bottom() = LONG_MAX;
+ USHORT nNewFlags = nCurTextDrawFlags;
+ nNewFlags &= ~( TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS );
+ aOptTextRect = pView->GetTextRect( aOptTextRect, aEntryText, nNewFlags );
+ if ( aOptTextRect != aTextRect || sQuickHelpText.Len() > 0 )
+ {
+ //aTextRect.Right() = aTextRect.Left() + aRealSize.Width() + 4;
+ Point aPt( aOptTextRect.TopLeft() );
+ aPt += pView->GetMapMode().GetOrigin();
+ aPt = pView->OutputToScreenPixel( aPt );
+ // Border der Tiphilfe abziehen
+ aPt.Y() -= 1;
+ aPt.X() -= 3;
+ aOptTextRect.SetPos( aPt );
+ String sHelpText;
+ if ( sQuickHelpText.Len() > 0 )
+ sHelpText = sQuickHelpText;
+ else
+ sHelpText = aEntryText;
+ Help::ShowQuickHelp( (Window*)pView, aOptTextRect, sHelpText, QUICKHELP_LEFT | QUICKHELP_VCENTER );
+ }
+
+ return TRUE;
+}
+
+void SvxIconChoiceCtrl_Impl::ClearColumnList()
+{
+ if( !pColumns )
+ return;
+
+ const USHORT nCount = pColumns->Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlColumnInfo* pInfo = (SvxIconChoiceCtrlColumnInfo*)
+ pColumns->GetObject( nCur );
+ delete pInfo;
+ }
+ DELETEZ(pColumns);
+}
+
+void SvxIconChoiceCtrl_Impl::SetColumn( USHORT nIndex, const SvxIconChoiceCtrlColumnInfo& rInfo)
+{
+ if( !pColumns )
+ pColumns = new SvPtrarr;
+ while( pColumns->Count() < nIndex + 1 )
+ pColumns->Insert( (void*)0, pColumns->Count() );
+
+ SvxIconChoiceCtrlColumnInfo* pInfo =
+ (SvxIconChoiceCtrlColumnInfo*)pColumns->GetObject(nIndex);
+ if( !pInfo )
+ {
+ pInfo = new SvxIconChoiceCtrlColumnInfo( rInfo );
+ pColumns->Insert( (void*)pInfo, nIndex );
+ }
+ else
+ {
+ delete pInfo;
+ pInfo = new SvxIconChoiceCtrlColumnInfo( rInfo );
+ pColumns->Replace( pInfo, nIndex );
+ }
+
+ // HACK(Detail-Modus ist noch nicht vollstaendig implementiert!)
+ // dieses Workaround bringts mit einer Spalte zum Fliegen
+ if( !nIndex && (nWinBits & WB_DETAILS) )
+ nGridDX = pInfo->GetWidth();
+
+ if( GetUpdateMode() )
+ Arrange( IsAutoArrange() );
+}
+
+const SvxIconChoiceCtrlColumnInfo* SvxIconChoiceCtrl_Impl::GetColumn( USHORT nIndex ) const
+{
+ if( !pColumns || nIndex >= pColumns->Count() )
+ return 0;
+ return (const SvxIconChoiceCtrlColumnInfo*)pColumns->GetObject( nIndex );
+}
+
+const SvxIconChoiceCtrlColumnInfo* SvxIconChoiceCtrl_Impl::GetItemColumn( USHORT nSubItem,
+ long& rLeft ) const
+{
+ rLeft = 0;
+ if( !pColumns )
+ return 0;
+ const USHORT nCount = pColumns->Count();
+ const SvxIconChoiceCtrlColumnInfo* pCol = 0;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ pCol = (const SvxIconChoiceCtrlColumnInfo*)pColumns->GetObject( nCur );
+ if( !pCol || pCol->GetSubItem() == nSubItem )
+ return pCol;
+ rLeft += pCol->GetWidth();
+ }
+ return pCol;
+}
+
+void SvxIconChoiceCtrl_Impl::DrawHighlightFrame(
+ OutputDevice* pOut, const Rectangle& rBmpRect, BOOL bHide )
+{
+ Rectangle aBmpRect( rBmpRect );
+ long nBorder = 2;
+ if( aImageSize.Width() < 32 )
+ nBorder = 1;
+ aBmpRect.Right() += nBorder;
+ aBmpRect.Left() -= nBorder;
+ aBmpRect.Bottom() += nBorder;
+ aBmpRect.Top() -= nBorder;
+
+ if ( bHide )
+ pView->Invalidate( aBmpRect );
+ else
+ {
+ DecorationView aDecoView( pOut );
+ USHORT nDecoFlags;
+ if ( bHighlightFramePressed )
+ nDecoFlags = FRAME_HIGHLIGHT_TESTBACKGROUND | FRAME_HIGHLIGHT_IN;
+ else
+ nDecoFlags = FRAME_HIGHLIGHT_TESTBACKGROUND | FRAME_HIGHLIGHT_OUT;
+ aDecoView.DrawHighlightFrame( aBmpRect, nDecoFlags );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::SetEntryHighlightFrame( SvxIconChoiceCtrlEntry* pEntry,
+ BOOL bKeepHighlightFlags )
+{
+ if( pEntry == pCurHighlightFrame )
+ return;
+
+ if( !bKeepHighlightFlags )
+ bHighlightFramePressed = FALSE;
+
+ HideEntryHighlightFrame();
+ pCurHighlightFrame = pEntry;
+ if( pEntry )
+ {
+ Rectangle aBmpRect( CalcFocusRect(pEntry) );
+ DrawHighlightFrame( pView, aBmpRect, FALSE );
+ }
+}
+
+void SvxIconChoiceCtrl_Impl::HideEntryHighlightFrame()
+{
+ if( !pCurHighlightFrame )
+ return;
+
+ SvxIconChoiceCtrlEntry* pEntry = pCurHighlightFrame;
+ pCurHighlightFrame = 0;
+ Rectangle aBmpRect( CalcFocusRect(pEntry) );
+ DrawHighlightFrame( pView, aBmpRect, TRUE );
+}
+
+void SvxIconChoiceCtrl_Impl::CallSelectHandler( SvxIconChoiceCtrlEntry* )
+{
+ // Bei aktiviertem Single-Click-Modus sollte der Selektionshandler
+ // synchron gerufen werden, weil die Selektion automatisch
+ // weggenommen wird, wenn der Mauszeiger nicht mehr das Objekt
+ // beruehrt. Es kann sonst zu fehlenden Select-Aufrufen kommen,
+ // wenn das Objekt aus einer Mausbewegung heraus selektiert wird,
+ // weil beim Ausloesen des Timers der Mauszeiger das Objekt u.U.
+ // schon verlassen hat.
+ // Fuer spezielle Faelle (=>SfxFileDialog!) koennen synchrone
+ // Aufrufe auch per WB_NOASYNCSELECTHDL erzwungen werden.
+ if( nWinBits & (WB_NOASYNCSELECTHDL | WB_HIGHLIGHTFRAME) )
+ {
+ pHdlEntry = 0;
+ pView->ClickIcon();
+ //pView->Select();
+ }
+ else
+ aCallSelectHdlTimer.Start();
+}
+
+IMPL_LINK( SvxIconChoiceCtrl_Impl, CallSelectHdlHdl, void*, EMPTYARG )
+{
+ pHdlEntry = 0;
+ pView->ClickIcon();
+ //pView->Select();
+ return 0;
+}
+
+Point SvxIconChoiceCtrl_Impl::GetPopupMenuPosPixel() const
+{
+ Point aResult;
+ if( !GetSelectionCount() )
+ return aResult;
+
+ SvxIconChoiceCtrlEntry* pEntry = GetCurEntry();
+ if( !pEntry || !pEntry->IsSelected() )
+ {
+ ULONG nNext;
+ pEntry = GetFirstSelectedEntry( nNext );
+ }
+ if( pEntry )
+ {
+ Rectangle aRect( ((SvxIconChoiceCtrl_Impl*)this)->CalcBmpRect( pEntry ) );
+ aResult = aRect.Center();
+ aResult = pView->GetPixelPos( aResult );
+ }
+ return aResult;
+}
+
+void SvxIconChoiceCtrl_Impl::SetOrigin( const Point& rPos, BOOL bDoNotUpdateWallpaper )
+{
+ MapMode aMapMode( pView->GetMapMode() );
+ aMapMode.SetOrigin( rPos );
+ pView->SetMapMode( aMapMode );
+ if( !bDoNotUpdateWallpaper )
+ {
+ BOOL bScrollable = pView->GetBackground().IsScrollable();
+ if( pView->HasBackground() && !bScrollable )
+ {
+ Rectangle aRect( GetOutputRect());
+ Wallpaper aPaper( pView->GetBackground() );
+ aPaper.SetRect( aRect );
+ pView->SetBackground( aPaper );
+ }
+ }
+}
+
+ULONG SvxIconChoiceCtrl_Impl::GetGridCount( const Size& rSize, BOOL bCheckScrBars,
+ BOOL bSmartScrBar ) const
+{
+ Size aSize( rSize );
+ if( bCheckScrBars && aHorSBar.IsVisible() )
+ aSize.Height() -= nHorSBarHeight;
+ else if( bSmartScrBar && (nWinBits & WB_ALIGN_LEFT) )
+ aSize.Height() -= nHorSBarHeight;
+
+ if( bCheckScrBars && aVerSBar.IsVisible() )
+ aSize.Width() -= nVerSBarWidth;
+ else if( bSmartScrBar && (nWinBits & WB_ALIGN_TOP) )
+ aSize.Width() -= nVerSBarWidth;
+
+ if( aSize.Width() < 0 )
+ aSize.Width() = 0;
+ if( aSize.Height() < 0 )
+ aSize.Height() = 0;
+
+ return IcnGridMap_Impl::GetGridCount( aSize, (USHORT)nGridDX, (USHORT)nGridDY );
+}
+
+BOOL SvxIconChoiceCtrl_Impl::HandleShortCutKey( const KeyEvent& rKEvt )
+{
+ StopEditTimer();
+
+ BOOL bRet = FALSE;
+
+ DBG_ASSERT( rKEvt.GetKeyCode().IsMod2(), "*SvxIconChoiceCtrl_Impl::HandleShortCutKey(): no <ALT> pressed!?" );
+
+ sal_Unicode cChar = rKEvt.GetCharCode();
+ ULONG nPos = (ULONG)-1;
+
+ if( cChar && IsMnemonicChar( cChar, nPos ) )
+ {
+ // shortcut is clicked
+ SvxIconChoiceCtrlEntry* pNewCursor = GetEntry( nPos );
+ SvxIconChoiceCtrlEntry* pOldCursor = pCursor;
+ if( pNewCursor != pOldCursor )
+ {
+ SetCursor_Impl( pOldCursor, pNewCursor, FALSE, FALSE, FALSE );
+
+ if( pNewCursor != NULL )
+ {
+ pHdlEntry = pNewCursor;
+ pCurHighlightFrame = pHdlEntry;
+ pView->ClickIcon();
+ pCurHighlightFrame = NULL;
+ }
+ }
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxIconChoiceCtrl_Impl::CallEventListeners( ULONG nEvent, void* pData )
+{
+ pView->CallImplEventListeners( nEvent, pData );
+}
+
+
diff --git a/svtools/source/contnr/imivctl2.cxx b/svtools/source/contnr/imivctl2.cxx
new file mode 100644
index 000000000000..7cb92e8cef07
--- /dev/null
+++ b/svtools/source/contnr/imivctl2.cxx
@@ -0,0 +1,848 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "imivctl.hxx"
+
+IcnCursor_Impl::IcnCursor_Impl( SvxIconChoiceCtrl_Impl* pOwner )
+{
+ pView = pOwner;
+ pColumns = 0;
+ pRows = 0;
+ pCurEntry = 0;
+ nDeltaWidth = 0;
+ nDeltaHeight= 0;
+ nCols = 0;
+ nRows = 0;
+}
+
+IcnCursor_Impl::~IcnCursor_Impl()
+{
+ delete[] pColumns;
+ delete[] pRows;
+}
+
+USHORT IcnCursor_Impl::GetSortListPos( SvPtrarr* pList, long nValue,
+ int bVertical )
+{
+ USHORT nCount = (USHORT)pList->Count();
+ if( !nCount )
+ return 0;
+
+ USHORT nCurPos = 0;
+ long nPrevValue = LONG_MIN;
+ while( nCount )
+ {
+ const Rectangle& rRect=
+ pView->GetEntryBoundRect((SvxIconChoiceCtrlEntry*)(pList->GetObject(nCurPos)));
+ long nCurValue;
+ if( bVertical )
+ nCurValue = rRect.Top();
+ else
+ nCurValue = rRect.Left();
+ if( nValue >= nPrevValue && nValue <= nCurValue )
+ return (USHORT)nCurPos;
+ nPrevValue = nCurValue;
+ nCount--;
+ nCurPos++;
+ }
+ return pList->Count();
+}
+
+void IcnCursor_Impl::ImplCreate()
+{
+ pView->CheckBoundingRects();
+ DBG_ASSERT(pColumns==0&&pRows==0,"ImplCreate: Not cleared");
+
+ SetDeltas();
+
+ pColumns = new SvPtrarr[ nCols ];
+ pRows = new SvPtrarr[ nRows ];
+
+ ULONG nCount = pView->aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pView->aEntries.GetObject( nCur );
+ // const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ Rectangle rRect( pView->CalcBmpRect( pEntry,0 ) );
+ short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / nDeltaHeight );
+ short nX = (short)( ((rRect.Left()+rRect.Right())/2) / nDeltaWidth );
+
+ // Rundungsfehler abfangen
+ if( nY >= nRows )
+ nY = sal::static_int_cast< short >(nRows - 1);
+ if( nX >= nCols )
+ nX = sal::static_int_cast< short >(nCols - 1);
+
+ USHORT nIns = GetSortListPos( &pColumns[nX], rRect.Top(), TRUE );
+ pColumns[ nX ].Insert( pEntry, nIns );
+
+ nIns = GetSortListPos( &pRows[nY], rRect.Left(), FALSE );
+ pRows[ nY ].Insert( pEntry, nIns );
+
+ pEntry->nX = nX;
+ pEntry->nY = nY;
+ }
+}
+
+
+
+
+void IcnCursor_Impl::Clear()
+{
+ if( pColumns )
+ {
+ delete[] pColumns;
+ delete[] pRows;
+ pColumns = 0;
+ pRows = 0;
+ pCurEntry = 0;
+ nDeltaWidth = 0;
+ nDeltaHeight = 0;
+ }
+}
+
+SvxIconChoiceCtrlEntry* IcnCursor_Impl::SearchCol(USHORT nCol,USHORT nTop,USHORT nBottom,
+ USHORT, BOOL bDown, BOOL bSimple )
+{
+ DBG_ASSERT(pCurEntry,"SearchCol: No reference entry");
+ SvPtrarr* pList = &(pColumns[ nCol ]);
+ const USHORT nCount = pList->Count();
+ if( !nCount )
+ return 0;
+
+ const Rectangle& rRefRect = pView->GetEntryBoundRect(pCurEntry);
+
+ if( bSimple )
+ {
+ USHORT nListPos = pList->GetPos( pCurEntry );
+ DBG_ASSERT(nListPos!=0xffff,"Entry not in Col-List");
+ if( bDown )
+ {
+ while( nListPos < nCount-1 )
+ {
+ nListPos++;
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ if( rRect.Top() > rRefRect.Top() )
+ return pEntry;
+ }
+ return 0;
+ }
+ else
+ {
+ while( nListPos )
+ {
+ nListPos--;
+ if( nListPos < nCount )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ if( rRect.Top() < rRefRect.Top() )
+ return pEntry;
+ }
+ }
+ return 0;
+ }
+ }
+
+ if( nTop > nBottom )
+ {
+ USHORT nTemp = nTop;
+ nTop = nBottom;
+ nBottom = nTemp;
+ }
+ long nMinDistance = LONG_MAX;
+ SvxIconChoiceCtrlEntry* pResult = 0;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pList->GetObject( nCur ));
+ if( pEntry != pCurEntry )
+ {
+ USHORT nY = pEntry->nY;
+ if( nY >= nTop && nY <= nBottom )
+ {
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ long nDistance = rRect.Top() - rRefRect.Top();
+ if( nDistance < 0 )
+ nDistance *= -1;
+ if( nDistance && nDistance < nMinDistance )
+ {
+ nMinDistance = nDistance;
+ pResult = pEntry;
+ }
+ }
+ }
+ }
+ return pResult;
+}
+
+SvxIconChoiceCtrlEntry* IcnCursor_Impl::SearchRow(USHORT nRow,USHORT nLeft,USHORT nRight,
+ USHORT, BOOL bRight, BOOL bSimple )
+{
+ DBG_ASSERT(pCurEntry,"SearchRow: No reference entry");
+ SvPtrarr* pList = &(pRows[ nRow ]);
+ const USHORT nCount = pList->Count();
+ if( !nCount )
+ return 0;
+
+ const Rectangle& rRefRect = pView->GetEntryBoundRect(pCurEntry);
+
+ if( bSimple )
+ {
+ USHORT nListPos = pList->GetPos( pCurEntry );
+ DBG_ASSERT(nListPos!=0xffff,"Entry not in Row-List");
+ if( bRight )
+ {
+ while( nListPos < nCount-1 )
+ {
+ nListPos++;
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ if( rRect.Left() > rRefRect.Left() )
+ return pEntry;
+ }
+ return 0;
+ }
+ else
+ {
+ while( nListPos )
+ {
+ nListPos--;
+ if( nListPos < nCount )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ if( rRect.Left() < rRefRect.Left() )
+ return pEntry;
+ }
+ }
+ return 0;
+ }
+
+ }
+ if( nRight < nLeft )
+ {
+ USHORT nTemp = nRight;
+ nRight = nLeft;
+ nLeft = nTemp;
+ }
+ long nMinDistance = LONG_MAX;
+ SvxIconChoiceCtrlEntry* pResult = 0;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pList->GetObject( nCur ));
+ if( pEntry != pCurEntry )
+ {
+ USHORT nX = pEntry->nX;
+ if( nX >= nLeft && nX <= nRight )
+ {
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ long nDistance = rRect.Left() - rRefRect.Left();
+ if( nDistance < 0 )
+ nDistance *= -1;
+ if( nDistance && nDistance < nMinDistance )
+ {
+ nMinDistance = nDistance;
+ pResult = pEntry;
+ }
+ }
+ }
+ }
+ return pResult;
+}
+
+
+
+/*
+ Sucht ab dem uebergebenen Eintrag den naechsten rechts- bzw.
+ linksstehenden. Suchverfahren am Beispiel bRight = TRUE:
+
+ c
+ b c
+ a b c
+ S 1 1 1 ====> Suchrichtung
+ a b c
+ b c
+ c
+
+ S : Startposition
+ 1 : erstes Suchrechteck
+ a,b,c : 2., 3., 4. Suchrechteck
+*/
+
+SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoLeftRight( SvxIconChoiceCtrlEntry* pCtrlEntry, BOOL bRight )
+{
+ SvxIconChoiceCtrlEntry* pResult;
+ pCurEntry = pCtrlEntry;
+ Create();
+ USHORT nY = pCtrlEntry->nY;
+ USHORT nX = pCtrlEntry->nX;
+ DBG_ASSERT(nY< nRows,"GoLeftRight:Bad column");
+ DBG_ASSERT(nX< nCols,"GoLeftRight:Bad row");
+ // Nachbar auf gleicher Zeile ?
+ if( bRight )
+ pResult = SearchRow(
+ nY, nX, sal::static_int_cast< USHORT >(nCols-1), nX, TRUE, TRUE );
+ else
+ pResult = SearchRow( nY, nX ,0, nX, FALSE, TRUE );
+ if( pResult )
+ return pResult;
+
+ long nCurCol = nX;
+
+ long nColOffs, nLastCol;
+ if( bRight )
+ {
+ nColOffs = 1;
+ nLastCol = nCols;
+ }
+ else
+ {
+ nColOffs = -1;
+ nLastCol = -1; // 0-1
+ }
+
+ USHORT nRowMin = nY;
+ USHORT nRowMax = nY;
+ do
+ {
+ SvxIconChoiceCtrlEntry* pEntry = SearchCol((USHORT)nCurCol,nRowMin,nRowMax,nY,TRUE, FALSE);
+ if( pEntry )
+ return pEntry;
+ if( nRowMin )
+ nRowMin--;
+ if( nRowMax < (nRows-1))
+ nRowMax++;
+ nCurCol += nColOffs;
+ } while( nCurCol != nLastCol );
+ return 0;
+}
+
+SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoPageUpDown( SvxIconChoiceCtrlEntry* pStart, BOOL bDown)
+{
+ if( pView->IsAutoArrange() && !(pView->nWinBits & WB_ALIGN_TOP) )
+ {
+ const long nPos = (long)pView->GetEntryListPos( pStart );
+ long nEntriesInView = (pView->aOutputSize.Height() / pView->nGridDY);
+ nEntriesInView *=
+ ((pView->aOutputSize.Width()+(pView->nGridDX/2)) / pView->nGridDX );
+ long nNewPos = nPos;
+ if( bDown )
+ {
+ nNewPos += nEntriesInView;
+ if( nNewPos >= (long)pView->aEntries.Count() )
+ nNewPos = pView->aEntries.Count() - 1;
+ }
+ else
+ {
+ nNewPos -= nEntriesInView;
+ if( nNewPos < 0 )
+ nNewPos = 0;
+ }
+ if( nPos != nNewPos )
+ return (SvxIconChoiceCtrlEntry*)pView->aEntries.GetObject( (ULONG)nNewPos );
+ return 0;
+ }
+ long nOpt = pView->GetEntryBoundRect( pStart ).Top();
+ if( bDown )
+ {
+ nOpt += pView->aOutputSize.Height();
+ nOpt -= pView->nGridDY;
+ }
+ else
+ {
+ nOpt -= pView->aOutputSize.Height();
+ nOpt += pView->nGridDY;
+ }
+ if( nOpt < 0 )
+ nOpt = 0;
+
+ long nPrevErr = LONG_MAX;
+
+ SvxIconChoiceCtrlEntry* pPrev = pStart;
+ SvxIconChoiceCtrlEntry* pNext = GoUpDown( pStart, bDown );
+ while( pNext )
+ {
+ long nCur = pView->GetEntryBoundRect( pNext ).Top();
+ long nErr = nOpt - nCur;
+ if( nErr < 0 )
+ nErr *= -1;
+ if( nErr > nPrevErr )
+ return pPrev;
+ nPrevErr = nErr;
+ pPrev = pNext;
+ pNext = GoUpDown( pNext, bDown );
+ }
+ if( pPrev != pStart )
+ return pPrev;
+ return 0;
+}
+
+SvxIconChoiceCtrlEntry* IcnCursor_Impl::GoUpDown( SvxIconChoiceCtrlEntry* pCtrlEntry, BOOL bDown)
+{
+ if( pView->IsAutoArrange() && !(pView->nWinBits & WB_ALIGN_TOP) )
+ {
+ ULONG nPos = pView->GetEntryListPos( pCtrlEntry );
+ if( bDown && nPos < (pView->aEntries.Count() - 1) )
+ return (SvxIconChoiceCtrlEntry*)pView->aEntries.GetObject( nPos + 1 );
+ else if( !bDown && nPos > 0 )
+ return (SvxIconChoiceCtrlEntry*)pView->aEntries.GetObject( nPos - 1 );
+ return 0;
+ }
+
+ SvxIconChoiceCtrlEntry* pResult;
+ pCurEntry = pCtrlEntry;
+ Create();
+ USHORT nY = pCtrlEntry->nY;
+ USHORT nX = pCtrlEntry->nX;
+ DBG_ASSERT(nY<nRows,"GoUpDown:Bad column");
+ DBG_ASSERT(nX<nCols,"GoUpDown:Bad row");
+
+ // Nachbar in gleicher Spalte ?
+ if( bDown )
+ pResult = SearchCol(
+ nX, nY, sal::static_int_cast< USHORT >(nRows-1), nY, TRUE, TRUE );
+ else
+ pResult = SearchCol( nX, nY ,0, nY, FALSE, TRUE );
+ if( pResult )
+ return pResult;
+
+ long nCurRow = nY;
+
+ long nRowOffs, nLastRow;
+ if( bDown )
+ {
+ nRowOffs = 1;
+ nLastRow = nRows;
+ }
+ else
+ {
+ nRowOffs = -1;
+ nLastRow = -1; // 0-1
+ }
+
+ USHORT nColMin = nX;
+ USHORT nColMax = nX;
+ do
+ {
+ SvxIconChoiceCtrlEntry* pEntry = SearchRow((USHORT)nCurRow,nColMin,nColMax,nX,TRUE, FALSE);
+ if( pEntry )
+ return pEntry;
+ if( nColMin )
+ nColMin--;
+ if( nColMax < (nCols-1))
+ nColMax++;
+ nCurRow += nRowOffs;
+ } while( nCurRow != nLastRow );
+ return 0;
+}
+
+void IcnCursor_Impl::SetDeltas()
+{
+ const Size& rSize = pView->aVirtOutputSize;
+ nCols = rSize.Width() / pView->nGridDX;
+ if( !nCols )
+ nCols = 1;
+ nRows = rSize.Height() / pView->nGridDY;
+ if( (nRows * pView->nGridDY) < rSize.Height() )
+ nRows++;
+ if( !nRows )
+ nRows = 1;
+
+ nDeltaWidth = (short)(rSize.Width() / nCols);
+ nDeltaHeight = (short)(rSize.Height() / nRows);
+ if( !nDeltaHeight )
+ {
+ nDeltaHeight = 1;
+ DBG_WARNING("SetDeltas:Bad height");
+ }
+ if( !nDeltaWidth )
+ {
+ nDeltaWidth = 1;
+ DBG_WARNING("SetDeltas:Bad width");
+ }
+}
+
+void IcnCursor_Impl::CreateGridAjustData( SvPtrarr& rLists, SvxIconChoiceCtrlEntry* pRefEntry)
+{
+ if( !pRefEntry )
+ {
+ USHORT nGridRows = (USHORT)(pView->aVirtOutputSize.Height() / pView->nGridDY);
+ nGridRows++; // wg. Abrundung!
+
+ if( !nGridRows )
+ return;
+ for( USHORT nCurList = 0; nCurList < nGridRows; nCurList++ )
+ {
+ SvPtrarr* pRow = new SvPtrarr;
+ rLists.Insert( (void*)pRow, nCurList );
+ }
+ const ULONG nCount = pView->aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pView->aEntries.GetObject( nCur );
+ const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
+ USHORT nIns = GetSortListPos((SvPtrarr*)rLists[nY],rRect.Left(),FALSE);
+ ((SvPtrarr*)rLists[ nY ])->Insert( pEntry, nIns );
+ }
+ }
+ else
+ {
+ // Aufbau eines hor. "Schlauchs" auf der RefEntry-Zeile
+ // UEBERLEGEN: BoundingRect nehmen wg. Ueberlappungen???
+ Rectangle rRefRect( pView->CalcBmpRect( pRefEntry ) );
+ //const Rectangle& rRefRect = pView->GetEntryBoundRect( pRefEntry );
+ short nRefRow = (short)( ((rRefRect.Top()+rRefRect.Bottom())/2) / pView->nGridDY );
+ SvPtrarr* pRow = new SvPtrarr;
+ rLists.Insert( (void*)pRow, 0 );
+ ULONG nCount = pView->aEntries.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pView->aEntries.GetObject( nCur );
+ Rectangle rRect( pView->CalcBmpRect(pEntry) );
+ //const Rectangle& rRect = pView->GetEntryBoundRect( pEntry );
+ short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
+ if( nY == nRefRow )
+ {
+ USHORT nIns = GetSortListPos( pRow, rRect.Left(), FALSE );
+ pRow->Insert( pEntry, nIns );
+ }
+ }
+ }
+}
+
+//static
+void IcnCursor_Impl::DestroyGridAdjustData( SvPtrarr& rLists )
+{
+ const USHORT nCount = rLists.Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvPtrarr* pArr = (SvPtrarr*)rLists[ nCur ];
+ delete pArr;
+ }
+ rLists.Remove( 0, rLists.Count() );
+}
+
+IcnGridMap_Impl::IcnGridMap_Impl(SvxIconChoiceCtrl_Impl* pView)
+{
+ _pView = pView;
+ _pGridMap = 0;
+ _nGridCols = 0;
+ _nGridRows = 0;
+}
+
+IcnGridMap_Impl::~IcnGridMap_Impl()
+{
+ delete[] _pGridMap, _pGridMap=0;
+}
+
+void IcnGridMap_Impl::Expand()
+{
+ if( !_pGridMap )
+ Create_Impl();
+ else
+ {
+ USHORT nNewGridRows = _nGridRows;
+ USHORT nNewGridCols = _nGridCols;
+ if( _pView->nWinBits & WB_ALIGN_TOP )
+ nNewGridRows += 50;
+ else
+ nNewGridCols += 50;
+
+ BOOL* pNewGridMap = new BOOL[nNewGridRows*nNewGridCols];
+ memset( pNewGridMap, 0, nNewGridRows * nNewGridCols * sizeof(BOOL) );
+ memcpy( pNewGridMap, _pGridMap, _nGridRows * _nGridCols * sizeof(BOOL) );
+ delete[] _pGridMap;
+ _pGridMap = pNewGridMap;
+ _nGridRows = nNewGridRows;
+ _nGridCols = nNewGridCols;
+ }
+}
+
+void IcnGridMap_Impl::Create_Impl()
+{
+ DBG_ASSERT(!_pGridMap,"Unnecessary call to IcnGridMap_Impl::Create_Impl()");
+ if( _pGridMap )
+ return;
+ GetMinMapSize( _nGridCols, _nGridRows );
+ if( _pView->nWinBits & WB_ALIGN_TOP )
+ _nGridRows += 50; // avoid resize of gridmap too often
+ else
+ _nGridCols += 50;
+
+ _pGridMap = new BOOL[ _nGridRows * _nGridCols];
+ memset( (void*)_pGridMap, 0, _nGridRows * _nGridCols );
+
+ const ULONG nCount = _pView->aEntries.Count();
+ for( ULONG nCur=0; nCur < nCount; nCur++ )
+ OccupyGrids( (SvxIconChoiceCtrlEntry*)_pView->aEntries.GetObject( nCur ));
+}
+
+void IcnGridMap_Impl::GetMinMapSize( USHORT& rDX, USHORT& rDY ) const
+{
+ long nX, nY;
+ if( _pView->nWinBits & WB_ALIGN_TOP )
+ {
+ // The view grows in vertical direction. Its max. width is _pView->nMaxVirtWidth
+ nX = _pView->nMaxVirtWidth;
+ if( !nX )
+ nX = _pView->pView->GetOutputSizePixel().Width();
+ if( !(_pView->nFlags & F_ARRANGING) )
+ nX -= _pView->nVerSBarWidth;
+
+ nY = _pView->aVirtOutputSize.Height();
+ }
+ else
+ {
+ // The view grows in horizontal direction. Its max. height is _pView->nMaxVirtHeight
+ nY = _pView->nMaxVirtHeight;
+ if( !nY )
+ nY = _pView->pView->GetOutputSizePixel().Height();
+ if( !(_pView->nFlags & F_ARRANGING) )
+ nY -= _pView->nHorSBarHeight;
+ nX = _pView->aVirtOutputSize.Width();
+ }
+
+ if( !nX )
+ nX = DEFAULT_MAX_VIRT_WIDTH;
+ if( !nY )
+ nY = DEFAULT_MAX_VIRT_HEIGHT;
+
+ long nDX = nX / _pView->nGridDX;
+ long nDY = nY / _pView->nGridDY;
+
+ if( !nDX )
+ nDX++;
+ if( !nDY )
+ nDY++;
+
+ rDX = (USHORT)nDX;
+ rDY = (USHORT)nDY;
+}
+
+GridId IcnGridMap_Impl::GetGrid( USHORT nGridX, USHORT nGridY )
+{
+ Create();
+ if( _pView->nWinBits & WB_ALIGN_TOP )
+ return nGridX + ( nGridY * _nGridCols );
+ else
+ return nGridY + ( nGridX * _nGridRows );
+}
+
+GridId IcnGridMap_Impl::GetGrid( const Point& rDocPos, BOOL* pbClipped )
+{
+ Create();
+
+ long nX = rDocPos.X();
+ long nY = rDocPos.Y();
+ nX -= LROFFS_WINBORDER;
+ nY -= TBOFFS_WINBORDER;
+ nX /= _pView->nGridDX;
+ nY /= _pView->nGridDY;
+ BOOL bClipped = FALSE;
+ if( nX >= _nGridCols )
+ {
+ nX = _nGridCols - 1;
+ bClipped = TRUE;
+ }
+ if( nY >= _nGridRows )
+ {
+ nY = _nGridRows - 1;
+ bClipped = TRUE;
+ }
+ GridId nId = GetGrid( (USHORT)nX, (USHORT)nY );
+ if( pbClipped )
+ *pbClipped = bClipped;
+ DBG_ASSERT(nId <(ULONG)(_nGridCols*_nGridRows),"GetGrid failed");
+ return nId;
+}
+
+Rectangle IcnGridMap_Impl::GetGridRect( GridId nId )
+{
+ Create();
+ USHORT nGridX, nGridY;
+ GetGridCoord( nId, nGridX, nGridY );
+ const long nLeft = nGridX * _pView->nGridDX+ LROFFS_WINBORDER;
+ const long nTop = nGridY * _pView->nGridDY + TBOFFS_WINBORDER;
+ return Rectangle(
+ nLeft, nTop,
+ nLeft + _pView->nGridDX,
+ nTop + _pView->nGridDY );
+}
+
+GridId IcnGridMap_Impl::GetUnoccupiedGrid( BOOL bOccupyFound )
+{
+ Create();
+ ULONG nStart = 0;
+ BOOL bExpanded = FALSE;
+
+ while( 1 )
+ {
+ const ULONG nCount = (USHORT)(_nGridCols * _nGridRows);
+ for( ULONG nCur = nStart; nCur < nCount; nCur++ )
+ {
+ if( !_pGridMap[ nCur ] )
+ {
+ if( bOccupyFound )
+ _pGridMap[ nCur ] = TRUE;
+ return (GridId)nCur;
+ }
+ }
+ DBG_ASSERT(!bExpanded,"ExpandGrid failed");
+ if( bExpanded )
+ return 0; // prevent never ending loop
+ bExpanded = TRUE;
+ Expand();
+ nStart = nCount;
+ }
+}
+
+// ein Eintrag belegt nur das unter seinem Zentrum liegende GridRect
+// diese Variante ist bedeutend schneller als die Belegung ueber das
+// Bounding-Rect, kann aber zu kleinen Ueberlappungen fuehren
+#define OCCUPY_CENTER
+
+void IcnGridMap_Impl::OccupyGrids( const SvxIconChoiceCtrlEntry* pEntry, BOOL bOccupy )
+{
+ if( !_pGridMap || !_pView->IsBoundingRectValid( pEntry->aRect ))
+ return;
+#ifndef OCCUPY_CENTER
+ OccupyGrids( pEntry->aRect, bOccupy );
+#else
+ OccupyGrid( GetGrid( pEntry->aRect.Center()), bOccupy );
+#endif
+
+}
+
+void IcnGridMap_Impl::OccupyGrids( const Rectangle& rRect, BOOL bUsed )
+{
+ if( !_pGridMap )
+ return;
+
+ if( bUsed )
+ {
+ if( _aLastOccupiedGrid == rRect )
+ return;
+ _aLastOccupiedGrid = rRect;
+ }
+ else
+ _aLastOccupiedGrid.SetEmpty();
+
+ BOOL bTopLeftClipped, bBottomRightClipped;
+ GridId nIdTL = GetGrid( rRect.TopLeft(), &bTopLeftClipped );
+ GridId nIdBR = GetGrid( rRect.BottomRight(), &bBottomRightClipped );
+
+ if( bTopLeftClipped && bBottomRightClipped )
+ return;
+
+ USHORT nX1,nX2,nY1,nY2;
+ GetGridCoord( nIdTL, nX1, nY1 );
+ GetGridCoord( nIdBR, nX2, nY2 );
+ USHORT nTemp;
+ if( nX1 > nX2 )
+ {
+ nTemp = nX1;
+ nX1 = nX2;
+ nX2 = nTemp;
+ }
+ if( nY1 > nY2 )
+ {
+ nTemp = nY1;
+ nY1 = nY2;
+ nY2 = nTemp;
+ }
+ for( ; nX1 <= nX2; nX1++ )
+ for( ; nY1 <= nY2; nY1++ )
+ OccupyGrid( GetGrid( nX1, nY1 ) );
+}
+
+void IcnGridMap_Impl::Clear()
+{
+ if( _pGridMap )
+ {
+ delete[] _pGridMap, _pGridMap=0;
+ _nGridRows = 0;
+ _nGridCols = 0;
+ _aLastOccupiedGrid.SetEmpty();
+ }
+}
+
+ULONG IcnGridMap_Impl::GetGridCount( const Size& rSizePixel, USHORT nDX, USHORT nDY)
+{
+ long ndx = (rSizePixel.Width() - LROFFS_WINBORDER) / nDX;
+ if( ndx < 0 ) ndx *= -1;
+ long ndy = (rSizePixel.Height() - TBOFFS_WINBORDER) / nDY;
+ if( ndy < 0 ) ndy *= -1;
+ return (ULONG)(ndx * ndy);
+}
+
+void IcnGridMap_Impl::OutputSizeChanged()
+{
+ if( _pGridMap )
+ {
+ USHORT nCols, nRows;
+ GetMinMapSize( nCols, nRows );
+ if( _pView->nWinBits & WB_ALIGN_TOP )
+ {
+ if( nCols != _nGridCols )
+ Clear();
+ else if( nRows >= _nGridRows )
+ Expand();
+ }
+ else
+ {
+ if( nRows != _nGridRows )
+ Clear();
+ else if( nCols >= _nGridCols )
+ Expand();
+ }
+ }
+}
+
+// Independendly of the views alignment (TOP or LEFT) the gridmap
+// should contain the data in a continues region, to make it possible
+// to copy the whole block if the gridmap needs to be expanded.
+void IcnGridMap_Impl::GetGridCoord( GridId nId, USHORT& rGridX, USHORT& rGridY )
+{
+ Create();
+ if( _pView->nWinBits & WB_ALIGN_TOP )
+ {
+ rGridX = (USHORT)(nId % _nGridCols);
+ rGridY = (USHORT)(nId / _nGridCols);
+ }
+ else
+ {
+ rGridX = (USHORT)(nId / _nGridRows);
+ rGridY = (USHORT)(nId % _nGridRows);
+ }
+}
+
+
+
diff --git a/svtools/source/contnr/ivctrl.cxx b/svtools/source/contnr/ivctrl.cxx
new file mode 100644
index 000000000000..dae3abbac966
--- /dev/null
+++ b/svtools/source/contnr/ivctrl.cxx
@@ -0,0 +1,642 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifndef GCC
+#endif
+
+#include "ivctrl.hxx"
+#include "imivctl.hxx"
+#include <vcl/bitmapex.hxx>
+#include <vcl/controllayout.hxx>
+#include <vcl/mnemonic.hxx>
+using namespace ::com::sun::star::accessibility;
+
+/*****************************************************************************
+|
+| class : SvxIconChoiceCtrlEntry
+|
+\*****************************************************************************/
+
+SvxIconChoiceCtrlEntry::SvxIconChoiceCtrlEntry( const String& rText, const Image& rImage, USHORT _nFlags )
+{
+ aText = rText;
+ aImage = rImage;
+ aImageHC = rImage;
+ pUserData = NULL;
+
+ nFlags = _nFlags;
+ eTextMode = IcnShowTextShort;
+ pblink = 0;
+ pflink = 0;
+}
+
+SvxIconChoiceCtrlEntry::SvxIconChoiceCtrlEntry( const String& rText, const Image& rImage, const Image& rImageHC, USHORT _nFlags )
+{
+ aText = rText;
+ aImage = rImage;
+ aImageHC = rImageHC;
+ pUserData = NULL;
+
+ nFlags = _nFlags;
+ eTextMode = IcnShowTextShort;
+ pblink = 0;
+ pflink = 0;
+}
+
+SvxIconChoiceCtrlEntry::SvxIconChoiceCtrlEntry( USHORT _nFlags )
+{
+ pUserData = NULL;
+
+ nFlags = _nFlags;
+ eTextMode = IcnShowTextShort;
+ pblink = 0;
+ pflink = 0;
+}
+
+void SvxIconChoiceCtrlEntry::SetMoved( BOOL bMoved )
+{
+ if( bMoved )
+ nFlags |= ICNVIEW_FLAG_POS_MOVED;
+ else
+ nFlags &= ~ICNVIEW_FLAG_POS_MOVED;
+}
+
+void SvxIconChoiceCtrlEntry::LockPos( BOOL bLock )
+{
+ if( bLock )
+ nFlags |= ICNVIEW_FLAG_POS_LOCKED;
+ else
+ nFlags &= ~ICNVIEW_FLAG_POS_LOCKED;
+}
+
+/*sal_Unicode SvxIconChoiceCtrlEntry::GetMnemonicChar() const
+{
+ sal_Unicode cChar = 0;
+ xub_StrLen nPos = aText.Search( '~' );
+ if ( nPos != STRING_NOTFOUND && nPos < ( aText.Len() ) - 1 )
+ cChar = aText.GetChar( nPos + 1 );
+ return cChar;
+}*/
+
+String SvxIconChoiceCtrlEntry::GetDisplayText() const
+{
+ return MnemonicGenerator::EraseAllMnemonicChars( aText );
+}
+
+// ----------------------------------------------------------------------------
+
+SvxIconChoiceCtrlColumnInfo::SvxIconChoiceCtrlColumnInfo( const SvxIconChoiceCtrlColumnInfo& rInfo )
+ : aColText( rInfo.aColText ), aColImage( rInfo.aColImage )
+{
+ nWidth = rInfo.nWidth;
+ eAlignment = rInfo.eAlignment;
+ nSubItem = rInfo.nSubItem;
+}
+
+/*****************************************************************************
+|
+| class : SvtIconChoiceCtrl
+|
+\*****************************************************************************/
+
+SvtIconChoiceCtrl::SvtIconChoiceCtrl( Window* pParent, WinBits nWinStyle ) :
+
+ // WB_CLIPCHILDREN an, da ScrollBars auf dem Fenster liegen!
+ Control( pParent, nWinStyle | WB_CLIPCHILDREN ),
+
+ _pCurKeyEvent ( NULL ),
+ _pImp ( new SvxIconChoiceCtrl_Impl( this, nWinStyle ) ),
+ _bAutoFontColor ( FALSE )
+
+{
+ SetLineColor();
+ _pImp->SetGrid( Size( 100, 70 ) );
+ _pImp->InitSettings();
+ _pImp->SetPositionMode( IcnViewPositionModeAutoArrange );
+}
+
+SvtIconChoiceCtrl::SvtIconChoiceCtrl( Window* pParent, const ResId& rResId ) :
+
+ Control( pParent, rResId ),
+
+ _pCurKeyEvent ( NULL ),
+ _pImp ( new SvxIconChoiceCtrl_Impl( this, WB_BORDER ) ),
+ _bAutoFontColor ( FALSE )
+
+{
+ SetLineColor();
+ _pImp->SetGrid( Size( 100, 70 ) );
+ _pImp->InitSettings();
+ _pImp->SetPositionMode( IcnViewPositionModeAutoArrange );
+}
+
+SvtIconChoiceCtrl::~SvtIconChoiceCtrl()
+{
+ _pImp->CallEventListeners( VCLEVENT_OBJECT_DYING );
+ delete _pImp;
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::InsertEntry( ULONG nPos, const Point* pPos, USHORT nFlags )
+{
+ SvxIconChoiceCtrlEntry* pEntry = new SvxIconChoiceCtrlEntry( nFlags );
+ _pImp->InsertEntry( pEntry, nPos, pPos );
+ return pEntry;
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::InsertEntry( const String& rText, const Image& rImage, ULONG nPos, const Point* pPos, USHORT nFlags )
+{
+ SvxIconChoiceCtrlEntry* pEntry = new SvxIconChoiceCtrlEntry( rText, rImage, nFlags);
+
+ _pImp->InsertEntry( pEntry, nPos, pPos );
+
+ return pEntry;
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::InsertEntry( const String& rText, const Image& rImage, const Image& rImageHC, ULONG nPos, const Point* pPos, USHORT nFlags )
+{
+ SvxIconChoiceCtrlEntry* pEntry = new SvxIconChoiceCtrlEntry( rText, rImage, rImageHC, nFlags);
+
+ _pImp->InsertEntry( pEntry, nPos, pPos );
+
+ return pEntry;
+}
+
+BOOL SvtIconChoiceCtrl::EditedEntry( SvxIconChoiceCtrlEntry*, const XubString&, BOOL )
+{
+ return TRUE;
+}
+BOOL SvtIconChoiceCtrl::EditingEntry( SvxIconChoiceCtrlEntry* )
+{
+ return TRUE;
+}
+void SvtIconChoiceCtrl::DrawEntryImage( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos, OutputDevice& rDev )
+{
+ rDev.DrawImage( rPos, GetSettings().GetStyleSettings().GetHighContrastMode() ? pEntry->GetImageHC() : pEntry->GetImage() );
+}
+String SvtIconChoiceCtrl::GetEntryText( SvxIconChoiceCtrlEntry* pEntry, BOOL )
+{
+ return pEntry->GetText();
+}
+BOOL SvtIconChoiceCtrl::HasBackground() const
+{
+ return FALSE;
+}
+BOOL SvtIconChoiceCtrl::HasFont() const
+{
+ return FALSE;
+}
+BOOL SvtIconChoiceCtrl::HasFontTextColor() const
+{
+ return TRUE;
+}
+BOOL SvtIconChoiceCtrl::HasFontFillColor() const
+{
+ return TRUE;
+}
+
+void SvtIconChoiceCtrl::Paint( const Rectangle& rRect )
+{
+ _pImp->Paint( rRect );
+}
+
+void SvtIconChoiceCtrl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if( !_pImp->MouseButtonDown( rMEvt ) )
+ Control::MouseButtonDown( rMEvt );
+}
+
+void SvtIconChoiceCtrl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if( !_pImp->MouseButtonUp( rMEvt ) )
+ Control::MouseButtonUp( rMEvt );
+}
+
+void SvtIconChoiceCtrl::MouseMove( const MouseEvent& rMEvt )
+{
+ if( !_pImp->MouseMove( rMEvt ) )
+ Control::MouseMove( rMEvt );
+}
+void SvtIconChoiceCtrl::ArrangeIcons()
+{
+ if ( GetStyle() & WB_ALIGN_TOP )
+ {
+ Size aFullSize;
+ Rectangle aEntryRect;
+
+ for ( ULONG i = 0; i < GetEntryCount(); i++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry ( i );
+ aEntryRect = _pImp->GetEntryBoundRect ( pEntry );
+
+ aFullSize.setWidth ( aFullSize.getWidth()+aEntryRect.GetWidth() );
+ }
+
+ _pImp->Arrange ( FALSE, aFullSize.getWidth() );
+ }
+ else if ( GetStyle() & WB_ALIGN_LEFT )
+ {
+ Size aFullSize;
+ Rectangle aEntryRect;
+
+ for ( ULONG i = 0; i < GetEntryCount(); i++ )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry ( i );
+ aEntryRect = _pImp->GetEntryBoundRect ( pEntry );
+
+ aFullSize.setHeight ( aFullSize.getHeight()+aEntryRect.GetHeight() );
+ }
+
+ _pImp->Arrange ( FALSE, 0, aFullSize.getHeight() );
+ }
+ else
+ {
+ _pImp->Arrange();
+ }
+ _pImp->Arrange( FALSE, 0, 1000 );
+}
+void SvtIconChoiceCtrl::Resize()
+{
+ _pImp->Resize();
+ Control::Resize();
+}
+
+Point SvtIconChoiceCtrl::GetLogicPos( const Point& rPosPixel ) const
+{
+ Point aPos( rPosPixel );
+ aPos -= GetMapMode().GetOrigin();
+ return aPos;
+}
+
+Point SvtIconChoiceCtrl::GetPixelPos( const Point& rPosLogic ) const
+{
+ Point aPos( rPosLogic );
+ aPos += GetMapMode().GetOrigin();
+ return aPos;
+}
+
+void SvtIconChoiceCtrl::DocumentRectChanged()
+{
+ _aDocRectChangedHdl.Call( this );
+}
+
+void SvtIconChoiceCtrl::VisibleRectChanged()
+{
+ _aVisRectChangedHdl.Call( this );
+}
+
+void SvtIconChoiceCtrl::GetFocus()
+{
+ _pImp->GetFocus();
+ Control::GetFocus();
+ ULONG nPos;
+ SvxIconChoiceCtrlEntry* pSelectedEntry = GetSelectedEntry ( nPos );
+ if ( pSelectedEntry )
+ _pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pSelectedEntry );
+}
+
+void SvtIconChoiceCtrl::LoseFocus()
+{
+ _pImp->LoseFocus();
+ Control::LoseFocus();
+}
+
+void SvtIconChoiceCtrl::SetUpdateMode( BOOL bUpdate )
+{
+ Control::SetUpdateMode( bUpdate );
+ _pImp->SetUpdateMode( bUpdate );
+}
+void SvtIconChoiceCtrl::SetFont( const Font& rFont )
+{
+ if( rFont != GetFont() )
+ {
+ Control::SetFont( rFont );
+ _pImp->FontModified();
+ }
+}
+
+void SvtIconChoiceCtrl::SetPointFont( const Font& rFont )
+{
+ if( rFont != GetPointFont() )
+ {
+ Control::SetPointFont( rFont );
+ _pImp->FontModified();
+ }
+}
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::GetEntry( const Point& rPixPos, BOOL bHit ) const
+{
+ Point aPos( rPixPos );
+ aPos -= GetMapMode().GetOrigin();
+ return ((SvtIconChoiceCtrl*)this)->_pImp->GetEntry( aPos, bHit );
+}
+
+void SvtIconChoiceCtrl::SetStyle( WinBits nWinStyle )
+{
+ _pImp->SetStyle( nWinStyle );
+}
+
+WinBits SvtIconChoiceCtrl::GetStyle() const
+{
+ return _pImp->GetStyle();
+}
+void SvtIconChoiceCtrl::Command( const CommandEvent& rCEvt )
+{
+ _pImp->Command( rCEvt );
+}
+
+void SvtIconChoiceCtrl::SetEntryTextMode( SvxIconChoiceCtrlTextMode eMode, SvxIconChoiceCtrlEntry* pEntry )
+{
+ _pImp->SetEntryTextMode( eMode, pEntry );
+}
+
+SvxIconChoiceCtrlTextMode SvtIconChoiceCtrl::GetEntryTextMode( const SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ return _pImp->GetEntryTextModeSmart( pEntry );
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::GetNextEntry( const Point& rPixPos, SvxIconChoiceCtrlEntry* pCurEntry, BOOL ) const
+{
+ Point aPos( rPixPos );
+ aPos -= GetMapMode().GetOrigin();
+ return ((SvtIconChoiceCtrl*)this)->_pImp->GetNextEntry( aPos, pCurEntry );
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::GetPrevEntry( const Point& rPixPos, SvxIconChoiceCtrlEntry* pCurEntry, BOOL ) const
+{
+ Point aPos( rPixPos );
+ aPos -= GetMapMode().GetOrigin();
+ return ((SvtIconChoiceCtrl*)this)->_pImp->GetPrevEntry( aPos, pCurEntry );
+}
+ULONG SvtIconChoiceCtrl::GetEntryCount() const
+{
+ return _pImp->GetEntryCount();
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::GetEntry( ULONG nPos ) const
+{
+ return _pImp->GetEntry( nPos );
+}
+
+void SvtIconChoiceCtrl::CreateAutoMnemonics( MnemonicGenerator& _rUsedMnemonics )
+{
+ _pImp->CreateAutoMnemonics( &_rUsedMnemonics );
+}
+
+void SvtIconChoiceCtrl::CreateAutoMnemonics( void )
+{
+ _pImp->CreateAutoMnemonics();
+}
+
+void SvtIconChoiceCtrl::RemoveEntry( SvxIconChoiceCtrlEntry* pEntry )
+{
+ _pImp->RemoveEntry( pEntry );
+}
+
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::GetSelectedEntry( ULONG& rPos ) const
+{
+ return _pImp->GetFirstSelectedEntry( rPos );
+}
+
+void SvtIconChoiceCtrl::ClickIcon()
+{
+ ULONG nPos;
+ GetSelectedEntry ( nPos );
+ _aClickIconHdl.Call( this );
+}
+BOOL SvtIconChoiceCtrl::IsEntryEditing() const
+{
+ return _pImp->IsEntryEditing();
+}
+
+BOOL SvtIconChoiceCtrl::SetChoiceWithCursor ( BOOL bDo )
+{
+ return _pImp->SetChoiceWithCursor (bDo);
+}
+
+void SvtIconChoiceCtrl::KeyInput( const KeyEvent& rKEvt )
+{
+ BOOL bKeyUsed = DoKeyInput( rKEvt );
+ if ( !bKeyUsed )
+ {
+ _pCurKeyEvent = (KeyEvent*)&rKEvt;
+ Control::KeyInput( rKEvt );
+ _pCurKeyEvent = NULL;
+ }
+}
+BOOL SvtIconChoiceCtrl::DoKeyInput( const KeyEvent& rKEvt )
+{
+ // unter OS/2 bekommen wir auch beim Editieren Key-Up/Down
+ if( IsEntryEditing() )
+ return TRUE;
+ _pCurKeyEvent = (KeyEvent*)&rKEvt;
+ BOOL bHandled = _pImp->KeyInput( rKEvt );
+ _pCurKeyEvent = NULL;
+ return bHandled;
+}
+ULONG SvtIconChoiceCtrl::GetEntryListPos( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ return _pImp->GetEntryListPos( pEntry );
+}
+SvxIconChoiceCtrlEntry* SvtIconChoiceCtrl::GetCursor( ) const
+{
+ return _pImp->GetCurEntry( );
+}
+void SvtIconChoiceCtrl::SetCursor( SvxIconChoiceCtrlEntry* pEntry )
+{
+ _pImp->SetCursor( pEntry );
+}
+void SvtIconChoiceCtrl::InvalidateEntry( SvxIconChoiceCtrlEntry* pEntry )
+{
+ _pImp->InvalidateEntry( pEntry );
+}
+void SvtIconChoiceCtrl::Clear()
+{
+ _pImp->Clear();
+}
+void SvtIconChoiceCtrl::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+}
+
+
+void SvtIconChoiceCtrl::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( ((rDCEvt.GetType() == DATACHANGED_SETTINGS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ _pImp->InitSettings();
+ Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ else
+ Control::DataChanged( rDCEvt );
+}
+
+void SvtIconChoiceCtrl::SetBackground( const Wallpaper& rPaper )
+{
+ if( rPaper != GetBackground() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Wallpaper aEmpty;
+ if( rPaper == aEmpty )
+ Control::SetBackground( rStyleSettings.GetFieldColor() );
+ else
+ {
+ Wallpaper aBackground( rPaper );
+ // HACK, da Hintergrund sonst transparent sein koennte
+ if( !aBackground.IsBitmap() )
+ aBackground.SetStyle( WALLPAPER_TILE );
+
+ WallpaperStyle eStyle = aBackground.GetStyle();
+ Color aBack( aBackground.GetColor());
+ Color aTrans( COL_TRANSPARENT );
+ if( aBack == aTrans && (
+ (!aBackground.IsBitmap() ||
+ aBackground.GetBitmap().IsTransparent() ||
+ (eStyle != WALLPAPER_TILE && eStyle != WALLPAPER_SCALE))))
+ {
+ aBackground.SetColor( rStyleSettings.GetFieldColor() );
+ }
+ if( aBackground.IsScrollable() )
+ {
+ Rectangle aRect;
+ aRect.SetSize( Size(32765, 32765) );
+ aBackground.SetRect( aRect );
+ }
+ else
+ {
+ Rectangle aRect( _pImp->GetOutputRect() );
+ aBackground.SetRect( aRect );
+ }
+ Control::SetBackground( aBackground );
+ }
+
+ // bei hart attributierter Textfarbe keine 'Automatik', die eine
+ // lesbare Textfarbe einstellt.
+ Font aFont( GetFont() );
+ aFont.SetColor( rStyleSettings.GetFieldTextColor() );
+ SetFont( aFont );
+
+ Invalidate(INVALIDATE_NOCHILDREN);
+ }
+}
+
+void SvtIconChoiceCtrl::Flush()
+{
+ _pImp->Flush();
+}
+
+void SvtIconChoiceCtrl::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( !_pImp->RequestHelp( rHEvt ) )
+ Control::RequestHelp( rHEvt );
+}
+
+void SvtIconChoiceCtrl::SetSelectionMode( SelectionMode eMode )
+{
+ _pImp->SetSelectionMode( eMode );
+}
+
+BOOL SvtIconChoiceCtrl::HandleShortCutKey( const KeyEvent& r )
+{
+ return _pImp->HandleShortCutKey( r );
+}
+
+Rectangle SvtIconChoiceCtrl::GetBoundingBox( SvxIconChoiceCtrlEntry* pEntry ) const
+{
+ return _pImp->GetEntryBoundRect( pEntry );
+}
+
+void SvtIconChoiceCtrl::FillLayoutData() const
+{
+ CreateLayoutData();
+
+ SvtIconChoiceCtrl* pNonConstMe = const_cast< SvtIconChoiceCtrl* >( this );
+
+ // loop through all entries
+ sal_uInt16 nCount = (sal_uInt16)GetEntryCount();
+ sal_uInt16 nPos = 0;
+ while ( nPos < nCount )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry( nPos );
+
+ Point aPos = _pImp->GetEntryBoundRect( pEntry ).TopLeft();
+ String sEntryText = pEntry->GetDisplayText( );
+ Rectangle aTextRect = _pImp->CalcTextRect( pEntry, &aPos, sal_False, &sEntryText );
+
+ sal_Bool bLargeIconMode = WB_ICON == ( _pImp->GetStyle() & ( VIEWMODE_MASK ) );
+ sal_uInt16 nTextPaintFlags = bLargeIconMode ? PAINTFLAG_HOR_CENTERED : PAINTFLAG_VER_CENTERED;
+
+ _pImp->PaintItem( aTextRect, IcnViewFieldTypeText, pEntry, nTextPaintFlags, pNonConstMe, &sEntryText, GetLayoutData() );
+
+ ++nPos;
+ }
+}
+
+Rectangle SvtIconChoiceCtrl::GetEntryCharacterBounds( const sal_Int32 _nEntryPos, const sal_Int32 _nCharacterIndex ) const
+{
+ Rectangle aRect;
+
+ Pair aEntryCharacterRange = GetLineStartEnd( _nEntryPos );
+ if ( aEntryCharacterRange.A() + _nCharacterIndex < aEntryCharacterRange.B() )
+ {
+ aRect = GetCharacterBounds( aEntryCharacterRange.A() + _nCharacterIndex );
+ }
+
+ return aRect;
+}
+
+void SvtIconChoiceCtrl::SetNoSelection()
+{
+ _pImp->SetNoSelection();
+}
+
+void SvtIconChoiceCtrl::CallImplEventListeners(ULONG nEvent, void* pData)
+{
+ CallEventListeners(nEvent, pData);
+}
+::com::sun::star::uno::Reference< XAccessible > SvtIconChoiceCtrl::CreateAccessible()
+{
+ Window* pParent = GetAccessibleParentWindow();
+ DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" );
+
+ ::com::sun::star::uno::Reference< XAccessible > xAccessible;
+ if ( pParent )
+ {
+ ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
+ if ( xAccParent.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface());
+ xAccessible = _pImp->GetAccessibleFactory().createAccessibleIconChoiceCtrl( *this, xAccParent );
+ }
+ }
+ return xAccessible;
+}
+
diff --git a/svtools/source/contnr/makefile.mk b/svtools/source/contnr/makefile.mk
new file mode 100644
index 000000000000..232665c88c9c
--- /dev/null
+++ b/svtools/source/contnr/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=svcontnr
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=cont_pch
+PROJECTPCHSOURCE=cont_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+EXCEPTIONSFILES=\
+ $(SLO)$/contentenumeration.obj \
+ $(SLO)$/fileview.obj \
+ $(SLO)$/svlbox.obj \
+ $(SLO)$/svtabbx.obj \
+ $(SLO)$/svimpbox.obj \
+ $(SLO)$/templwin.obj
+
+SLOFILES= $(EXCEPTIONSFILES) \
+ $(SLO)$/svicnvw.obj \
+ $(SLO)$/svimpicn.obj \
+ $(SLO)$/treelist.obj \
+ $(SLO)$/svlbitm.obj \
+ $(SLO)$/svtreebx.obj \
+ $(SLO)$/imivctl1.obj \
+ $(SLO)$/imivctl2.obj \
+ $(SLO)$/ivctrl.obj \
+ $(SLO)$/tooltiplbox.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES =\
+ fileview.src \
+ templwin.src \
+ svcontnr.src
+
+HXX1TARGET= svcontnr
+HXX1EXT= hxx
+HXX1FILES= $(PRJ)$/inc$/svlbox.hxx \
+ $(PRJ)$/inc$/svlbitm.hxx \
+ $(PRJ)$/inc$/svtreebx.hxx \
+ $(PRJ)$/inc$/svicnvw.hxx \
+ $(PRJ)$/inc$/svtabbx.hxx \
+ $(PRJ)$/inc$/treelist.hxx
+HXX1EXCL= -E:*include*
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/contnr/svcontnr.src b/svtools/source/contnr/svcontnr.src
new file mode 100644
index 000000000000..bcd1e060664f
--- /dev/null
+++ b/svtools/source/contnr/svcontnr.src
@@ -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 <svtools/svtools.hrc>
+
+Image RID_IMG_TREENODE_COLLAPSED
+{
+ ImageBitmap = Bitmap { File = "plus.bmp"; } ;
+ MaskColor = Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; };
+};
+
+Image RID_IMG_TREENODE_EXPANDED
+{
+ ImageBitmap = Bitmap { File = "minus.bmp"; } ;
+ MaskColor = Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; };
+};
+
+Image RID_IMG_TREENODE_COLLAPSED_HC
+{
+ ImageBitmap = Bitmap { File = "plus_sch.bmp"; } ;
+ MaskColor = Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; };
+};
+
+Image RID_IMG_TREENODE_EXPANDED_HC
+{
+ ImageBitmap = Bitmap { File = "minus_sch.bmp"; } ;
+ MaskColor = Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; };
+};
+
+// descriptions of accessible objects
+
+String STR_SVT_ACC_DESC_TABLISTBOX
+{
+ Text [ en-US ] = "Row: %1, Column: %2";
+};
+String STR_SVT_ACC_DESC_FILEVIEW
+{
+ Text [ en-US ] = ", Type: %1, URL: %2";
+};
+String STR_SVT_ACC_DESC_FOLDER
+{
+ Text [ en-US ] = "Folder";
+};
+String STR_SVT_ACC_DESC_FILE
+{
+ Text [ en-US ] = "File";
+};
+String STR_SVT_ACC_EMPTY_FIELD
+{
+ Text [ en-US ] = "Empty Field";
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/contnr/svicnvw.cxx b/svtools/source/contnr/svicnvw.cxx
new file mode 100644
index 000000000000..20bcfe0fe33a
--- /dev/null
+++ b/svtools/source/contnr/svicnvw.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_svtools.hxx"
+
+#include <svtools/svlbox.hxx>
+#include <svtools/svicnvw.hxx>
+#include <svimpicn.hxx>
+#include <svtools/svlbitm.hxx>
+
+#ifndef GCC
+#endif
+
+#define ICNVW_BLOCK_ENTRYINS 0x0001
+
+SvIcnVwDataEntry::SvIcnVwDataEntry()
+ : nIcnVwFlags(0),eTextMode(ShowTextDontKnow)
+{
+}
+
+SvIcnVwDataEntry::~SvIcnVwDataEntry()
+{
+}
+
+SvIconView::SvIconView( Window* pParent, WinBits nWinStyle ) :
+ SvLBox( pParent, nWinStyle | WB_BORDER )
+{
+ nWinBits = nWinStyle;
+ nIcnVwFlags = 0;
+ pImp = new SvImpIconView( this, GetModel(), nWinStyle | WB_ICON );
+ pImp->mpViewData = 0;
+ SetSelectionMode( SINGLE_SELECTION );
+ SetLineColor();
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+ SetDefaultFont();
+}
+
+SvIconView::SvIconView( Window* pParent , const ResId& rResId ) :
+ SvLBox( pParent, rResId )
+{
+ pImp = new SvImpIconView( this, GetModel(), WB_BORDER | WB_ICON );
+ nIcnVwFlags = 0;
+ pImp->mpViewData = 0;
+ SetLineColor();
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+ SetDefaultFont();
+ pImp->SetSelectionMode( GetSelectionMode() );
+ pImp->SetWindowBits( nWindowStyle );
+ nWinBits = nWindowStyle;
+}
+
+SvIconView::~SvIconView()
+{
+ delete pImp;
+}
+
+void SvIconView::SetDefaultFont()
+{
+ SetFont( GetFont() );
+}
+
+SvLBoxEntry* SvIconView::CreateEntry( const XubString& rStr,
+ const Image& rCollEntryBmp, const Image& rExpEntryBmp )
+{
+ SvLBoxEntry* pEntry = new SvLBoxEntry;
+
+ SvLBoxContextBmp* pContextBmp =
+ new SvLBoxContextBmp( pEntry,0, rCollEntryBmp,rExpEntryBmp, 0xffff );
+ pEntry->AddItem( pContextBmp );
+
+ SvLBoxString* pString = new SvLBoxString( pEntry, 0, rStr );
+ pEntry->AddItem( pString );
+
+ return pEntry;
+}
+
+void SvIconView::DisconnectFromModel()
+{
+ SvLBox::DisconnectFromModel();
+ pImp->SetModel( GetModel(), 0 );
+}
+
+
+SvLBoxEntry* SvIconView::InsertEntry( const XubString& rText,
+ SvLBoxEntry* pParent, BOOL bChildsOnDemand, ULONG nPos )
+{
+ SvLBoxEntry* pEntry = CreateEntry(
+ rText, aCollapsedEntryBmp, aExpandedEntryBmp );
+ pEntry->EnableChildsOnDemand( bChildsOnDemand );
+
+ if ( !pParent )
+ SvLBox::Insert( pEntry, nPos );
+ else
+ SvLBox::Insert( pEntry, pParent, nPos );
+ return pEntry;
+}
+
+SvLBoxEntry* SvIconView::InsertEntry( const XubString& rText,
+ const Image& rExpEntryBmp,
+ const Image& rCollEntryBmp,
+ SvLBoxEntry* pParent, BOOL bChildsOnDemand, ULONG nPos)
+{
+ SvLBoxEntry* pEntry = CreateEntry(
+ rText, rCollEntryBmp, rExpEntryBmp );
+
+ pEntry->EnableChildsOnDemand( bChildsOnDemand );
+ if ( !pParent )
+ SvLBox::Insert( pEntry, nPos );
+ else
+ SvLBox::Insert( pEntry, pParent, nPos );
+ return pEntry;
+}
+
+
+void SvIconView::SetEntryText(SvLBoxEntry* pEntry, const XubString& rStr)
+{
+ SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if ( pItem )
+ {
+ pItem->SetText( pEntry, rStr );
+ GetModel()->InvalidateEntry( pEntry );
+ }
+}
+
+void SvIconView::SetExpandedEntryBmp(SvLBoxEntry* pEntry, const Image& rBmp)
+{
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if ( pItem )
+ {
+ pItem->SetBitmap2( rBmp );
+ GetModel()->InvalidateEntry( pEntry );
+ }
+}
+
+void SvIconView::SetCollapsedEntryBmp(SvLBoxEntry* pEntry,
+ const Image& rBmp )
+{
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if ( pItem )
+ {
+ pItem->SetBitmap1( rBmp );
+ GetModel()->InvalidateEntry( pEntry );
+ }
+}
+
+XubString SvIconView::GetEntryText(SvLBoxEntry* pEntry ) const
+{
+ XubString aStr;
+ SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if ( pItem )
+ aStr = pItem->GetText();
+ return aStr;
+}
+
+Image SvIconView::GetExpandedEntryBmp(SvLBoxEntry* pEntry) const
+{
+ Image aBmp;
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if ( pItem )
+ aBmp = pItem->GetBitmap2();
+ return aBmp;
+}
+
+Image SvIconView::GetCollapsedEntryBmp(SvLBoxEntry* pEntry) const
+{
+ Image aBmp;
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if ( pItem )
+ aBmp = pItem->GetBitmap1();
+ return aBmp;
+}
+
+
+SvLBoxEntry* SvIconView::CloneEntry( SvLBoxEntry* pSource )
+{
+ XubString aStr;
+ Image aCollEntryBmp;
+ Image aExpEntryBmp;
+
+ SvLBoxString* pStringItem = (SvLBoxString*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if ( pStringItem )
+ aStr = pStringItem->GetText();
+ SvLBoxContextBmp* pBmpItem =(SvLBoxContextBmp*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if ( pBmpItem )
+ {
+ aCollEntryBmp = pBmpItem->GetBitmap1();
+ aExpEntryBmp = pBmpItem->GetBitmap2();
+ }
+ SvLBoxEntry* pEntry = CreateEntry( aStr, aCollEntryBmp, aExpEntryBmp );
+ pEntry->SvListEntry::Clone( pSource );
+ pEntry->EnableChildsOnDemand( pSource->HasChildsOnDemand() );
+ pEntry->SetUserData( pSource->GetUserData() );
+ return pEntry;
+}
+
+
+USHORT SvIconView::IsA()
+{
+ return SV_LISTBOX_ID_ICONVIEW;
+}
+
+void SvIconView::RequestingChilds( SvLBoxEntry* pParent )
+{
+ if ( !pParent->HasChilds() )
+ InsertEntry( String::CreateFromAscii("<dummy>"), pParent, FALSE, LIST_APPEND );
+}
+
+void __EXPORT SvIconView::Paint( const Rectangle& rRect )
+{
+ pImp->Paint( rRect );
+}
+
+void __EXPORT SvIconView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ pImp->MouseButtonDown( rMEvt );
+}
+
+void __EXPORT SvIconView::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ pImp->MouseButtonUp( rMEvt );
+}
+
+void __EXPORT SvIconView::MouseMove( const MouseEvent& rMEvt )
+{
+ pImp->MouseMove( rMEvt );
+}
+
+void __EXPORT SvIconView::KeyInput( const KeyEvent& rKEvt )
+{
+ // unter OS/2 bekommen wir auch beim Editieren Key-Up/Down
+ if( IsEditingActive() )
+ return;
+
+ nImpFlags |= SVLBOX_IS_TRAVELSELECT;
+ BOOL bKeyUsed = pImp->KeyInput( rKEvt );
+ if ( !bKeyUsed )
+ SvLBox::KeyInput( rKEvt );
+ nImpFlags &= ~SVLBOX_IS_TRAVELSELECT;
+}
+
+void __EXPORT SvIconView::Resize()
+{
+ pImp->Resize();
+ SvLBox::Resize();
+}
+
+void __EXPORT SvIconView::GetFocus()
+{
+ pImp->GetFocus();
+ SvLBox::GetFocus();
+}
+
+void __EXPORT SvIconView::LoseFocus()
+{
+ pImp->LoseFocus();
+ SvLBox::LoseFocus();
+}
+
+void SvIconView::SetUpdateMode( BOOL bUpdate )
+{
+ Control::SetUpdateMode( bUpdate );
+ if ( bUpdate )
+ pImp->UpdateAll();
+}
+
+void SvIconView::SetModel( SvLBoxTreeList* )
+{
+}
+
+void SvIconView::SetModel( SvLBoxTreeList* pNewModel, SvLBoxEntry* pParent )
+{
+ nIcnVwFlags |= ICNVW_BLOCK_ENTRYINS;
+ SvLBox::SetModel( pNewModel );
+ nIcnVwFlags &= (~ICNVW_BLOCK_ENTRYINS);
+ if ( pParent && pParent->HasChildsOnDemand() )
+ RequestingChilds( pParent );
+ pImp->SetModel( pNewModel, pParent );
+}
+
+void __EXPORT SvIconView::ModelHasCleared()
+{
+ SvLBox::ModelHasCleared();
+ pImp->Clear();
+}
+
+void __EXPORT SvIconView::ModelHasInserted( SvListEntry* pEntry )
+{
+ if( !(nIcnVwFlags & ICNVW_BLOCK_ENTRYINS ) )
+ pImp->EntryInserted( (SvLBoxEntry*)pEntry );
+}
+
+void __EXPORT SvIconView::ModelHasInsertedTree( SvListEntry* pEntry )
+{
+ pImp->TreeInserted( (SvLBoxEntry*)pEntry );
+}
+
+void __EXPORT SvIconView::ModelIsMoving(SvListEntry* pSource,
+ SvListEntry* /* pTargetParent */ , ULONG /* nChildPos */ )
+{
+ pImp->MovingEntry( (SvLBoxEntry*)pSource );
+}
+
+void __EXPORT SvIconView::ModelHasMoved(SvListEntry* pSource )
+{
+ pImp->EntryMoved( (SvLBoxEntry*)pSource );
+}
+
+void __EXPORT SvIconView::ModelIsRemoving( SvListEntry* pEntry )
+{
+ pImp->RemovingEntry( (SvLBoxEntry*)pEntry );
+ NotifyRemoving( (SvLBoxEntry*)pEntry );
+}
+
+void __EXPORT SvIconView::ModelHasRemoved( SvListEntry* /* pEntry */ )
+{
+ pImp->EntryRemoved();
+}
+
+void __EXPORT SvIconView::ModelHasEntryInvalidated( SvListEntry* pEntry )
+{
+ // die einzelnen Items des Entries reinitialisieren
+ SvLBox::ModelHasEntryInvalidated( pEntry );
+ // painten
+ pImp->ModelHasEntryInvalidated( pEntry );
+}
+
+void SvIconView::ShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL bShow )
+{
+ pImp->ShowTargetEmphasis( pEntry, bShow );
+}
+
+Point SvIconView::GetEntryPosition( SvLBoxEntry* pEntry ) const
+{
+ return ((SvIconView*)this)->pImp->GetEntryPosition( pEntry );
+}
+
+void SvIconView::SetEntryPosition( SvLBoxEntry* pEntry, const Point& rPos)
+{
+ pImp->SetEntryPosition( pEntry, rPos, FALSE, TRUE );
+}
+
+void SvIconView::SetEntryPosition( SvLBoxEntry* pEntry, const Point& rPos, BOOL bAdjustAtGrid )
+{
+ pImp->SetEntryPosition( pEntry, rPos, bAdjustAtGrid );
+}
+
+void SvIconView::SetFont( const Font& rFont )
+{
+ Font aTempFont( rFont );
+ aTempFont.SetTransparent( TRUE );
+ SvLBox::SetFont( aTempFont );
+ RecalcViewData();
+ pImp->ChangedFont();
+}
+
+void SvIconView::ViewDataInitialized( SvLBoxEntry* pEntry )
+{
+ pImp->ViewDataInitialized( pEntry );
+}
+
+SvLBoxEntry* SvIconView::GetDropTarget( const Point& rPos )
+{
+ return pImp->GetDropTarget( rPos );
+}
+
+SvLBoxEntry* SvIconView::GetEntry( const Point& rPixPos, BOOL ) const
+{
+ Point aPos( rPixPos );
+ aPos -= GetMapMode().GetOrigin();
+ return ((SvIconView*)this)->pImp->GetEntry( aPos );
+}
+
+SvLBoxEntry* SvIconView::GetEntryFromLogicPos( const Point& rDocPos ) const
+{
+ return ((SvIconView*)this)->pImp->GetEntry( rDocPos );
+}
+
+
+void SvIconView::SetWindowBits( WinBits nWinStyle )
+{
+ nWinBits = nWinStyle;
+ pImp->SetWindowBits( nWinStyle );
+}
+
+void SvIconView::PaintEntry( SvLBoxEntry* pEntry )
+{
+ pImp->PaintEntry( pEntry );
+}
+
+
+void SvIconView::PaintEntry( SvLBoxEntry* pEntry, const Point& rPos )
+{
+ pImp->PaintEntry( pEntry, rPos );
+}
+
+Rectangle SvIconView::GetFocusRect( SvLBoxEntry* pEntry )
+{
+ return pImp->CalcFocusRect( pEntry );
+}
+
+void SvIconView::InvalidateEntry( SvLBoxEntry* pEntry )
+{
+ pImp->InvalidateEntry( pEntry );
+}
+
+void SvIconView::SetDragDropMode( DragDropMode nDDMode )
+{
+ SvLBox::SetDragDropMode( nDDMode );
+ pImp->SetDragDropMode( nDDMode );
+}
+
+void SvIconView::SetSelectionMode( SelectionMode eSelectMode )
+{
+ SvLBox::SetSelectionMode( eSelectMode );
+ pImp->SetSelectionMode( eSelectMode );
+}
+
+BOOL SvIconView::Select( SvLBoxEntry* pEntry, BOOL bSelect )
+{
+ EndEditing();
+ BOOL bRetVal = SvListView::Select( pEntry, bSelect );
+ if( bRetVal )
+ {
+ pImp->EntrySelected( pEntry, bSelect );
+ pHdlEntry = pEntry;
+ SelectHdl();
+ }
+ return bRetVal;
+}
+
+void SvIconView::SelectAll( BOOL bSelect, BOOL )
+{
+ SvLBoxEntry* pEntry = pImp->GetCurParent();
+ pEntry = FirstChild( pEntry );
+ while( pEntry )
+ {
+ Select( pEntry, bSelect );
+ pEntry = NextSibling( pEntry );
+ }
+}
+
+void SvIconView::SetCurEntry( SvLBoxEntry* _pEntry )
+{
+ pImp->SetCursor( _pEntry );
+}
+
+SvLBoxEntry* SvIconView::GetCurEntry() const
+{
+ return pImp->GetCurEntry();
+}
+
+void SvIconView::Arrange()
+{
+#ifdef DBG_UTIL
+ USHORT n=1;
+ if( n == 1 && n-1 == 0 )
+ {
+ pImp->Arrange();
+ }
+ else
+ {
+ pImp->AdjustAtGrid();
+ }
+#else
+ pImp->Arrange();
+#endif
+}
+
+
+void SvIconView::SetSpaceBetweenEntries( long nX, long nY )
+{
+ pImp->SetSpaceBetweenEntries( nX, nY );
+}
+
+BOOL SvIconView::NotifyMoving( SvLBoxEntry* pTarget, SvLBoxEntry* pEntry,
+ SvLBoxEntry*& rpNewParent, ULONG& rNewChildPos )
+{
+ return pImp->NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos);
+}
+
+BOOL SvIconView::NotifyCopying( SvLBoxEntry* pTarget, SvLBoxEntry* pEntry,
+ SvLBoxEntry*& rpNewParent, ULONG& rNewChildPos )
+{
+ return pImp->NotifyCopying(pTarget,pEntry,rpNewParent,rNewChildPos);
+}
+
+
+void SvIconView::EnableInplaceEditing( BOOL bEnable )
+{
+ SvLBox::EnableInplaceEditing( bEnable );
+}
+
+void SvIconView::EditingRequest( SvLBoxEntry* pEntry, SvLBoxItem* pItem,
+ const Point& )
+{
+ if ( pItem->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ Selection aSel( SELECTION_MIN, SELECTION_MAX );
+ if ( EditingEntry( pEntry, aSel ) )
+ {
+ SelectAll( FALSE );
+ EditItemText( pEntry, (SvLBoxString*)pItem, aSel );
+ }
+ }
+}
+
+
+void SvIconView::EditItemText( SvLBoxEntry* pEntry, SvLBoxItem* pItem,
+ const Selection& rSel )
+{
+ DBG_ASSERT(pEntry&&pItem,"EditItemText:Params?");
+ pCurEdEntry = pEntry;
+ pCurEdItem = pItem;
+ Rectangle aRect( pImp->CalcTextRect( pEntry, (SvLBoxString*)pItem,0,TRUE ));
+
+ aRect.Bottom() += 4;
+ pImp->MakeVisible( aRect ); // vor der Umrechnung in Pixel-Koord. rufen!
+ aRect.Bottom() -= 4;
+
+ Point aPos( aRect.TopLeft() );
+ aPos += GetMapMode().GetOrigin(); // Dok-Koord. -> Window-Koord.
+ aRect.SetPos( aPos );
+
+ aRect.Bottom() += 2; // sieht huebscher aus
+
+#ifdef WIN
+ aRect.Bottom() += 4;
+#endif
+#ifdef OS2
+
+#if OS2_SINGLE_LINE_EDIT
+ aRect.Left() -= 3;
+ aRect.Right() += 3;
+ aRect.Top() -= 3;
+ aRect.Bottom() += 3;
+#else
+ aRect.Left() -= 10;
+ aRect.Right() += 10;
+ aRect.Top() -= 5;
+ aRect.Bottom() += 5;
+#endif
+
+#endif // OS2
+ EditText( ((SvLBoxString*)pItem)->GetText(), aRect, rSel, TRUE );
+}
+
+void SvIconView::EditEntry( SvLBoxEntry* pEntry )
+{
+ if( !pEntry )
+ pEntry = pImp->GetCurEntry();
+ if( pEntry )
+ {
+ SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if( pItem )
+ {
+ Selection aSel( SELECTION_MIN, SELECTION_MAX );
+ if( EditingEntry( pEntry, aSel ) )
+ {
+ SelectAll( FALSE );
+ EditItemText( pEntry, pItem, aSel );
+ }
+ }
+ }
+}
+
+void SvIconView::EditedText( const XubString& rStr )
+{
+ XubString aRefStr( ((SvLBoxString*)pCurEdItem)->GetText() );
+ if ( EditedEntry( pCurEdEntry, rStr ) )
+ {
+ ((SvLBoxString*)pCurEdItem)->SetText( pCurEdEntry, rStr );
+ pModel->InvalidateEntry( pCurEdEntry );
+ }
+ if( GetSelectionMode()==SINGLE_SELECTION && !GetSelectionCount())
+ Select( pCurEdEntry );
+}
+
+
+BOOL SvIconView::EditingEntry( SvLBoxEntry*, Selection& )
+{
+ return TRUE;
+}
+
+BOOL SvIconView::EditedEntry( SvLBoxEntry*, const XubString& )
+{
+ return TRUE;
+}
+
+
+void SvIconView::WriteDragServerInfo( const Point& rPos, SvLBoxDDInfo* pInfo)
+{
+ pImp->WriteDragServerInfo( rPos, pInfo );
+}
+
+void SvIconView::ReadDragServerInfo( const Point& rPos, SvLBoxDDInfo* pInfo )
+{
+ pImp->ReadDragServerInfo( rPos, pInfo );
+}
+
+void SvIconView::Command( const CommandEvent& rCEvt )
+{
+ pImp->PrepareCommandEvent( rCEvt.GetMousePosPixel() );
+}
+
+void SvIconView::SetCurParent( SvLBoxEntry* pNewParent )
+{
+ if ( pNewParent && pNewParent->HasChildsOnDemand() )
+ RequestingChilds( pNewParent );
+ pImp->SetCurParent( pNewParent );
+}
+
+SvLBoxEntry* SvIconView::GetCurParent() const
+{
+ return pImp->GetCurParent();
+}
+
+SvViewData* SvIconView::CreateViewData( SvListEntry* )
+{
+ SvIcnVwDataEntry* pEntryData = new SvIcnVwDataEntry;
+ return (SvViewData*)pEntryData;
+}
+
+void SvIconView::InitViewData( SvViewData* pData, SvListEntry* pEntry )
+{
+ SvLBox::InitViewData( pData, pEntry );
+ pImp->InvalidateBoundingRect( ((SvIcnVwDataEntry*)pData)->aRect );
+}
+
+Region SvIconView::GetDragRegion() const
+{
+ Rectangle aRect;
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if( pEntry )
+ aRect = pImp->GetBoundingRect( pEntry );
+ Region aRegion( aRect );
+ return aRegion;
+}
+
+ULONG SvIconView::GetSelectionCount() const
+{
+ return (ULONG)(pImp->GetSelectionCount());
+}
+
+void SvIconView::SetGrid( long nDX, long nDY )
+{
+ pImp->SetGrid( nDX, nDY );
+}
+
+void SvIconView::ModelNotification( USHORT nActionId, SvListEntry* pEntry1,
+ SvListEntry* pEntry2, ULONG nPos )
+{
+ SvLBox::ModelNotification( nActionId, pEntry1, pEntry2, nPos );
+ switch( nActionId )
+ {
+ case LISTACTION_RESORTING:
+ SetUpdateMode( FALSE );
+ break;
+
+ case LISTACTION_RESORTED:
+ SetUpdateMode( TRUE );
+ Arrange();
+ break;
+
+ case LISTACTION_CLEARED:
+ if( IsUpdateMode() )
+ Update();
+ break;
+ }
+}
+
+
+void SvIconView::Scroll( long nDeltaX, long nDeltaY, USHORT )
+{
+ pImp->Scroll( nDeltaX, nDeltaY, FALSE );
+}
+
+void SvIconView::PrepareCommandEvent( const CommandEvent& rCEvt )
+{
+ pImp->PrepareCommandEvent( rCEvt.GetMousePosPixel() );
+}
+
+void SvIconView::StartDrag( sal_Int8 nAction, const Point& rPos )
+{
+ pImp->SttDrag( rPos );
+ SvLBoxEntry* pEntry = GetEntry( rPos, TRUE );
+ pImp->mpViewData = pEntry;
+ SvLBox::StartDrag( nAction, rPos );
+}
+
+void SvIconView::DragFinished( sal_Int8 )
+{
+ pImp->EndDrag();
+}
+
+sal_Int8 SvIconView::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ if( pImp->mpViewData )
+ pImp->HideDDIcon();
+ sal_Int8 nRet = SvLBox::AcceptDrop( rEvt );
+ if( DND_ACTION_NONE != nRet )
+ pImp->ShowDDIcon( pImp->mpViewData, rEvt.maPosPixel );
+
+ return nRet;
+}
+
+sal_Int8 SvIconView::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ if( pImp->mpViewData )
+ {
+ pImp->HideDDIcon();
+ pImp->mpViewData = 0;
+ }
+ return SvLBox::ExecuteDrop( rEvt );
+}
+
+void SvIconView::ShowDDIcon( SvLBoxEntry* pRefEntry, const Point& rPos )
+{
+ pImp->ShowDDIcon( pRefEntry, rPos );
+}
+
+void SvIconView::HideDDIcon()
+{
+ pImp->HideDDIcon();
+}
+
+void SvIconView::HideShowDDIcon( SvLBoxEntry* pRefEntry, const Point& rPos )
+{
+ pImp->HideShowDDIcon( pRefEntry, rPos );
+}
+
+void SvIconView::SelectRect( const Rectangle& rRect, BOOL bAdd,
+ SvPtrarr* pRects, short nOffs )
+{
+ pImp->SelectRect( rRect, bAdd, pRects, nOffs );
+}
+
+void SvIconView::CalcScrollOffsets( const Point& rRefPosPixel, long& rX, long& rY,
+ BOOL b, USHORT nBorderWidth )
+{
+ pImp->CalcScrollOffsets( rRefPosPixel, rX, rY, b, nBorderWidth );
+}
+
+void SvIconView::EndTracking()
+{
+ pImp->EndTracking();
+}
+
+void SvIconView::MakeVisible( SvLBoxEntry* pEntry )
+{
+ pImp->MakeVisible( pEntry );
+}
+
+void SvIconView::PreparePaint( SvLBoxEntry* )
+{
+}
+
+void SvIconView::AdjustAtGrid( SvLBoxEntry* pEntry )
+{
+ pImp->AdjustAtGrid( pEntry );
+}
+
+void SvIconView::LockEntryPos( SvLBoxEntry* pEntry, BOOL bLock )
+{
+ SvIcnVwDataEntry* pViewData = (SvIcnVwDataEntry*)GetViewData( pEntry );
+ if( bLock )
+ pViewData->SetVwFlags( ICNVW_FLAG_POS_LOCKED );
+ else
+ pViewData->ClearVwFlags( ICNVW_FLAG_POS_LOCKED );
+}
+
+BOOL SvIconView::IsEntryPosLocked( const SvLBoxEntry* pEntry ) const
+{
+ const SvIcnVwDataEntry* pViewData = (const SvIcnVwDataEntry*)GetViewData( (SvListEntry*)pEntry );
+ return pViewData->IsEntryPosLocked();
+}
+
+void SvIconView::SetTextMode( SvIconViewTextMode eMode, SvLBoxEntry* pEntry )
+{
+ pImp->SetTextMode( eMode, pEntry );
+}
+
+SvIconViewTextMode SvIconView::GetTextMode( const SvLBoxEntry* pEntry ) const
+{
+ return pImp->GetTextMode( pEntry );
+}
+
+SvLBoxEntry* SvIconView::GetNextEntry( const Point& rPixPos, SvLBoxEntry* pCurEntry, BOOL ) const
+{
+ Point aPos( rPixPos );
+ aPos -= GetMapMode().GetOrigin();
+ return ((SvIconView*)this)->pImp->GetNextEntry( aPos, pCurEntry );
+}
+
+SvLBoxEntry* SvIconView::GetPrevEntry( const Point& rPixPos, SvLBoxEntry* pCurEntry, BOOL ) const
+{
+ Point aPos( rPixPos );
+ aPos -= GetMapMode().GetOrigin();
+ return ((SvIconView*)this)->pImp->GetPrevEntry( aPos, pCurEntry );
+}
+
+void SvIconView::ShowFocusRect( const SvLBoxEntry* pEntry )
+{
+ pImp->ShowFocusRect( pEntry );
+}
+
+
diff --git a/svtools/source/contnr/svimpbox.cxx b/svtools/source/contnr/svimpbox.cxx
new file mode 100644
index 000000000000..484584828b9f
--- /dev/null
+++ b/svtools/source/contnr/svimpbox.cxx
@@ -0,0 +1,3650 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/salnativewidgets.hxx>
+
+#ifndef _HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#include <tabbar.hxx>
+
+#ifndef _STACK_
+#include <stack>
+#endif
+
+#define _SVTREEBX_CXX
+#include <svtools/svtreebx.hxx>
+#include <svtools/svlbox.hxx>
+#include <svimpbox.hxx>
+#include <rtl/instance.hxx>
+#include <svtools/svtdata.hxx>
+
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+// #102891# --------------------
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+
+#define NODE_BMP_TABDIST_NOTVALID -2000000
+#define FIRST_ENTRY_TAB 1
+
+// #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors
+Image* SvImpLBox::s_pDefCollapsed = NULL;
+Image* SvImpLBox::s_pDefExpanded = NULL;
+Image* SvImpLBox::s_pDefCollapsedHC = NULL;
+Image* SvImpLBox::s_pDefExpandedHC = NULL;
+sal_Int32 SvImpLBox::s_nImageRefCount = 0;
+
+SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvLBoxTreeList* pLBTree, WinBits nWinStyle) :
+
+ pTabBar( NULL ),
+ aVerSBar( pLBView, WB_DRAG | WB_VSCROLL ),
+ aHorSBar( pLBView, WB_DRAG | WB_HSCROLL ),
+ aScrBarBox( pLBView ),
+ aOutputSize( 0, 0 ),
+ aSelEng( pLBView, (FunctionSet*)0 ),
+ aFctSet( this, &aSelEng, pLBView ),
+ nExtendedWinBits( 0 ),
+ bAreChildrenTransient( sal_True ),
+ pIntlWrapper( NULL ) // #102891# -----------------------
+{
+ osl_incrementInterlockedCount(&s_nImageRefCount);
+ pView = pLBView;
+ pTree = pLBTree;
+ aSelEng.SetFunctionSet( (FunctionSet*)&aFctSet );
+ aSelEng.ExpandSelectionOnMouseMove( FALSE );
+ SetWindowBits( nWinStyle );
+ SetSelectionMode( SINGLE_SELECTION );
+ SetDragDropMode( 0 );
+
+ aVerSBar.SetScrollHdl( LINK( this, SvImpLBox, ScrollUpDownHdl ) );
+ aHorSBar.SetScrollHdl( LINK( this, SvImpLBox, ScrollLeftRightHdl ) );
+ aHorSBar.SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) );
+ aVerSBar.SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) );
+ aVerSBar.SetRange( Range(0,0) );
+ aVerSBar.Hide();
+ aHorSBar.SetRange( Range(0,0) );
+ aHorSBar.SetPageSize( 24 ); // Pixel
+ aHorSBar.SetLineSize( 8 ); // Pixel
+
+ nHorSBarHeight = (short)aHorSBar.GetSizePixel().Height();
+ nVerSBarWidth = (short)aVerSBar.GetSizePixel().Width();
+
+ pStartEntry = 0;
+ pCursor = 0;
+ pAnchor = 0;
+ nVisibleCount = 0; // Anzahl Daten-Zeilen im Control
+ nNodeBmpTabDistance = NODE_BMP_TABDIST_NOTVALID;
+ nYoffsNodeBmp = 0;
+ nNodeBmpWidth = 0;
+
+ bAsyncBeginDrag = FALSE;
+ aAsyncBeginDragTimer.SetTimeout( 0 );
+ aAsyncBeginDragTimer.SetTimeoutHdl( LINK(this,SvImpLBox,BeginDragHdl));
+ // Button-Animation in Listbox
+ pActiveButton = 0;
+ pActiveEntry = 0;
+ pActiveTab = 0;
+
+ nFlags = 0;
+ nCurTabPos = FIRST_ENTRY_TAB;
+
+ aEditTimer.SetTimeout( 800 );
+ aEditTimer.SetTimeoutHdl( LINK(this,SvImpLBox,EditTimerCall) );
+
+ nMostRight = -1;
+ pMostRightEntry = 0;
+ nCurUserEvent = 0xffffffff;
+
+ bUpdateMode = TRUE;
+ bInVScrollHdl = FALSE;
+ nFlags |= F_FILLING;
+
+ bSubLstOpRet = bSubLstOpLR = bContextMenuHandling = bIsCellFocusEnabled = FALSE;
+}
+
+SvImpLBox::~SvImpLBox()
+{
+ aEditTimer.Stop();
+ StopUserEvent();
+
+ // #102891# ---------------------
+ if( pIntlWrapper )
+ delete pIntlWrapper;
+ if ( osl_decrementInterlockedCount(&s_nImageRefCount) == 0 )
+ {
+ DELETEZ(s_pDefCollapsed);
+ DELETEZ(s_pDefExpanded);
+ DELETEZ(s_pDefCollapsedHC);
+ DELETEZ(s_pDefExpandedHC);
+ }
+}
+
+// #102891# --------------------
+void SvImpLBox::UpdateIntlWrapper()
+{
+ const ::com::sun::star::lang::Locale & aNewLocale = Application::GetSettings().GetLocale();
+ if( !pIntlWrapper )
+ pIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale );
+ else
+ {
+ const ::com::sun::star::lang::Locale &aLocale = pIntlWrapper->getLocale();
+ if( aLocale.Language != aNewLocale.Language || // different Locale from the older one
+ aLocale.Country != aNewLocale.Country ||
+ aLocale.Variant != aNewLocale.Variant )
+ {
+ delete pIntlWrapper;
+ pIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale );
+ }
+ }
+}
+
+// #97680# ----------------------
+short SvImpLBox::UpdateContextBmpWidthVector( SvLBoxEntry* pEntry, short nWidth )
+{
+ DBG_ASSERT( pView->pModel, "View and Model aren't valid!" );
+
+ USHORT nDepth = pView->pModel->GetDepth( pEntry );
+ // initialize vector if necessary
+ std::vector< short >::size_type nSize = aContextBmpWidthVector.size();
+ while ( nDepth > nSize )
+ {
+ aContextBmpWidthVector.resize( nSize + 1 );
+ aContextBmpWidthVector.at( nSize ) = nWidth;
+ ++nSize;
+ }
+ if( aContextBmpWidthVector.size() == nDepth )
+ {
+ aContextBmpWidthVector.resize( nDepth + 1 );
+ aContextBmpWidthVector.at( nDepth ) = 0;
+ }
+ short nContextBmpWidth = aContextBmpWidthVector[ nDepth ];
+ if( nContextBmpWidth < nWidth )
+ {
+ aContextBmpWidthVector.at( nDepth ) = nWidth;
+ return nWidth;
+ }
+ else
+ return nContextBmpWidth;
+}
+
+void SvImpLBox::UpdateContextBmpWidthVectorFromMovedEntry( SvLBoxEntry* pEntry )
+{
+ DBG_ASSERT( pEntry, "Moved Entry is invalid!" );
+
+ SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
+ short nExpWidth = (short)pBmpItem->GetBitmap1().GetSizePixel().Width();
+ short nColWidth = (short)pBmpItem->GetBitmap2().GetSizePixel().Width();
+ short nMax = Max(nExpWidth, nColWidth);
+ UpdateContextBmpWidthVector( pEntry, nMax );
+
+ if( pEntry->HasChilds() ) // recursive call, whether expanded or not
+ {
+ SvLBoxEntry* pChild = pView->FirstChild( pEntry );
+ DBG_ASSERT( pChild, "The first child is invalid!" );
+ do
+ {
+ UpdateContextBmpWidthVectorFromMovedEntry( pChild );
+ pChild = pView->Next( pChild );
+ } while ( pChild );
+ }
+}
+
+void SvImpLBox::UpdateContextBmpWidthMax( SvLBoxEntry* pEntry )
+{
+ USHORT nDepth = pView->pModel->GetDepth( pEntry );
+ if( aContextBmpWidthVector.size() < 1 )
+ return;
+ short nWidth = aContextBmpWidthVector[ nDepth ];
+ if( nWidth != pView->nContextBmpWidthMax ) {
+ pView->nContextBmpWidthMax = nWidth;
+ nFlags |= F_IGNORE_CHANGED_TABS;
+ pView->SetTabs();
+ nFlags &= ~F_IGNORE_CHANGED_TABS;
+ }
+}
+
+void SvImpLBox::CalcCellFocusRect( SvLBoxEntry* pEntry, Rectangle& rRect )
+{
+ if ( pEntry && bIsCellFocusEnabled )
+ {
+ if ( nCurTabPos > FIRST_ENTRY_TAB )
+ {
+ SvLBoxItem* pItem = pCursor->GetItem( nCurTabPos );
+ rRect.Left() = pView->GetTab( pCursor, pItem )->GetPos();
+ }
+ if ( pCursor->ItemCount() > ( nCurTabPos + 1 ) )
+ {
+ SvLBoxItem* pNextItem = pCursor->GetItem( nCurTabPos + 1 );
+ long nRight = pView->GetTab( pCursor, pNextItem )->GetPos() - 1;
+ if ( nRight < rRect.Right() )
+ rRect.Right() = nRight;
+ }
+ }
+}
+
+void SvImpLBox::SetWindowBits( WinBits nWinStyle )
+{
+ nWinBits = nWinStyle;
+ if((nWinStyle & WB_SIMPLEMODE) && aSelEng.GetSelectionMode()==MULTIPLE_SELECTION)
+ aSelEng.AddAlways( TRUE );
+}
+
+void SvImpLBox::SetExtendedWindowBits( ExtendedWinBits _nBits )
+{
+ nExtendedWinBits = _nBits;
+}
+
+// Das Model darf hier nicht mehr angefasst werden
+void SvImpLBox::Clear()
+{
+ StopUserEvent();
+ pStartEntry = 0;
+ pAnchor = 0;
+
+ pActiveButton = 0;
+ pActiveEntry = 0;
+ pActiveTab = 0;
+
+ nMostRight = -1;
+ pMostRightEntry = 0;
+
+ // Der Cursor darf hier nicht mehr angefasst werden!
+ if( pCursor )
+ {
+ if( pView->HasFocus() )
+ pView->HideFocus();
+ pCursor = 0;
+ }
+ aVerSBar.Hide();
+ aVerSBar.SetThumbPos( 0 );
+ Range aRange( 0, 0 );
+ aVerSBar.SetRange( aRange );
+ aOutputSize = pView->Control::GetOutputSizePixel();
+ nFlags &= ~(F_VER_SBARSIZE_WITH_HBAR | F_HOR_SBARSIZE_WITH_VBAR );
+ if( pTabBar )
+ {
+ aOutputSize.Height() -= nHorSBarHeight;
+ nFlags |= F_VER_SBARSIZE_WITH_HBAR;
+ }
+ if( !pTabBar )
+ aHorSBar.Hide();
+ aHorSBar.SetThumbPos( 0 );
+ MapMode aMapMode( pView->GetMapMode());
+ aMapMode.SetOrigin( Point(0,0) );
+ pView->Control::SetMapMode( aMapMode );
+ aHorSBar.SetRange( aRange );
+ aHorSBar.SetSizePixel(Size(aOutputSize.Width(),nHorSBarHeight));
+ pView->SetClipRegion();
+ if( GetUpdateMode() )
+ pView->Invalidate( GetVisibleArea() );
+ nFlags |= F_FILLING;
+ if( !aHorSBar.IsVisible() && !aVerSBar.IsVisible() )
+ aScrBarBox.Hide();
+
+ // #97680# ---------
+ aContextBmpWidthVector.clear();
+}
+
+// *********************************************************************
+// Painten, Navigieren, Scrollen
+// *********************************************************************
+
+IMPL_LINK_INLINE_START( SvImpLBox, EndScrollHdl, ScrollBar *, EMPTYARG )
+{
+ if( nFlags & F_ENDSCROLL_SET_VIS_SIZE )
+ {
+ aVerSBar.SetVisibleSize( nNextVerVisSize );
+ nFlags &= ~F_ENDSCROLL_SET_VIS_SIZE;
+ }
+ EndScroll();
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvImpLBox, EndScrollHdl, ScrollBar *, pScrollBar )
+
+
+// Handler vertikale ScrollBar
+
+IMPL_LINK( SvImpLBox, ScrollUpDownHdl, ScrollBar *, pScrollBar )
+{
+ DBG_ASSERT(!bInVScrollHdl,"Scroll-Handler ueberholt sich!");
+ long nDelta = pScrollBar->GetDelta();
+ if( !nDelta )
+ return 0;
+
+ nFlags &= (~F_FILLING);
+
+ bInVScrollHdl = TRUE;
+
+ if( pView->IsEditingActive() )
+ {
+ pView->EndEditing( TRUE ); // Cancel
+ pView->Update();
+ }
+ BeginScroll();
+
+ if( nDelta > 0 )
+ {
+ if( nDelta == 1 )
+ CursorDown();
+ else
+ PageDown( (USHORT) nDelta );
+ }
+ else
+ {
+ nDelta *= (-1);
+ if( nDelta == 1 )
+ CursorUp();
+ else
+ PageUp( (USHORT) nDelta );
+ }
+ bInVScrollHdl = FALSE;
+ return 0;
+}
+
+
+void SvImpLBox::CursorDown()
+{
+ SvLBoxEntry* pNextFirstToDraw = (SvLBoxEntry*)(pView->NextVisible( pStartEntry));
+ if( pNextFirstToDraw )
+ {
+ nFlags &= (~F_FILLING);
+ pView->NotifyScrolling( -1 );
+ ShowCursor( FALSE );
+ pView->Update();
+ pStartEntry = pNextFirstToDraw;
+ Rectangle aArea( GetVisibleArea() );
+ pView->Scroll( 0, -(pView->GetEntryHeight()), aArea, SCROLL_NOCHILDREN );
+ pView->Update();
+ ShowCursor( TRUE );
+ pView->NotifyScrolled();
+ }
+}
+
+void SvImpLBox::CursorUp()
+{
+ SvLBoxEntry* pPrevFirstToDraw = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry));
+ if( pPrevFirstToDraw )
+ {
+ nFlags &= (~F_FILLING);
+ long nEntryHeight = pView->GetEntryHeight();
+ pView->NotifyScrolling( 1 );
+ ShowCursor( FALSE );
+ pView->Update();
+ pStartEntry = pPrevFirstToDraw;
+ Rectangle aArea( GetVisibleArea() );
+ aArea.Bottom() -= nEntryHeight;
+ pView->Scroll( 0, nEntryHeight, aArea, SCROLL_NOCHILDREN );
+ pView->Update();
+ ShowCursor( TRUE );
+ pView->NotifyScrolled();
+ }
+}
+
+void SvImpLBox::PageDown( USHORT nDelta )
+{
+ USHORT nRealDelta = nDelta;
+
+ if( !nDelta )
+ return;
+
+ SvLBoxEntry* pNext;
+ pNext = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nRealDelta ));
+ if( (ULONG)pNext == (ULONG)pStartEntry )
+ return;
+
+ ShowCursor( FALSE );
+
+ nFlags &= (~F_FILLING);
+ pView->Update();
+ pStartEntry = pNext;
+
+ if( nRealDelta >= nVisibleCount )
+ {
+ pView->Invalidate( GetVisibleArea() );
+ pView->Update();
+ }
+ else
+ {
+ long nScroll = nRealDelta * (-1);
+ pView->NotifyScrolling( nScroll );
+ Rectangle aArea( GetVisibleArea() );
+ nScroll = pView->GetEntryHeight()*nRealDelta;
+ nScroll = -nScroll;
+ pView->Update();
+ pView->Scroll( 0, nScroll, aArea, SCROLL_NOCHILDREN );
+ pView->Update();
+ pView->NotifyScrolled();
+ }
+
+ ShowCursor( TRUE );
+}
+
+void SvImpLBox::PageUp( USHORT nDelta )
+{
+ USHORT nRealDelta = nDelta;
+ if( !nDelta )
+ return;
+
+ SvLBoxEntry* pPrev = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry, nRealDelta ));
+ if( (ULONG)pPrev == (ULONG)pStartEntry )
+ return;
+
+ nFlags &= (~F_FILLING);
+ ShowCursor( FALSE );
+
+ pView->Update();
+ pStartEntry = pPrev;
+ if( nRealDelta >= nVisibleCount )
+ {
+ pView->Invalidate( GetVisibleArea() );
+ pView->Update();
+ }
+ else
+ {
+ long nEntryHeight = pView->GetEntryHeight();
+ pView->NotifyScrolling( (long)nRealDelta );
+ Rectangle aArea( GetVisibleArea() );
+ pView->Update();
+ pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, SCROLL_NOCHILDREN );
+ pView->Update();
+ pView->NotifyScrolled();
+ }
+
+ ShowCursor( TRUE );
+}
+
+void SvImpLBox::KeyUp( BOOL bPageUp, BOOL bNotifyScroll )
+{
+ if( !aVerSBar.IsVisible() )
+ return;
+
+ long nDelta;
+ if( bPageUp )
+ nDelta = aVerSBar.GetPageSize();
+ else
+ nDelta = 1;
+
+ long nThumbPos = aVerSBar.GetThumbPos();
+
+ if( nThumbPos < nDelta )
+ nDelta = nThumbPos;
+
+ if( nDelta <= 0 )
+ return;
+
+ nFlags &= (~F_FILLING);
+ if( bNotifyScroll )
+ BeginScroll();
+
+ aVerSBar.SetThumbPos( nThumbPos - nDelta );
+ if( bPageUp )
+ PageUp( (short)nDelta );
+ else
+ CursorUp();
+
+ if( bNotifyScroll )
+ EndScroll();
+}
+
+
+void SvImpLBox::KeyDown( BOOL bPageDown, BOOL bNotifyScroll )
+{
+ if( !aVerSBar.IsVisible() )
+ return;
+
+ long nDelta;
+ if( bPageDown )
+ nDelta = aVerSBar.GetPageSize();
+ else
+ nDelta = 1;
+
+ long nThumbPos = aVerSBar.GetThumbPos();
+ long nVisibleSize = aVerSBar.GetVisibleSize();
+ long nRange = aVerSBar.GetRange().Len();
+
+ long nTmp = nThumbPos+nVisibleSize;
+ while( (nDelta > 0) && (nTmp+nDelta) >= nRange )
+ nDelta--;
+
+ if( nDelta <= 0 )
+ return;
+
+ nFlags &= (~F_FILLING);
+ if( bNotifyScroll )
+ BeginScroll();
+
+ aVerSBar.SetThumbPos( nThumbPos+nDelta );
+ if( bPageDown )
+ PageDown( (short)nDelta );
+ else
+ CursorDown();
+
+ if( bNotifyScroll )
+ EndScroll();
+}
+
+
+
+void SvImpLBox::InvalidateEntriesFrom( long nY ) const
+{
+ if( !(nFlags & F_IN_PAINT ))
+ {
+ Rectangle aRect( GetVisibleArea() );
+ aRect.Top() = nY;
+ pView->Invalidate( aRect );
+ }
+}
+
+void SvImpLBox::InvalidateEntry( long nY ) const
+{
+ if( !(nFlags & F_IN_PAINT ))
+ {
+ Rectangle aRect( GetVisibleArea() );
+ long nMaxBottom = aRect.Bottom();
+ aRect.Top() = nY;
+ aRect.Bottom() = nY; aRect.Bottom() += pView->GetEntryHeight();
+ if( aRect.Top() > nMaxBottom )
+ return;
+ if( aRect.Bottom() > nMaxBottom )
+ aRect.Bottom() = nMaxBottom;
+ pView->Invalidate( aRect );
+ }
+}
+
+void SvImpLBox::InvalidateEntry( SvLBoxEntry* pEntry )
+{
+ if( GetUpdateMode() )
+ {
+ long nPrev = nMostRight;
+ SetMostRight( pEntry );
+ if( nPrev < nMostRight )
+ ShowVerSBar();
+ }
+ if( !(nFlags & F_IN_PAINT ))
+ {
+ BOOL bHasFocusRect = FALSE;
+ if( pEntry==pCursor && pView->HasFocus() )
+ {
+ bHasFocusRect = TRUE;
+ ShowCursor( FALSE );
+ }
+ InvalidateEntry( GetEntryLine( pEntry ) );
+ if( bHasFocusRect )
+ ShowCursor( TRUE );
+ }
+}
+
+
+void SvImpLBox::RecalcFocusRect()
+{
+ if( pView->HasFocus() && pCursor )
+ {
+ pView->HideFocus();
+ long nY = GetEntryLine( pCursor );
+ Rectangle aRect = pView->GetFocusRect( pCursor, nY );
+ CalcCellFocusRect( pCursor, aRect );
+ Region aOldClip( pView->GetClipRegion());
+ Region aClipRegion( GetClipRegionRect() );
+ pView->SetClipRegion( aClipRegion );
+ pView->ShowFocus( aRect );
+ pView->SetClipRegion( aOldClip );
+ }
+}
+
+//
+// Setzt Cursor. Passt bei SingleSelection die Selektion an
+//
+
+void SvImpLBox::SetCursor( SvLBoxEntry* pEntry, BOOL bForceNoSelect )
+{
+ SvViewDataEntry* pViewDataNewCur = 0;
+ if( pEntry )
+ pViewDataNewCur= pView->GetViewDataEntry(pEntry);
+ if( pEntry &&
+ pEntry == pCursor &&
+ pViewDataNewCur->HasFocus() &&
+ pViewDataNewCur->IsSelected())
+ {
+ return;
+ }
+
+ // if this cursor is not selectable, find first visible that is and use it
+ while( pEntry && pViewDataNewCur && !pViewDataNewCur->IsSelectable() )
+ {
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ pViewDataNewCur = pEntry ? pView->GetViewDataEntry(pEntry) : 0;
+ }
+
+ SvLBoxEntry* pOldCursor = pCursor;
+ if( pCursor && pEntry != pCursor )
+ {
+ pView->SetEntryFocus( pCursor, FALSE );
+ if( bSimpleTravel )
+ pView->Select( pCursor, FALSE );
+ pView->HideFocus();
+ }
+ pCursor = pEntry;
+ if( pCursor )
+ {
+ pViewDataNewCur->SetFocus( TRUE );
+ if(!bForceNoSelect && bSimpleTravel && !(nFlags & F_DESEL_ALL) && GetUpdateMode())
+ {
+ pView->Select( pCursor, TRUE );
+ }
+ // Mehrfachselektion: Im Cursor-Move selektieren, wenn
+ // nicht im Add-Mode (Ctrl-F8)
+ else if( GetUpdateMode() &&
+ pView->GetSelectionMode() == MULTIPLE_SELECTION &&
+ !(nFlags & F_DESEL_ALL) && !aSelEng.IsAddMode() &&
+ !bForceNoSelect )
+ {
+ pView->Select( pCursor, TRUE );
+ }
+ else
+ {
+ ShowCursor( TRUE );
+ }
+
+ if( pAnchor )
+ {
+ DBG_ASSERT(aSelEng.GetSelectionMode() != SINGLE_SELECTION,"Mode?");
+ SetAnchorSelection( pOldCursor, pCursor );
+ }
+ }
+ nFlags &= (~F_DESEL_ALL);
+}
+
+void SvImpLBox::ShowCursor( BOOL bShow )
+{
+ if( !bShow || !pCursor || !pView->HasFocus() )
+ {
+ Region aOldClip( pView->GetClipRegion());
+ Region aClipRegion( GetClipRegionRect() );
+ pView->SetClipRegion( aClipRegion );
+ pView->HideFocus();
+ pView->SetClipRegion( aOldClip );
+ }
+ else
+ {
+ long nY = GetEntryLine( pCursor );
+ Rectangle aRect = pView->GetFocusRect( pCursor, nY );
+ CalcCellFocusRect( pCursor, aRect );
+ Region aOldClip( pView->GetClipRegion());
+ Region aClipRegion( GetClipRegionRect() );
+ pView->SetClipRegion( aClipRegion );
+ pView->ShowFocus( aRect );
+ pView->SetClipRegion( aOldClip );
+ }
+}
+
+
+
+void SvImpLBox::UpdateAll( BOOL bInvalidateCompleteView,
+ BOOL bUpdateVerScrollBar )
+{
+ if( bUpdateVerScrollBar )
+ FindMostRight(0);
+ aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) );
+ SyncVerThumb();
+ FillView();
+ ShowVerSBar();
+ if( bSimpleTravel && pCursor && pView->HasFocus() )
+ pView->Select( pCursor, TRUE );
+ ShowCursor( TRUE );
+ if( bInvalidateCompleteView )
+ pView->Invalidate();
+ else
+ pView->Invalidate( GetVisibleArea() );
+}
+
+IMPL_LINK_INLINE_START( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar )
+{
+ long nDelta = pScrollBar->GetDelta();
+ if( nDelta )
+ {
+ if( pView->IsEditingActive() )
+ {
+ pView->EndEditing( TRUE ); // Cancel
+ pView->Update();
+ }
+ pView->nFocusWidth = -1;
+ KeyLeftRight( nDelta );
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar )
+
+void SvImpLBox::KeyLeftRight( long nDelta )
+{
+ if( !(nFlags & F_IN_RESIZE) )
+ pView->Update();
+ BeginScroll();
+ nFlags &= (~F_FILLING);
+ pView->NotifyScrolling( 0 ); // 0 == horizontales Scrolling
+ ShowCursor( FALSE );
+
+ // neuen Origin berechnen
+ long nPos = aHorSBar.GetThumbPos();
+ Point aOrigin( -nPos, 0 );
+
+ MapMode aMapMode( pView->GetMapMode() );
+ aMapMode.SetOrigin( aOrigin );
+ pView->SetMapMode( aMapMode );
+
+ if( !(nFlags & F_IN_RESIZE) )
+ {
+ Rectangle aRect( GetVisibleArea() );
+ pView->Scroll( -nDelta, 0, aRect, SCROLL_NOCHILDREN );
+ }
+ else
+ pView->Invalidate();
+ RecalcFocusRect();
+ ShowCursor( TRUE );
+ pView->NotifyScrolled();
+}
+
+
+// gibt letzten Eintrag zurueck, wenn Position unter
+// dem letzten Eintrag ist
+SvLBoxEntry* SvImpLBox::GetClickedEntry( const Point& rPoint ) const
+{
+ DBG_ASSERT( pView->GetModel(), "SvImpLBox::GetClickedEntry: how can this ever happen? Please tell me (frank.schoenheit@sun.com) how to reproduce!" );
+ if ( !pView->GetModel() )
+ // this is quite impossible. Nevertheless, stack traces from the crash reporter
+ // suggest it isn't. Okay, make it safe, and wait for somebody to reproduce it
+ // reliably :-\ ....
+ // #122359# / 2005-05-23 / frank.schoenheit@sun.com
+ return NULL;
+ if( pView->GetEntryCount() == 0 || !pStartEntry || !pView->GetEntryHeight())
+ return 0;
+
+ USHORT nClickedEntry = (USHORT)(rPoint.Y() / pView->GetEntryHeight() );
+ USHORT nTemp = nClickedEntry;
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nTemp ));
+ return pEntry;
+}
+
+//
+// prueft, ob der Eintrag "richtig" getroffen wurde
+// (Focusrect+ ContextBitmap bei TreeListBox)
+//
+BOOL SvImpLBox::EntryReallyHit(SvLBoxEntry* pEntry,const Point& rPosPixel,long nLine)
+{
+ BOOL bRet;
+ // bei "besonderen" Entries (mit CheckButtons usw.) sind wir
+ // nicht so pingelig
+ if( pEntry->ItemCount() >= 3 )
+ return TRUE;
+
+ Rectangle aRect( pView->GetFocusRect( pEntry, nLine ));
+ aRect.Right() = GetOutputSize().Width() - pView->GetMapMode().GetOrigin().X();
+ if( pView->IsA() == SV_LISTBOX_ID_TREEBOX )
+ {
+ SvLBoxContextBmp* pBmp = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ aRect.Left() -= pBmp->GetSize(pView,pEntry).Width();
+ aRect.Left() -= 4; // etwas Speilraum lassen
+ }
+ Point aPos( rPosPixel );
+ aPos -= pView->GetMapMode().GetOrigin();
+ if( aRect.IsInside( aPos ) )
+ bRet = TRUE;
+ else
+ bRet = FALSE;
+ return bRet;
+}
+
+
+// gibt 0 zurueck, wenn Position unter dem letzten Eintrag ist
+SvLBoxEntry* SvImpLBox::GetEntry( const Point& rPoint ) const
+{
+ if( (pView->GetEntryCount() == 0) || !pStartEntry ||
+ (rPoint.Y() > aOutputSize.Height())
+ || !pView->GetEntryHeight())
+ return 0;
+
+ USHORT nClickedEntry = (USHORT)(rPoint.Y() / pView->GetEntryHeight() );
+ USHORT nTemp = nClickedEntry;
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nTemp ));
+ if( nTemp != nClickedEntry )
+ pEntry = 0;
+ return pEntry;
+}
+
+
+SvLBoxEntry* SvImpLBox::MakePointVisible(const Point& rPoint,BOOL bNotifyScroll)
+{
+ if( !pCursor )
+ return 0;
+ long nY = rPoint.Y();
+ SvLBoxEntry* pEntry = 0;
+ long nMax = aOutputSize.Height();
+ if( nY < 0 || nY >= nMax ) // aOutputSize.Height() )
+ {
+ if( nY < 0 )
+ pEntry = (SvLBoxEntry*)(pView->PrevVisible( pCursor ));
+ else
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pCursor ));
+
+ if( pEntry && pEntry != pCursor )
+ pView->SetEntryFocus( pCursor, FALSE );
+
+ if( nY < 0 )
+ KeyUp( FALSE, bNotifyScroll );
+ else
+ KeyDown( FALSE, bNotifyScroll );
+ }
+ else
+ {
+ pEntry = GetClickedEntry( rPoint );
+ if( !pEntry )
+ {
+ USHORT nSteps = 0xFFFF;
+ // LastVisible ist noch nicht implementiert!
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nSteps ));
+ }
+ if( pEntry )
+ {
+ if( pEntry != pCursor &&
+ aSelEng.GetSelectionMode() == SINGLE_SELECTION
+ )
+ pView->Select( pCursor, FALSE );
+ }
+ }
+ return pEntry;
+}
+
+Rectangle SvImpLBox::GetClipRegionRect() const
+{
+ Point aOrigin( pView->GetMapMode().GetOrigin() );
+ aOrigin.X() *= -1; // Umrechnung Dokumentkoord.
+ Rectangle aClipRect( aOrigin, aOutputSize );
+ aClipRect.Bottom()++;
+ return aClipRect;
+}
+
+
+void SvImpLBox::Paint( const Rectangle& rRect )
+{
+ if( !pView->GetVisibleCount() )
+ return;
+
+ nFlags |= F_IN_PAINT;
+
+ if( nFlags & F_FILLING )
+ {
+ SvLBoxEntry* pFirst = pView->First();
+ if( pFirst != pStartEntry )
+ {
+ ShowCursor( FALSE );
+ pStartEntry = pView->First();
+ aVerSBar.SetThumbPos( 0 );
+ StopUserEvent();
+ ShowCursor( TRUE );
+ nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent),(void*)1);
+ return;
+ }
+ }
+
+ if( !pStartEntry )
+ {
+ pStartEntry = pView->First();
+ }
+
+#ifdef XX_OV
+ ULONG nXAbsPos = (USHORT)pTree->GetAbsPos( pStartEntry );
+ ULONG nXVisPos = pView->GetVisiblePos( pStartEntry );
+ SvLBoxString* pXStr = (SvLBoxString*)pStartEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING);
+#endif
+
+
+
+ if( nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID )
+ SetNodeBmpTabDistance();
+
+ long nRectHeight = rRect.GetHeight();
+ long nEntryHeight = pView->GetEntryHeight();
+
+ // Bereich der zu zeichnenden Entries berechnen
+ USHORT nStartLine = (USHORT)( rRect.Top() / nEntryHeight );
+ USHORT nCount = (USHORT)( nRectHeight / nEntryHeight );
+ nCount += 2; // keine Zeile vergessen
+
+ long nY = nStartLine * nEntryHeight;
+ SvLBoxEntry* pEntry = pStartEntry;
+ while( nStartLine && pEntry )
+ {
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ nStartLine--;
+ }
+
+ Region aClipRegion( GetClipRegionRect() );
+
+ // erst die Linien Zeichnen, dann clippen!
+ pView->SetClipRegion();
+ if( nWinBits & ( WB_HASLINES | WB_HASLINESATROOT ) )
+ DrawNet();
+
+ pView->SetClipRegion( aClipRegion );
+
+ for( USHORT n=0; n< nCount && pEntry; n++ )
+ {
+ /*long nMaxRight=*/
+ pView->PaintEntry1( pEntry, nY, 0xffff, TRUE );
+ nY += nEntryHeight;
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+
+ if ( !pCursor && ( ( nExtendedWinBits & EWB_NO_AUTO_CURENTRY ) == 0 ) )
+ {
+ // do not select if multiselection or explicit set
+ BOOL bNotSelect = ( aSelEng.GetSelectionMode() == MULTIPLE_SELECTION )
+ || ( ( nWinBits & WB_NOINITIALSELECTION ) == WB_NOINITIALSELECTION );
+ SetCursor( pStartEntry, bNotSelect );
+ }
+
+ nFlags &= (~F_DESEL_ALL);
+ pView->SetClipRegion();
+ Rectangle aRect;
+ if( !(nFlags & F_PAINTED) )
+ {
+ nFlags |= F_PAINTED;
+ RepaintScrollBars();
+ }
+ nFlags &= (~F_IN_PAINT);
+}
+
+void SvImpLBox::MakeVisible( SvLBoxEntry* pEntry, BOOL bMoveToTop )
+{
+ if( !pEntry )
+ return;
+
+ BOOL bInView = IsEntryInView( pEntry );
+
+ if( bInView && (!bMoveToTop || pStartEntry == pEntry) )
+ return; // ist schon sichtbar
+
+ if( pStartEntry || (nWinBits & WB_FORCE_MAKEVISIBLE) )
+ nFlags &= (~F_FILLING);
+ if( !bInView )
+ {
+ if( !pView->IsEntryVisible(pEntry) ) // Parent(s) zugeklappt ?
+ {
+ SvLBoxEntry* pParent = pView->GetParent( pEntry );
+ while( pParent )
+ {
+ if( !pView->IsExpanded( pParent ) )
+ {
+ #ifdef DBG_UTIL
+ BOOL bRet =
+ #endif
+ pView->Expand( pParent );
+ DBG_ASSERT(bRet,"Not expanded!");
+ }
+ pParent = pView->GetParent( pParent );
+ }
+ // Passen Childs der Parents in View oder muessen wir scrollen ?
+ if( IsEntryInView( pEntry ) && !bMoveToTop )
+ return; // Scrollen nicht noetig -> tschuess
+ }
+ }
+
+ pStartEntry = pEntry;
+ ShowCursor( FALSE );
+ FillView();
+ aVerSBar.SetThumbPos( (long)(pView->GetVisiblePos( pStartEntry )) );
+ ShowCursor( TRUE );
+ pView->Invalidate();
+}
+
+
+void SvImpLBox::RepaintSelectionItems()
+{
+ if( !pView->GetVisibleCount() )
+ return;
+
+ if( !pStartEntry )
+ pStartEntry = pView->First();
+
+ if( nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID )
+ SetNodeBmpTabDistance();
+
+ ShowCursor( FALSE );
+
+ long nEntryHeight = pView->GetEntryHeight();
+
+ ULONG nCount = nVisibleCount;
+ long nY = 0;
+ SvLBoxEntry* pEntry = pStartEntry;
+ for( ULONG n=0; n< nCount && pEntry; n++ )
+ {
+ pView->PaintEntry1( pEntry, nY, 0xffff ); //wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
+ nY += nEntryHeight;
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+
+ ShowCursor( TRUE );
+}
+
+
+void SvImpLBox::DrawNet()
+{
+ if( pView->GetVisibleCount() < 2 && !pStartEntry->HasChildsOnDemand() &&
+ !pStartEntry->HasChilds() )
+ return;
+
+ //for platforms who don't have nets, DrawNativeControl does nothing and return true
+ //so that SvImpLBox::DrawNet() doesn't draw anything too
+ if(pView->IsNativeControlSupported( CTRL_LISTNET, PART_ENTIRE_CONTROL)) {
+ ImplControlValue aControlValue;
+ Point aTemp(0,0); // temporary needed for g++ 3.3.5
+ Rectangle aCtrlRegion( aTemp, Size( 0, 0 ) );
+ ControlState nState = CTRL_STATE_ENABLED;
+ if( pView->DrawNativeControl( CTRL_LISTNET, PART_ENTIRE_CONTROL,
+ aCtrlRegion, nState, aControlValue, rtl::OUString() ) )
+ {
+ return;
+ }
+
+ }
+
+ long nEntryHeight = pView->GetEntryHeight();
+ long nEntryHeightDIV2 = nEntryHeight / 2;
+ if( nEntryHeightDIV2 && !(nEntryHeight & 0x0001))
+ nEntryHeightDIV2--;
+
+ SvLBoxEntry* pChild;
+ SvLBoxEntry* pEntry = pStartEntry;
+
+ SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab();
+ while( pTree->GetDepth( pEntry ) > 0 )
+ pEntry = pView->GetParent( pEntry );
+ USHORT nOffs = (USHORT)(pView->GetVisiblePos( pStartEntry ) -
+ pView->GetVisiblePos( pEntry ));
+ long nY = 0;
+ nY -= ( nOffs * nEntryHeight );
+
+ DBG_ASSERT(pFirstDynamicTab,"No Tree!");
+
+ Color aOldLineColor = pView->GetLineColor();
+ const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings();
+ Color aCol= rStyleSettings.GetFaceColor();
+
+ if( aCol.IsRGBEqual( pView->GetBackground().GetColor()) )
+ aCol = rStyleSettings.GetShadowColor();
+ pView->SetLineColor( aCol );
+ Point aPos1, aPos2;
+ USHORT nDistance;
+ ULONG nMax = nVisibleCount + nOffs + 1;
+
+ const Image& rExpandedNodeBitmap = GetExpandedNodeBmp();
+
+ for( ULONG n=0; n< nMax && pEntry; n++ )
+ {
+ if( pView->IsExpanded(pEntry) )
+ {
+ aPos1.X() = pView->GetTabPos(pEntry, pFirstDynamicTab);
+ // wenn keine ContextBitmap, dann etwas nach rechts
+ // unter den ersten Text (Node.Bmp ebenfalls
+ if( !pView->nContextBmpWidthMax )
+ aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2;
+
+ aPos1.Y() = nY;
+ aPos1.Y() += nEntryHeightDIV2;
+
+ pChild = pView->FirstChild( pEntry );
+ DBG_ASSERT(pChild,"Child?");
+ pChild = pTree->LastSibling( pChild );
+ nDistance = (USHORT)(pView->GetVisiblePos(pChild) -
+ pView->GetVisiblePos(pEntry));
+ aPos2 = aPos1;
+ aPos2.Y() += nDistance * nEntryHeight;
+ pView->DrawLine( aPos1, aPos2 );
+ }
+ // Sichtbar im Control ?
+ if( n>= nOffs && ((nWinBits & WB_HASLINESATROOT) || !pTree->IsAtRootDepth(pEntry)))
+ {
+ // kann aPos1 recyclet werden ?
+ if( !pView->IsExpanded(pEntry) )
+ {
+ // njet
+ aPos1.X() = pView->GetTabPos(pEntry, pFirstDynamicTab);
+ // wenn keine ContextBitmap, dann etwas nach rechts
+ // unter den ersten Text (Node.Bmp ebenfalls
+ if( !pView->nContextBmpWidthMax )
+ aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2;
+ aPos1.Y() = nY;
+ aPos1.Y() += nEntryHeightDIV2;
+ aPos2.X() = aPos1.X();
+ }
+ aPos2.Y() = aPos1.Y();
+ aPos2.X() -= pView->GetIndent();
+ pView->DrawLine( aPos1, aPos2 );
+ }
+ nY += nEntryHeight;
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( nWinBits & WB_HASLINESATROOT )
+ {
+ pEntry = pView->First();
+ aPos1.X() = pView->GetTabPos( pEntry, pFirstDynamicTab);
+ // wenn keine ContextBitmap, dann etwas nach rechts
+ // unter den ersten Text (Node.Bmp ebenfalls
+ if( !pView->nContextBmpWidthMax )
+ aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2;
+ aPos1.X() -= pView->GetIndent();
+ aPos1.Y() = GetEntryLine( pEntry );
+ aPos1.Y() += nEntryHeightDIV2;
+ pChild = pTree->LastSibling( pEntry );
+ aPos2.X() = aPos1.X();
+ aPos2.Y() = GetEntryLine( pChild );
+ aPos2.Y() += nEntryHeightDIV2;
+ pView->DrawLine( aPos1, aPos2 );
+ }
+ pView->SetLineColor( aOldLineColor );
+}
+
+
+static long GetOptSize( TabBar* pTabBar )
+{
+ return pTabBar->CalcWindowSizePixel().Width();
+}
+
+void SvImpLBox::PositionScrollBars( Size& rSize, USHORT nMask )
+{
+ long nOverlap = 0;
+
+ Size aVerSize( nVerSBarWidth, rSize.Height() );
+ Size aHorSize( rSize.Width(), nHorSBarHeight );
+ long nTabBarWidth = 0;
+ if( pTabBar )
+ {
+ nTabBarWidth = GetOptSize( pTabBar );
+ long nMaxWidth = (rSize.Width() * 700) / 1000;
+ if( nTabBarWidth > nMaxWidth )
+ {
+ nTabBarWidth = nMaxWidth;
+ pTabBar->SetStyle( pTabBar->GetStyle() | WB_MINSCROLL );
+ }
+ else
+ {
+ WinBits nStyle = pTabBar->GetStyle();
+ nStyle &= ~(WB_MINSCROLL);
+ pTabBar->SetStyle( nStyle );
+ }
+ aHorSize.Width() -= nTabBarWidth;
+ Size aTabSize( pTabBar->GetSizePixel() );
+ aTabSize.Width() = nTabBarWidth;
+ pTabBar->SetSizePixel( aTabSize );
+ }
+ if( nMask & 0x0001 )
+ aHorSize.Width() -= nVerSBarWidth;
+ if( nMask & 0x0002 )
+ aVerSize.Height() -= nHorSBarHeight;
+
+ aVerSize.Height() += 2 * nOverlap;
+ Point aVerPos( rSize.Width() - aVerSize.Width() + nOverlap, -nOverlap );
+ aVerSBar.SetPosSizePixel( aVerPos, aVerSize );
+
+ aHorSize.Width() += 2 * nOverlap;
+ Point aHorPos( -nOverlap, rSize.Height() - aHorSize.Height() + nOverlap );
+ if( pTabBar )
+ pTabBar->SetPosPixel( aHorPos );
+ aHorPos.X() += nTabBarWidth;
+ aHorSBar.SetPosSizePixel( aHorPos, aHorSize );
+
+ if( nMask & 0x0001 )
+ rSize.Width() = aVerPos.X();
+ if( nMask & 0x0002 )
+ rSize.Height() = aHorPos.Y();
+ if( pTabBar )
+ pTabBar->Show();
+
+ if( (nMask & (0x0001|0x0002)) == (0x0001|0x0002) )
+ aScrBarBox.Show();
+ else
+ aScrBarBox.Hide();
+
+}
+
+// nResult: Bit0 == VerSBar Bit1 == HorSBar
+USHORT SvImpLBox::AdjustScrollBars( Size& rSize )
+{
+ long nEntryHeight = pView->GetEntryHeight();
+ if( !nEntryHeight )
+ return 0;
+
+ USHORT nResult = 0;
+
+ Size aOSize( pView->Control::GetOutputSizePixel() );
+
+ BOOL bVerSBar = ( pView->nWindowStyle & WB_VSCROLL ) != 0;
+ BOOL bHorBar = FALSE;
+ long nMaxRight = aOSize.Width(); //GetOutputSize().Width();
+ Point aOrigin( pView->GetMapMode().GetOrigin() );
+ aOrigin.X() *= -1;
+ nMaxRight += aOrigin.X() - 1;
+ long nVis = nMostRight - aOrigin.X();
+ if( pTabBar || (
+ (pView->nWindowStyle & WB_HSCROLL) &&
+ (nVis < nMostRight || nMaxRight < nMostRight) ))
+ bHorBar = TRUE;
+
+ // Anzahl aller nicht eingeklappten Eintraege
+ ULONG nTotalCount = pView->GetVisibleCount();
+
+ // Anzahl in der View sichtbarer Eintraege
+ nVisibleCount = aOSize.Height() / nEntryHeight;
+
+ // muessen wir eine vertikale Scrollbar einblenden?
+ if( bVerSBar || nTotalCount > nVisibleCount )
+ {
+ nResult = 1;
+ nFlags |= F_HOR_SBARSIZE_WITH_VBAR;
+ nMaxRight -= nVerSBarWidth;
+ if( !bHorBar )
+ {
+ if( (pView->nWindowStyle & WB_HSCROLL) &&
+ (nVis < nMostRight || nMaxRight < nMostRight) )
+ bHorBar = TRUE;
+ }
+ }
+
+ // muessen wir eine horizontale Scrollbar einblenden?
+ if( bHorBar )
+ {
+ nResult |= 0x0002;
+ // die Anzahl der in der View sichtbaren Eintraege
+ // muss neu berechnet werden, da die horizontale
+ // ScrollBar eingeblendet wird
+ nVisibleCount = (aOSize.Height() - nHorSBarHeight) / nEntryHeight;
+ // eventuell brauchen wir jetzt doch eine vertikale ScrollBar
+ if( !(nResult & 0x0001) &&
+ ((nTotalCount > nVisibleCount) || bVerSBar) )
+ {
+ nResult = 3;
+ nFlags |= F_VER_SBARSIZE_WITH_HBAR;
+ }
+ }
+
+ PositionScrollBars( aOSize, nResult );
+
+ // Range, VisibleRange usw. anpassen
+
+ // Output-Size aktualisieren, falls wir scrollen muessen
+ Rectangle aRect;
+ aRect.SetSize( aOSize );
+ aSelEng.SetVisibleArea( aRect );
+
+ // Vertikale ScrollBar
+ long nTemp = (long)nVisibleCount;
+ nTemp--;
+ if( nTemp != aVerSBar.GetVisibleSize() )
+ {
+ if( !bInVScrollHdl )
+ {
+ aVerSBar.SetPageSize( nTemp - 1 );
+ aVerSBar.SetVisibleSize( nTemp );
+ }
+ else
+ {
+ nFlags |= F_ENDSCROLL_SET_VIS_SIZE;
+ nNextVerVisSize = nTemp;
+ }
+ }
+
+ // Horizontale ScrollBar
+ nTemp = aHorSBar.GetThumbPos();
+ aHorSBar.SetVisibleSize( aOSize.Width() );
+ long nNewThumbPos = aHorSBar.GetThumbPos();
+ Range aRange( aHorSBar.GetRange() );
+ if( aRange.Max() < nMostRight+25 )
+ {
+ aRange.Max() = nMostRight+25;
+ aHorSBar.SetRange( aRange );
+ }
+
+ if( nTemp != nNewThumbPos )
+ {
+ nTemp = nNewThumbPos - nTemp;
+ if( pView->IsEditingActive() )
+ {
+ pView->EndEditing( TRUE ); // Cancel
+ pView->Update();
+ }
+ pView->nFocusWidth = -1;
+ KeyLeftRight( nTemp );
+ }
+
+ if( nResult & 0x0001 )
+ aVerSBar.Show();
+ else
+ aVerSBar.Hide();
+
+ if( nResult & 0x0002 )
+ aHorSBar.Show();
+ else
+ {
+ if( !pTabBar )
+ aHorSBar.Hide();
+ }
+ rSize = aOSize;
+ return nResult;
+}
+
+void SvImpLBox::InitScrollBarBox()
+{
+ aScrBarBox.SetSizePixel( Size(nVerSBarWidth, nHorSBarHeight) );
+ Size aSize( pView->Control::GetOutputSizePixel() );
+ aScrBarBox.SetPosPixel( Point(aSize.Width()-nVerSBarWidth, aSize.Height()-nHorSBarHeight));
+}
+
+void SvImpLBox::Resize()
+{
+ Size aSize( pView->Control::GetOutputSizePixel());
+ if( aSize.Width() <= 0 || aSize.Height() <= 0 )
+ return;
+ nFlags |= F_IN_RESIZE;
+ InitScrollBarBox();
+
+ if( pView->GetEntryHeight())
+ {
+ AdjustScrollBars( aOutputSize );
+ FillView();
+ }
+ // !!!HACK, da in Floating- & Docking-Windows nach Resizes
+ // die Scrollbars nicht richtig, bzw. ueberhaupt nicht gezeichnet werden
+ if( aHorSBar.IsVisible())
+ aHorSBar.Invalidate();
+ if( aVerSBar.IsVisible())
+ aVerSBar.Invalidate();
+ nFlags &= (~(F_IN_RESIZE | F_PAINTED));
+}
+
+void SvImpLBox::FillView()
+{
+ if( !pStartEntry )
+ {
+ USHORT nVisibleViewCount = (USHORT)(pView->GetVisibleCount());
+ USHORT nTempThumb = (USHORT)aVerSBar.GetThumbPos();
+ if( nTempThumb >= nVisibleViewCount )
+ nTempThumb = nVisibleViewCount - 1;
+ pStartEntry = (SvLBoxEntry*)(pView->GetEntryAtVisPos(nTempThumb));
+ }
+ if( pStartEntry )
+ {
+ USHORT nLast = (USHORT)(pView->GetVisiblePos( (SvLBoxEntry*)(pView->LastVisible())));
+ USHORT nThumb = (USHORT)(pView->GetVisiblePos( pStartEntry ));
+ USHORT nCurDispEntries = nLast-nThumb+1;
+ if( nCurDispEntries < nVisibleCount )
+ {
+ ShowCursor( FALSE );
+ // Fenster fuellen, indem der Thumb schrittweise
+ // nach oben bewegt wird
+ BOOL bFound = FALSE;
+ SvLBoxEntry* pTemp = pStartEntry;
+ while( nCurDispEntries < nVisibleCount && pTemp )
+ {
+ pTemp = (SvLBoxEntry*)(pView->PrevVisible(pStartEntry));
+ if( pTemp )
+ {
+ nThumb--;
+ pStartEntry = pTemp;
+ nCurDispEntries++;
+ bFound = TRUE;
+ }
+ }
+ if( bFound )
+ {
+ aVerSBar.SetThumbPos( nThumb );
+ ShowCursor( TRUE ); // Focusrect neu berechnen
+ pView->Invalidate();
+ }
+ }
+ }
+}
+
+
+
+
+void SvImpLBox::ShowVerSBar()
+{
+ BOOL bVerBar = ( pView->nWindowStyle & WB_VSCROLL ) != 0;
+ ULONG nVis = 0;
+ if( !bVerBar )
+ nVis = pView->GetVisibleCount();
+ if( bVerBar || (nVisibleCount && nVis > (ULONG)(nVisibleCount-1)) )
+ {
+ if( !aVerSBar.IsVisible() )
+ {
+ pView->nFocusWidth = -1;
+ AdjustScrollBars( aOutputSize );
+ if( GetUpdateMode() )
+ aVerSBar.Update();
+ }
+ }
+ else
+ {
+ if( aVerSBar.IsVisible() )
+ {
+ pView->nFocusWidth = -1;
+ AdjustScrollBars( aOutputSize );
+ }
+ }
+
+ long nMaxRight = GetOutputSize().Width();
+ Point aPos( pView->GetMapMode().GetOrigin() );
+ aPos.X() *= -1; // Umrechnung Dokumentkoord.
+ nMaxRight = nMaxRight + aPos.X() - 1;
+ if( nMaxRight < nMostRight )
+ {
+ if( !aHorSBar.IsVisible() )
+ {
+ pView->nFocusWidth = -1;
+ AdjustScrollBars( aOutputSize );
+ if( GetUpdateMode() )
+ aHorSBar.Update();
+ }
+ else
+ {
+ Range aRange( aHorSBar.GetRange() );
+ if( aRange.Max() < nMostRight+25 )
+ {
+ aRange.Max() = nMostRight+25;
+ aHorSBar.SetRange( aRange );
+ }
+ else
+ {
+ pView->nFocusWidth = -1;
+ AdjustScrollBars( aOutputSize );
+ }
+ }
+ }
+ else
+ {
+ if( aHorSBar.IsVisible() )
+ {
+ pView->nFocusWidth = -1;
+ AdjustScrollBars( aOutputSize );
+ }
+ }
+}
+
+
+void SvImpLBox::SyncVerThumb()
+{
+ if( pStartEntry )
+ {
+ long nEntryPos = pView->GetVisiblePos( pStartEntry );
+ aVerSBar.SetThumbPos( nEntryPos );
+ }
+ else
+ aVerSBar.SetThumbPos( 0 );
+}
+
+BOOL SvImpLBox::IsEntryInView( SvLBoxEntry* pEntry ) const
+{
+ // Parent eingeklappt
+ if( !pView->IsEntryVisible(pEntry) )
+ return FALSE;
+ long nY = GetEntryLine( pEntry );
+ if( nY < 0 )
+ return FALSE;
+ long nMax = nVisibleCount * pView->GetEntryHeight();
+ if( nY >= nMax )
+ return FALSE;
+ return TRUE;
+}
+
+
+long SvImpLBox::GetEntryLine( SvLBoxEntry* pEntry ) const
+{
+ if(!pStartEntry )
+ return -1; // unsichtbare Position
+
+ long nFirstVisPos = pView->GetVisiblePos( pStartEntry );
+ long nEntryVisPos = pView->GetVisiblePos( pEntry );
+ nFirstVisPos = nEntryVisPos - nFirstVisPos;
+ nFirstVisPos *= pView->GetEntryHeight();
+ return nFirstVisPos;
+}
+
+void SvImpLBox::SetEntryHeight( short /* nHeight */ )
+{
+ SetNodeBmpYOffset( GetExpandedNodeBmp() );
+ SetNodeBmpYOffset( GetCollapsedNodeBmp() );
+ if(!pView->HasViewData()) // stehen wir im Clear?
+ {
+ Size aSize = pView->Control::GetOutputSizePixel();
+ AdjustScrollBars( aSize );
+ }
+ else
+ {
+ Resize();
+ if( GetUpdateMode() )
+ pView->Invalidate();
+ }
+}
+
+
+
+// ***********************************************************************
+// Callback-Functions
+// ***********************************************************************
+
+void SvImpLBox::IndentChanged( short /* nIndentPixel */ ) {}
+
+void SvImpLBox::EntryExpanded( SvLBoxEntry* pEntry )
+{
+ // SelAllDestrAnch( FALSE, TRUE ); //DeselectAll();
+ if( GetUpdateMode() )
+ {
+ ShowCursor( FALSE );
+ long nY = GetEntryLine( pEntry );
+ if( IsLineVisible(nY) )
+ {
+ InvalidateEntriesFrom( nY );
+ FindMostRight( pEntry, 0 );
+ }
+ aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) );
+ // falls vor dem Thumb expandiert wurde, muss
+ // die Thumb-Position korrigiert werden.
+ SyncVerThumb();
+ ShowVerSBar();
+ ShowCursor( TRUE );
+ }
+}
+
+void SvImpLBox::EntryCollapsed( SvLBoxEntry* pEntry )
+{
+ if( !pView->IsEntryVisible( pEntry ) )
+ return;
+
+ ShowCursor( FALSE );
+
+ if( !pMostRightEntry || pTree->IsChild( pEntry,pMostRightEntry ) )
+ {
+ FindMostRight(0);
+ }
+
+ if( pStartEntry )
+ {
+ long nOldThumbPos = aVerSBar.GetThumbPos();
+ ULONG nVisList = pView->GetVisibleCount();
+ aVerSBar.SetRange( Range(0, nVisList-1) );
+ long nNewThumbPos = aVerSBar.GetThumbPos();
+ if( nNewThumbPos != nOldThumbPos )
+ {
+ pStartEntry = pView->First();
+ USHORT nDistance = (USHORT)nNewThumbPos;
+ if( nDistance )
+ pStartEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry,
+ nDistance));
+ if( GetUpdateMode() )
+ pView->Invalidate();
+ }
+ else
+ SyncVerThumb();
+ ShowVerSBar();
+ }
+ // wurde Cursor eingeklappt ?
+ if( pTree->IsChild( pEntry, pCursor ) )
+ SetCursor( pEntry );
+ if( GetUpdateMode() )
+ ShowVerSBar();
+ ShowCursor( TRUE );
+ if( GetUpdateMode() && pCursor )
+ pView->Select( pCursor, TRUE );
+}
+
+void SvImpLBox::CollapsingEntry( SvLBoxEntry* pEntry )
+{
+ if( !pView->IsEntryVisible( pEntry ) || !pStartEntry )
+ return;
+
+ SelAllDestrAnch( FALSE, TRUE ); // deselectall
+
+ // ist der eingeklappte Parent sichtbar ?
+ long nY = GetEntryLine( pEntry );
+ if( IsLineVisible(nY) )
+ {
+ if( GetUpdateMode() )
+ InvalidateEntriesFrom( nY );
+ }
+ else
+ {
+ if( pTree->IsChild(pEntry, pStartEntry) )
+ {
+ pStartEntry = pEntry;
+ if( GetUpdateMode() )
+ pView->Invalidate();
+ }
+ }
+}
+
+
+void SvImpLBox::SetNodeBmpYOffset( const Image& rBmp )
+{
+ Size aSize;
+ nYoffsNodeBmp = pView->GetHeightOffset( rBmp, aSize );
+ nNodeBmpWidth = aSize.Width();
+}
+
+void SvImpLBox::SetNodeBmpTabDistance()
+{
+ nNodeBmpTabDistance = -pView->GetIndent();
+ if( pView->nContextBmpWidthMax )
+ {
+ // nur, wenn der erste dynamische Tab zentriert ist
+ // (setze ich momentan voraus)
+ Size aSize = GetExpandedNodeBmp().GetSizePixel();
+ nNodeBmpTabDistance -= aSize.Width() / 2;
+ }
+}
+
+//
+// korrigiert bei SingleSelection den Cursor
+//
+void SvImpLBox::EntrySelected( SvLBoxEntry* pEntry, BOOL bSelect )
+{
+ if( nFlags & F_IGNORE_SELECT )
+ return;
+
+ /*
+ if( (nWinBits & WB_HIDESELECTION) && pEntry && !pView->HasFocus() )
+ {
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ pViewData->SetCursored( bSelect );
+ }
+ */
+
+ nFlags &= (~F_DESEL_ALL);
+ if( bSelect &&
+ aSelEng.GetSelectionMode() == SINGLE_SELECTION &&
+ pEntry != pCursor )
+ {
+ SetCursor( pEntry );
+ DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?");
+ }
+
+ if( GetUpdateMode() && pView->IsEntryVisible(pEntry) )
+ {
+ long nY = GetEntryLine( pEntry );
+ if( IsLineVisible( nY ) )
+ {
+ ShowCursor( FALSE );
+ pView->PaintEntry1( pEntry, nY, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
+ ShowCursor( TRUE );
+ }
+ }
+}
+
+
+void SvImpLBox::RemovingEntry( SvLBoxEntry* pEntry )
+{
+ DestroyAnchor();
+
+ if( !pView->IsEntryVisible( pEntry ) )
+ {
+ // wenn Parent eingeklappt, dann tschuess
+ nFlags |= F_REMOVED_ENTRY_INVISIBLE;
+ return;
+ }
+
+ if( pEntry == pMostRightEntry || (
+ pEntry->HasChilds() && pView->IsExpanded(pEntry) &&
+ pTree->IsChild(pEntry, pMostRightEntry)))
+ {
+ nFlags |= F_REMOVED_RECALC_MOST_RIGHT;
+ }
+
+ SvLBoxEntry* pOldStartEntry = pStartEntry;
+
+ SvLBoxEntry* pParent = (SvLBoxEntry*)(pView->GetModel()->GetParent(pEntry));
+
+ if( pParent && pView->GetModel()->GetChildList(pParent)->Count() == 1 )
+ {
+ DBG_ASSERT( pView->IsExpanded( pParent ), "Parent not expanded");
+ pParent->SetFlags( pParent->GetFlags() | SV_ENTRYFLAG_NO_NODEBMP);
+ InvalidateEntry( pParent );
+ }
+
+ if( pCursor && pTree->IsChild( pEntry, pCursor) )
+ pCursor = pEntry;
+ if( pStartEntry && pTree->IsChild(pEntry,pStartEntry) )
+ pStartEntry = pEntry;
+
+ SvLBoxEntry* pTemp;
+ if( pCursor && pCursor == pEntry )
+ {
+ if( bSimpleTravel )
+ pView->Select( pCursor, FALSE );
+ ShowCursor( FALSE ); // Focus-Rect weg
+ // NextSibling, weil auch Childs des Cursors geloescht werden
+ pTemp = pView->NextSibling( pCursor );
+ if( !pTemp )
+ pTemp = (SvLBoxEntry*)(pView->PrevVisible( pCursor ));
+
+ SetCursor( pTemp, TRUE );
+ }
+ if( pStartEntry && pStartEntry == pEntry )
+ {
+ pTemp = pView->NextSibling( pStartEntry );
+ if( !pTemp )
+ pTemp = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry ));
+ pStartEntry = pTemp;
+ }
+ if( GetUpdateMode())
+ {
+ // wenns der letzte ist, muss invalidiert werden, damit die Linien
+ // richtig gezeichnet (in diesem Fall geloescht) werden.
+ if( pStartEntry && (pStartEntry != pOldStartEntry || pEntry == (SvLBoxEntry*)pView->GetModel()->Last()) )
+ {
+ aVerSBar.SetThumbPos( pView->GetVisiblePos( pStartEntry ));
+ pView->Invalidate( GetVisibleArea() );
+ }
+ else
+ InvalidateEntriesFrom( GetEntryLine( pEntry ) );
+ }
+}
+
+void SvImpLBox::EntryRemoved()
+{
+ if( nFlags & F_REMOVED_ENTRY_INVISIBLE )
+ {
+ nFlags &= (~F_REMOVED_ENTRY_INVISIBLE);
+ return;
+ }
+ if( !pStartEntry )
+ pStartEntry = pTree->First();
+ if( !pCursor )
+ SetCursor( pStartEntry, TRUE );
+
+ if( pCursor && (bSimpleTravel || !pView->GetSelectionCount() ))
+ pView->Select( pCursor, TRUE );
+
+ if( GetUpdateMode())
+ {
+ if( nFlags & F_REMOVED_RECALC_MOST_RIGHT )
+ FindMostRight(0);
+ aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) );
+ FillView();
+ if( pStartEntry )
+ // falls ueber dem Thumb geloescht wurde
+ aVerSBar.SetThumbPos( pView->GetVisiblePos( pStartEntry) );
+
+ ShowVerSBar();
+ if( pCursor && pView->HasFocus() && !pView->IsSelected(pCursor) )
+ {
+ if( pView->GetSelectionCount() )
+ {
+ // ist ein benachbarter Eintrag selektiert?
+ SvLBoxEntry* pNextCursor = (SvLBoxEntry*)pView->PrevVisible( pCursor );
+ if( !pNextCursor || !pView->IsSelected( pNextCursor ))
+ pNextCursor = (SvLBoxEntry*)pView->NextVisible( pCursor );
+ if( !pNextCursor || !pView->IsSelected( pNextCursor ))
+ // kein Nachbar selektiert: Ersten selektierten nehmen
+ pNextCursor = pView->FirstSelected();
+ SetCursor( pNextCursor );
+ MakeVisible( pCursor );
+ }
+ else
+ pView->Select( pCursor, TRUE );
+ }
+ ShowCursor( TRUE );
+ }
+ nFlags &= (~F_REMOVED_RECALC_MOST_RIGHT);
+}
+
+
+void SvImpLBox::MovingEntry( SvLBoxEntry* pEntry )
+{
+ int bDeselAll = nFlags & F_DESEL_ALL;
+ SelAllDestrAnch( FALSE, TRUE ); // DeselectAll();
+ if( !bDeselAll )
+ nFlags &= (~F_DESEL_ALL);
+
+ if( pEntry == pCursor )
+ ShowCursor( FALSE );
+ if( IsEntryInView( pEntry ) )
+ pView->Invalidate();
+ if( pEntry == pStartEntry )
+ {
+ SvLBoxEntry* pNew = 0;
+ if( !pEntry->HasChilds() )
+ {
+ pNew = (SvLBoxEntry*)(pView->NextVisible( pStartEntry ));
+ if( !pNew )
+ pNew = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry ));
+ }
+ else
+ {
+ pNew = pTree->NextSibling( pEntry );
+ if( !pNew )
+ pNew = pTree->PrevSibling( pEntry );
+ }
+ pStartEntry = pNew;
+ }
+}
+
+void SvImpLBox::EntryMoved( SvLBoxEntry* pEntry )
+{
+ // #97680# --------------
+ UpdateContextBmpWidthVectorFromMovedEntry( pEntry );
+
+ if ( !pStartEntry )
+ // this might happen if the only entry in the view is moved to its very same position
+ // #i97346#
+ pStartEntry = pView->First();
+
+ aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1));
+ USHORT nFirstPos = (USHORT)pTree->GetAbsPos( pStartEntry );
+ USHORT nNewPos = (USHORT)pTree->GetAbsPos( pEntry );
+ FindMostRight(0);
+ if( nNewPos < nFirstPos ) //!!!Notloesung
+ pStartEntry = pEntry;
+ // #97702# ---------------
+ SyncVerThumb();
+ if( pEntry == pCursor )
+ {
+ if( pView->IsEntryVisible( pCursor ) )
+ ShowCursor( TRUE );
+ else
+ {
+ SvLBoxEntry* pParent = pEntry;
+ do {
+ pParent = pTree->GetParent( pParent );
+ }
+ while( !pView->IsEntryVisible( pParent ) );
+ SetCursor( pParent );
+ }
+ }
+ if( IsEntryInView( pEntry ) )
+ pView->Invalidate();
+}
+
+
+
+void SvImpLBox::EntryInserted( SvLBoxEntry* pEntry )
+{
+ if( GetUpdateMode() )
+ {
+ SvLBoxEntry* pParent = (SvLBoxEntry*)pTree->GetParent(pEntry);
+ if( pParent && pTree->GetChildList(pParent)->Count() == 1 )
+ // Pluszeichen zeichnen
+ pTree->InvalidateEntry( pParent );
+
+ if( !pView->IsEntryVisible( pEntry ) )
+ return;
+ int bDeselAll = nFlags & F_DESEL_ALL;
+ if( bDeselAll )
+ SelAllDestrAnch( FALSE, TRUE );
+ else
+ DestroyAnchor();
+ // nFlags &= (~F_DESEL_ALL);
+// ShowCursor( FALSE ); // falls sich Cursor nach unten verschiebt
+ long nY = GetEntryLine( pEntry );
+ BOOL bEntryVisible = IsLineVisible( nY );
+ if( bEntryVisible )
+ {
+ ShowCursor( FALSE ); // falls sich Cursor nach unten verschiebt
+ nY -= pView->GetEntryHeight(); // wg. Linien
+ InvalidateEntriesFrom( nY );
+ }
+ else if( pStartEntry && nY < GetEntryLine(pStartEntry) )
+ {
+ // pruefen, ob die View komplett gefuellt ist. Wenn
+ // nicht, dann pStartEntry und den Cursor anpassen
+ // (automatisches scrollen)
+ USHORT nLast = (USHORT)(pView->GetVisiblePos( (SvLBoxEntry*)(pView->LastVisible())));
+ USHORT nThumb = (USHORT)(pView->GetVisiblePos( pStartEntry ));
+ USHORT nCurDispEntries = nLast-nThumb+1;
+ if( nCurDispEntries < nVisibleCount )
+ {
+ // beim naechsten Paint-Event setzen
+ pStartEntry = 0;
+ SetCursor( 0 );
+ pView->Invalidate();
+ }
+ }
+ else if( !pStartEntry )
+ pView->Invalidate();
+
+ // die Linien invalidieren
+ /*
+ if( (bEntryVisible || bPrevEntryVisible) &&
+ (nWinBits & ( WB_HASLINES | WB_HASLINESATROOT )) )
+ {
+ SvLBoxTab* pTab = pView->GetFirstDynamicTab();
+ if( pTab )
+ {
+ long nDX = pView->GetTabPos( pEntry, pTab );
+ Point aTmpPoint;
+ Size aSize( nDX, nY );
+ Rectangle aRect( aTmpPoint, aSize );
+ pView->Invalidate( aRect );
+ }
+ }
+ */
+
+ SetMostRight( pEntry );
+ aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1));
+ SyncVerThumb(); // falls vor Thumb eingefuegt wurde
+ ShowVerSBar();
+ ShowCursor( TRUE );
+ if( pStartEntry != pView->First() && (nFlags & F_FILLING) )
+ pView->Update();
+ }
+}
+
+
+
+// ********************************************************************
+// Eventhandler
+// ********************************************************************
+
+
+// ****** Steuerung der Controlanimation
+
+BOOL SvImpLBox::ButtonDownCheckCtrl(const MouseEvent& rMEvt, SvLBoxEntry* pEntry,
+ long nY )
+{
+ SvLBoxItem* pItem = pView->GetItem(pEntry,rMEvt.GetPosPixel().X(),&pActiveTab);
+ if( pItem && (pItem->IsA()==SV_ITEM_ID_LBOXBUTTON))
+ {
+ pActiveButton = (SvLBoxButton*)pItem;
+ pActiveEntry = pEntry;
+ if( pCursor == pActiveEntry )
+ pView->HideFocus();
+ pView->CaptureMouse();
+ pActiveButton->SetStateHilighted( TRUE );
+ pView->PaintEntry1( pActiveEntry, nY,
+ SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER |
+ SV_LBOXTAB_ADJUST_RIGHT );
+ return TRUE;
+ }
+ else
+ pActiveButton = 0;
+ return FALSE;
+}
+
+BOOL SvImpLBox::MouseMoveCheckCtrl( const MouseEvent& rMEvt, SvLBoxEntry* pEntry)
+{
+ if( pActiveButton )
+ {
+ long nY;
+ long nMouseX = rMEvt.GetPosPixel().X();
+ if( pEntry == pActiveEntry &&
+ pView->GetItem(pActiveEntry, nMouseX) == pActiveButton )
+ {
+ if( !pActiveButton->IsStateHilighted() )
+ {
+ pActiveButton->SetStateHilighted(TRUE );
+ nY = GetEntryLine( pActiveEntry );
+ pView->PaintEntry1( pActiveEntry, nY,
+ SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER |
+ SV_LBOXTAB_ADJUST_RIGHT );
+ }
+ }
+ else
+ {
+ if( pActiveButton->IsStateHilighted() )
+ {
+ pActiveButton->SetStateHilighted(FALSE );
+ nY = GetEntryLine( pActiveEntry );
+ pView->PaintEntry1( pActiveEntry, nY, SV_LBOXTAB_PUSHABLE );
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SvImpLBox::ButtonUpCheckCtrl( const MouseEvent& rMEvt )
+{
+ if( pActiveButton )
+ {
+ pView->ReleaseMouse();
+ SvLBoxEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() );
+ long nY = GetEntryLine( pActiveEntry );
+ pActiveButton->SetStateHilighted( FALSE );
+ long nMouseX = rMEvt.GetPosPixel().X();
+ if( pEntry == pActiveEntry &&
+ pView->GetItem( pActiveEntry, nMouseX ) == pActiveButton )
+ pActiveButton->ClickHdl( pView, pActiveEntry );
+ pView->PaintEntry1( pActiveEntry, nY,
+ SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER |
+ SV_LBOXTAB_ADJUST_RIGHT );
+ if( pCursor == pActiveEntry )
+ ShowCursor( TRUE );
+ pActiveButton = 0;
+ pActiveEntry = 0;
+ pActiveTab = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// ******* Steuerung Plus/Minus-Button zum Expandieren/Kollabieren
+
+// FALSE == kein Expand/Collapse-Button getroffen
+BOOL SvImpLBox::IsNodeButton( const Point& rPosPixel, SvLBoxEntry* pEntry ) const
+{
+ if( !pEntry->HasChilds() && !pEntry->HasChildsOnDemand() )
+ return FALSE;
+
+ SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab();
+ if( !pFirstDynamicTab )
+ return FALSE;
+
+ long nMouseX = rPosPixel.X();
+ // in Doc-Koords umrechnen
+ Point aOrigin( pView->GetMapMode().GetOrigin() );
+ nMouseX -= aOrigin.X();
+
+ long nX = pView->GetTabPos( pEntry, pFirstDynamicTab);
+ nX += nNodeBmpTabDistance;
+ if( nMouseX < nX )
+ return FALSE;
+ nX += nNodeBmpWidth;
+ if( nMouseX > nX )
+ return FALSE;
+ return TRUE;
+}
+
+// FALSE == hit no node button
+BOOL SvImpLBox::ButtonDownCheckExpand( const MouseEvent& rMEvt, SvLBoxEntry* pEntry, long /* nY */ )
+{
+ BOOL bRet = FALSE;
+
+ if ( pView->IsEditingActive() && pEntry == pView->pEdEntry )
+ // inplace editing -> nothing to do
+ bRet = TRUE;
+ else if ( IsNodeButton( rMEvt.GetPosPixel(), pEntry ) )
+ {
+ if ( pView->IsExpanded( pEntry ) )
+ {
+ pView->EndEditing( TRUE );
+ pView->Collapse( pEntry );
+ }
+ else
+ {
+ // you can expand an entry, which is in editing
+ pView->Expand( pEntry );
+ }
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+void SvImpLBox::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsLeft() && !rMEvt.IsRight())
+ return;
+
+#ifdef OS2
+ // unter OS/2 kommt zwischen MouseButtonDown und
+ // MouseButtonUp ein MouseMove
+ nFlags |= F_IGNORE_NEXT_MOUSEMOVE;
+#endif
+ aEditTimer.Stop();
+ Point aPos( rMEvt.GetPosPixel());
+
+ if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() )
+ return;
+
+ SvLBoxEntry* pEntry = GetEntry( aPos );
+ if ( pEntry != pCursor )
+ // new entry selected -> reset current tab position to first tab
+ nCurTabPos = FIRST_ENTRY_TAB;
+ nFlags &= (~F_FILLING);
+ pView->GrabFocus();
+ // #120417# the entry can still be invalid!
+ if( !pEntry || !pView->GetViewData( pEntry ))
+ return;
+
+ long nY = GetEntryLine( pEntry );
+ // Node-Button?
+ if( ButtonDownCheckExpand( rMEvt, pEntry, nY ) )
+ return;
+
+ if( !EntryReallyHit(pEntry,aPos,nY))
+ return;
+
+ SvLBoxItem* pXItem = pView->GetItem( pEntry, aPos.X() );
+ if( pXItem )
+ {
+ SvLBoxTab* pXTab = pView->GetTab( pEntry, pXItem );
+ if ( !rMEvt.IsMod1() && !rMEvt.IsMod2() && rMEvt.IsLeft() && pXTab->IsEditable()
+ && pEntry == pView->FirstSelected() && NULL == pView->NextSelected( pEntry ) )
+ // #i8234# FirstSelected() and NextSelected() ensures, that inplace editing is only triggered, when only one entry is selected
+ nFlags |= F_START_EDITTIMER;
+ if ( !pView->IsSelected( pEntry ) )
+ nFlags &= ~F_START_EDITTIMER;
+ }
+
+
+ if( (rMEvt.GetClicks() % 2) == 0 )
+ {
+ nFlags &= (~F_START_EDITTIMER);
+ pView->pHdlEntry = pEntry;
+ if( pView->DoubleClickHdl() )
+ {
+ // falls im Handler der Eintrag geloescht wurde
+ pEntry = GetClickedEntry( aPos );
+ if( !pEntry )
+ return;
+ if( pEntry != pView->pHdlEntry )
+ {
+ // neu selektieren & tschuess
+ if( !bSimpleTravel && !aSelEng.IsAlwaysAdding())
+ SelAllDestrAnch( FALSE, TRUE ); // DeselectAll();
+ SetCursor( pEntry );
+
+ DBG_ERROR( "Please report what you did to get this assertion to FS!" );
+ // The entry which has been double-clicked changed - and we select it, again.
+ // I have situations where this behaviour does not make any sense at all - even more, it
+ // leads to hacks to revert it's results.
+ // So I'm not sure if this behaviour here is nonsense (which I believe at the moment),
+ // or if there are really scenarious where it dones make sense ....
+ // 07.12.2001 - 95727 - fs@openoffice.org
+
+ return;
+ }
+ if( pEntry->HasChilds() || pEntry->HasChildsOnDemand() )
+ {
+ if( pView->IsExpanded(pEntry) )
+ pView->Collapse( pEntry );
+ else
+ pView->Expand( pEntry );
+ if( pEntry == pCursor ) // nur wenn Entryitem angeklickt wurde
+ // (Nodebutton ist kein Entryitem!)
+ pView->Select( pCursor, TRUE );
+ return;
+ }
+ }
+ }
+ else
+ {
+ // CheckButton? (TreeListBox: Check + Info)
+ if( ButtonDownCheckCtrl(rMEvt, pEntry, nY) == TRUE)
+ return;
+ // Inplace-Editing?
+#if 0
+ if( rMEvt.IsMod2() && pView->IsInplaceEditingEnabled() )
+ {
+ SvLBoxItem* pItem = pView->GetItem( pEntry, aPos.X() );
+ if( pItem )
+ pView->EditingRequest( pEntry, pItem, aPos );
+ return;
+ }
+#endif
+ }
+ if ( aSelEng.GetSelectionMode() != NO_SELECTION )
+ aSelEng.SelMouseButtonDown( rMEvt );
+}
+
+void SvImpLBox::MouseButtonUp( const MouseEvent& rMEvt)
+{
+#ifdef OS2
+ nFlags &= (~F_IGNORE_NEXT_MOUSEMOVE);
+#endif
+ if ( !ButtonUpCheckCtrl( rMEvt ) && ( aSelEng.GetSelectionMode() != NO_SELECTION ) )
+ aSelEng.SelMouseButtonUp( rMEvt );
+ EndScroll();
+ if( nFlags & F_START_EDITTIMER )
+ {
+ nFlags &= (~F_START_EDITTIMER);
+ aEditClickPos = rMEvt.GetPosPixel();
+ aEditTimer.Start();
+ }
+
+ return;
+}
+
+void SvImpLBox::MouseMove( const MouseEvent& rMEvt)
+{
+#ifdef OS2
+ if( nFlags & F_IGNORE_NEXT_MOUSEMOVE )
+ {
+ nFlags &= (~F_IGNORE_NEXT_MOUSEMOVE);
+ return;
+ }
+#endif
+ SvLBoxEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() );
+ if ( !MouseMoveCheckCtrl( rMEvt, pEntry ) && ( aSelEng.GetSelectionMode() != NO_SELECTION ) )
+ aSelEng.SelMouseMove( rMEvt );
+ return;
+}
+
+BOOL SvImpLBox::KeyInput( const KeyEvent& rKEvt)
+{
+ aEditTimer.Stop();
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+
+ if( rKeyCode.IsMod2() )
+ return FALSE; // Alt-Taste nicht auswerten
+
+ nFlags &= (~F_FILLING);
+
+ if( !pCursor )
+ pCursor = pStartEntry;
+ if( !pCursor )
+ return FALSE;
+
+ BOOL bKeyUsed = TRUE;
+
+ USHORT nDelta = (USHORT)aVerSBar.GetPageSize();
+ USHORT aCode = rKeyCode.GetCode();
+
+ BOOL bShift = rKeyCode.IsShift();
+ BOOL bMod1 = rKeyCode.IsMod1();
+
+ SvLBoxEntry* pNewCursor;
+
+ switch( aCode )
+ {
+ case KEY_UP:
+ if( !IsEntryInView( pCursor ) )
+ MakeVisible( pCursor );
+
+ pNewCursor = pCursor;
+ do
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor ));
+ } while( pNewCursor && !IsSelectable(pNewCursor) );
+
+ if ( pNewCursor )
+ // new entry selected -> reset current tab position to first tab
+ nCurTabPos = FIRST_ENTRY_TAB;
+ // if there is no next entry, take the current one
+ // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
+ // the cursor key
+ // 06.09.20001 - 83416 - fs@openoffice.org
+ if ( !pNewCursor && pCursor )
+ pNewCursor = pCursor;
+
+ if( pNewCursor )
+ {
+ aSelEng.CursorPosChanging( bShift, bMod1 );
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ if( !IsEntryInView( pNewCursor ) )
+ KeyUp( FALSE );
+ }
+ break;
+
+ case KEY_DOWN:
+ if( !IsEntryInView( pCursor ) )
+ MakeVisible( pCursor );
+
+ pNewCursor = pCursor;
+ do
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor ));
+ } while( pNewCursor && !IsSelectable(pNewCursor) );
+
+ if ( pNewCursor )
+ // new entry selected -> reset current tab position to first tab
+ nCurTabPos = FIRST_ENTRY_TAB;
+
+ // if there is no next entry, take the current one
+ // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
+ // the cursor key
+ // 06.09.20001 - 83416 - frank.schoenheit@sun.com
+ if ( !pNewCursor && pCursor )
+ pNewCursor = pCursor;
+
+ if( pNewCursor )
+ {
+ aSelEng.CursorPosChanging( bShift, bMod1 );
+ if( IsEntryInView( pNewCursor ) )
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ else
+ {
+ if( pCursor )
+ pView->Select( pCursor, FALSE );
+ KeyDown( FALSE );
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ }
+ }
+ else
+ KeyDown( FALSE ); // weil ScrollBar-Range evtl. noch
+ // scrollen erlaubt
+ break;
+
+ case KEY_RIGHT:
+ {
+ if( bSubLstOpLR && IsNowExpandable() )
+ pView->Expand( pCursor );
+ else if ( bIsCellFocusEnabled && pCursor )
+ {
+ if ( nCurTabPos < ( pView->TabCount() - 1 /*!2*/ ) )
+ {
+ ++nCurTabPos;
+ ShowCursor( TRUE );
+ CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor );
+ }
+ }
+ else if( pView->nWindowStyle & WB_HSCROLL )
+ {
+ long nThumb = aHorSBar.GetThumbPos();
+ nThumb += aHorSBar.GetLineSize();
+ long nOldThumb = aHorSBar.GetThumbPos();
+ aHorSBar.SetThumbPos( nThumb );
+ nThumb = nOldThumb;
+ nThumb -= aHorSBar.GetThumbPos();
+ nThumb *= -1;
+ if( nThumb )
+ {
+ KeyLeftRight( nThumb );
+ EndScroll();
+ }
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+ }
+
+ case KEY_LEFT:
+ {
+ if ( bIsCellFocusEnabled )
+ {
+ if ( nCurTabPos > FIRST_ENTRY_TAB )
+ {
+ --nCurTabPos;
+ ShowCursor( TRUE );
+ CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor );
+ }
+ }
+ else if ( pView->nWindowStyle & WB_HSCROLL )
+ {
+ long nThumb = aHorSBar.GetThumbPos();
+ nThumb -= aHorSBar.GetLineSize();
+ long nOldThumb = aHorSBar.GetThumbPos();
+ aHorSBar.SetThumbPos( nThumb );
+ nThumb = nOldThumb;
+ nThumb -= aHorSBar.GetThumbPos();
+ if( nThumb )
+ {
+ KeyLeftRight( -nThumb );
+ EndScroll();
+ }
+ else if( bSubLstOpLR )
+ {
+ if( IsExpandable() && pView->IsExpanded( pCursor ) )
+ pView->Collapse( pCursor );
+ else
+ {
+ pNewCursor = pView->GetParent( pCursor );
+ if( pNewCursor )
+ SetCursor( pNewCursor );
+ }
+ }
+ }
+ else if( bSubLstOpLR && IsExpandable() )
+ pView->Collapse( pCursor );
+ else
+ bKeyUsed = FALSE;
+ break;
+ }
+
+ case KEY_PAGEUP:
+ if( !bMod1 )
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pCursor, nDelta ));
+
+ while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor ));
+ nDelta--;
+ }
+
+ if( nDelta )
+ {
+ DBG_ASSERT(pNewCursor&&(ULONG)pNewCursor!=(ULONG)pCursor,"Cursor?");
+ aSelEng.CursorPosChanging( bShift, bMod1 );
+ if( IsEntryInView( pNewCursor ) )
+ SetCursor( pNewCursor );
+ else
+ {
+ SetCursor( pNewCursor );
+ KeyUp( TRUE );
+ }
+ }
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_PAGEDOWN:
+ if( !bMod1 )
+ {
+ pNewCursor= (SvLBoxEntry*)(pView->NextVisible( pCursor, nDelta ));
+
+ while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor ));
+ nDelta--;
+ }
+
+ if( nDelta )
+ {
+ DBG_ASSERT(pNewCursor&&(ULONG)pNewCursor!=(ULONG)pCursor,"Cursor?");
+ aSelEng.CursorPosChanging( bShift, bMod1 );
+ if( IsEntryInView( pNewCursor ) )
+ SetCursor( pNewCursor );
+ else
+ {
+ SetCursor( pNewCursor );
+ KeyDown( TRUE );
+ }
+ }
+ else
+ KeyDown( FALSE ); // siehe KEY_DOWN
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_SPACE:
+ if ( pView->GetSelectionMode() != NO_SELECTION )
+ {
+ if ( bMod1 )
+ {
+ if ( pView->GetSelectionMode() == MULTIPLE_SELECTION && !bShift )
+ // toggle selection
+ pView->Select( pCursor, !pView->IsSelected( pCursor ) );
+ }
+ else if ( !bShift /*&& !bMod1*/ )
+ {
+ if ( aSelEng.IsAddMode() )
+ // toggle selection
+ pView->Select( pCursor, !pView->IsSelected( pCursor ) );
+ else
+ {
+ SelAllDestrAnch( FALSE );
+ pView->Select( pCursor, TRUE );
+ }
+ }
+ else
+ bKeyUsed = FALSE;
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_RETURN:
+ if( bSubLstOpRet && IsExpandable() )
+ {
+ if( pView->IsExpanded( pCursor ) )
+ pView->Collapse( pCursor );
+ else
+ pView->Expand( pCursor );
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_F2:
+ if( !bShift && !bMod1 )
+ {
+ aEditClickPos = Point( -1, -1 );
+ EditTimerCall( 0 );
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_F8:
+ if( bShift && pView->GetSelectionMode()==MULTIPLE_SELECTION &&
+ !(nWinBits & WB_SIMPLEMODE))
+ {
+ if( aSelEng.IsAlwaysAdding() )
+ aSelEng.AddAlways( FALSE );
+ else
+ aSelEng.AddAlways( TRUE );
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+
+#ifdef OV_DEBUG
+ case KEY_F9:
+ MakeVisible( pCursor );
+ break;
+ case KEY_F10:
+ pView->RemoveSelection();
+ break;
+ case KEY_DELETE:
+ pView->RemoveEntry( pCursor );
+ break;
+#endif
+
+ case KEY_ADD:
+ if( pCursor )
+ {
+ if( !pView->IsExpanded(pCursor))
+ pView->Expand( pCursor );
+ if( bMod1 )
+ {
+ USHORT nRefDepth = pTree->GetDepth( pCursor );
+ SvLBoxEntry* pCur = pTree->Next( pCursor );
+ while( pCur && pTree->GetDepth(pCur) > nRefDepth )
+ {
+ if( pCur->HasChilds() && !pView->IsExpanded(pCur))
+ pView->Expand( pCur );
+ pCur = pTree->Next( pCur );
+ }
+ }
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_A:
+ if( bMod1 )
+ SelAllDestrAnch( TRUE );
+// else
+// bKeyUsed = FALSE; #105907# assume user wants to use quicksearch with key "a", so key is handled!
+ break;
+
+ case KEY_SUBTRACT:
+ if( pCursor )
+ {
+ if( pView->IsExpanded(pCursor))
+ pView->Collapse( pCursor );
+ if( bMod1 )
+ {
+ // bis zur Root alle Parents einklappen
+ SvLBoxEntry* pParentToCollapse = (SvLBoxEntry*)pTree->GetRootLevelParent(pCursor);
+ if( pParentToCollapse )
+ {
+ USHORT nRefDepth;
+ // Sonderbehandlung Explorer: Befindet sich auf der
+ // Root nur ein Eintrag,dann den Root-Entry nicht
+ // einklappen
+ if( pTree->GetChildList(0)->Count() < 2 )
+ {
+ nRefDepth = 1;
+ pParentToCollapse = pCursor;
+ while( pTree->GetParent(pParentToCollapse) &&
+ pTree->GetDepth( pTree->GetParent(pParentToCollapse)) > 0)
+ {
+ pParentToCollapse = pTree->GetParent(pParentToCollapse);
+ }
+ }
+ else
+ nRefDepth = 0;
+
+ if( pView->IsExpanded(pParentToCollapse) )
+ pView->Collapse( pParentToCollapse );
+ SvLBoxEntry* pCur = pTree->Next( pParentToCollapse );
+ while( pCur && pTree->GetDepth(pCur) > nRefDepth )
+ {
+ if( pCur->HasChilds() && pView->IsExpanded(pCur) )
+ pView->Collapse( pCur );
+ pCur = pTree->Next( pCur );
+ }
+ }
+ }
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_DIVIDE :
+ if( bMod1 )
+ SelAllDestrAnch( TRUE );
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_COMMA :
+ if( bMod1 )
+ SelAllDestrAnch( FALSE );
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_HOME :
+ pNewCursor = pView->GetModel()->First();
+
+ while( pNewCursor && !IsSelectable(pNewCursor) )
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor ));
+ }
+
+ if( pNewCursor && pNewCursor != pCursor )
+ {
+// SelAllDestrAnch( FALSE );
+ aSelEng.CursorPosChanging( bShift, bMod1 );
+ SetCursor( pNewCursor );
+ if( !IsEntryInView( pNewCursor ) )
+ MakeVisible( pNewCursor );
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_END :
+ pNewCursor = pView->GetModel()->Last();
+
+ while( pNewCursor && !IsSelectable(pNewCursor) )
+ {
+ pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor ));
+ }
+
+ if( pNewCursor && pNewCursor != pCursor)
+ {
+// SelAllDestrAnch( FALSE );
+ aSelEng.CursorPosChanging( bShift, bMod1 );
+ SetCursor( pNewCursor );
+ if( !IsEntryInView( pNewCursor ) )
+ MakeVisible( pNewCursor );
+ }
+ else
+ bKeyUsed = FALSE;
+ break;
+
+ case KEY_ESCAPE:
+ case KEY_TAB:
+ case KEY_DELETE:
+ case KEY_BACKSPACE:
+ // #105907# must not be handled because this quits dialogs and does other magic things...
+ // if there are other single keys which should not be handled, they can be added here
+ bKeyUsed = FALSE;
+ break;
+
+ default:
+ if( bMod1 || rKeyCode.GetGroup() == KEYGROUP_FKEYS )
+ // #105907# CTRL or Function key is pressed, assume user don't want to use quicksearch...
+ // if there are groups of keys which should not be handled, they can be added here
+ bKeyUsed = FALSE;
+ }
+ return bKeyUsed;
+}
+
+void __EXPORT SvImpLBox::GetFocus()
+{
+ if( pCursor )
+ {
+ pView->SetEntryFocus( pCursor, TRUE );
+ ShowCursor( TRUE );
+// auskommentiert wg. deselectall
+// if( bSimpleTravel && !pView->IsSelected(pCursor) )
+// pView->Select( pCursor, TRUE );
+ }
+ if( nWinBits & WB_HIDESELECTION )
+ {
+ SvLBoxEntry* pEntry = pView->FirstSelected();
+ while( pEntry )
+ {
+ InvalidateEntry( pEntry );
+ pEntry = pView->NextSelected( pEntry );
+ }
+ /*
+ SvLBoxEntry* pEntry = pView->GetModel()->First();
+ while( pEntry )
+ {
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ if( pViewData->IsCursored() )
+ {
+ pViewData->SetCursored( FALSE );
+ InvalidateEntry( pEntry );
+ }
+ pEntry = pView->GetModel()->Next( pEntry );
+ }
+ */
+
+
+ }
+}
+
+void __EXPORT SvImpLBox::LoseFocus()
+{
+ aEditTimer.Stop();
+ if( pCursor )
+ pView->SetEntryFocus( pCursor,FALSE );
+ ShowCursor( FALSE );
+
+ if( nWinBits & WB_HIDESELECTION )
+ {
+ SvLBoxEntry* pEntry = pView->FirstSelected();
+ while( pEntry )
+ {
+ //SvViewData* pViewData = pView->GetViewData( pEntry );
+ //pViewData->SetCursored( TRUE );
+ InvalidateEntry( pEntry );
+ pEntry = pView->NextSelected( pEntry );
+ }
+ }
+}
+
+
+// ********************************************************************
+// SelectionEngine
+// ********************************************************************
+
+inline void SvImpLBox::SelectEntry( SvLBoxEntry* pEntry, BOOL bSelect )
+{
+ pView->Select( pEntry, bSelect );
+}
+
+__EXPORT ImpLBSelEng::ImpLBSelEng( SvImpLBox* pImpl, SelectionEngine* pSEng,
+ SvTreeListBox* pV )
+{
+ pImp = pImpl;
+ pSelEng = pSEng;
+ pView = pV;
+}
+
+__EXPORT ImpLBSelEng::~ImpLBSelEng()
+{
+}
+
+void __EXPORT ImpLBSelEng::BeginDrag()
+{
+ pImp->BeginDrag();
+}
+
+/*
+void __EXPORT ImpLBSelEng::EndDrag( const Point& )
+{
+}
+*/
+
+void __EXPORT ImpLBSelEng::CreateAnchor()
+{
+ pImp->pAnchor = pImp->pCursor;
+}
+
+void __EXPORT ImpLBSelEng::DestroyAnchor()
+{
+ pImp->pAnchor = 0;
+}
+
+/*
+void __EXPORT ImpLBSelEng::CreateCursor()
+{
+ pImp->pAnchor = 0;
+}
+*/
+
+
+BOOL __EXPORT ImpLBSelEng::SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor)
+{
+ SvLBoxEntry* pNewCursor = pImp->MakePointVisible( rPoint );
+ if( pNewCursor != pImp->pCursor )
+ pImp->BeginScroll();
+
+ if( pNewCursor )
+ {
+ // bei SimpleTravel wird in SetCursor selektiert und
+ // der Select-Handler gerufen
+ //if( !bDontSelectAtCursor && !pImp->bSimpleTravel )
+ // pImp->SelectEntry( pNewCursor, TRUE );
+ pImp->SetCursor( pNewCursor, bDontSelectAtCursor );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL __EXPORT ImpLBSelEng::IsSelectionAtPoint( const Point& rPoint )
+{
+ SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
+ if( pEntry )
+ return pView->IsSelected(pEntry);
+ return FALSE;
+}
+
+void __EXPORT ImpLBSelEng::DeselectAtPoint( const Point& rPoint )
+{
+ SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
+ if( !pEntry )
+ return;
+ pImp->SelectEntry( pEntry, FALSE );
+}
+
+/*
+void __EXPORT ImpLBSelEng::SelectAtPoint( const Point& rPoint )
+{
+ SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
+ if( !pEntry )
+ return;
+ pImp->SelectEntry( pEntry, TRUE );
+}
+*/
+
+void __EXPORT ImpLBSelEng::DeselectAll()
+{
+ pImp->SelAllDestrAnch( FALSE, FALSE ); // SelectionEngine nicht resetten!
+ pImp->nFlags &= (~F_DESEL_ALL);
+}
+
+// ***********************************************************************
+// Selektion
+// ***********************************************************************
+
+void SvImpLBox::SetAnchorSelection(SvLBoxEntry* pOldCursor,SvLBoxEntry* pNewCursor)
+{
+ SvLBoxEntry* pEntry;
+ ULONG nAnchorVisPos = pView->GetVisiblePos( pAnchor );
+ ULONG nOldVisPos = pView->GetVisiblePos( pOldCursor );
+ ULONG nNewVisPos = pView->GetVisiblePos( pNewCursor );
+
+ if( nOldVisPos > nAnchorVisPos ||
+ ( nAnchorVisPos==nOldVisPos && nNewVisPos > nAnchorVisPos) )
+ {
+ if( nNewVisPos > nOldVisPos )
+ {
+ pEntry = pOldCursor;
+ while( pEntry && pEntry != pNewCursor )
+ {
+ pView->Select( pEntry, TRUE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, TRUE );
+ return;
+ }
+
+ if( nNewVisPos < nAnchorVisPos )
+ {
+ pEntry = pAnchor;
+ while( pEntry && pEntry != pOldCursor )
+ {
+ pView->Select( pEntry, FALSE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, FALSE );
+
+ pEntry = pNewCursor;
+ while( pEntry && pEntry != pAnchor )
+ {
+ pView->Select( pEntry, TRUE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, TRUE );
+ return;
+ }
+
+ if( nNewVisPos < nOldVisPos )
+ {
+ pEntry = pNewCursor;
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ while( pEntry && pEntry != pOldCursor )
+ {
+ pView->Select( pEntry, FALSE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, FALSE );
+ return;
+ }
+ }
+ else
+ {
+ if( nNewVisPos < nOldVisPos ) // Vergroessern der Selektion
+ {
+ pEntry = pNewCursor;
+ while( pEntry && pEntry != pOldCursor )
+ {
+ pView->Select( pEntry, TRUE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, TRUE );
+ return;
+ }
+
+ if( nNewVisPos > nAnchorVisPos )
+ {
+ pEntry = pOldCursor;
+ while( pEntry && pEntry != pAnchor )
+ {
+ pView->Select( pEntry, FALSE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, FALSE );
+ pEntry = pAnchor;
+ while( pEntry && pEntry != pNewCursor )
+ {
+ pView->Select( pEntry, TRUE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ if( pEntry )
+ pView->Select( pEntry, TRUE );
+ return;
+ }
+
+ if( nNewVisPos > nOldVisPos )
+ {
+ pEntry = pOldCursor;
+ while( pEntry && pEntry != pNewCursor )
+ {
+ pView->Select( pEntry, FALSE );
+ pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
+ }
+ return;
+ }
+ }
+}
+
+void SvImpLBox::SelAllDestrAnch( BOOL bSelect, BOOL bDestroyAnchor,
+ BOOL bSingleSelToo )
+{
+ SvLBoxEntry* pEntry;
+ nFlags &= (~F_DESEL_ALL);
+ if( bSelect && bSimpleTravel )
+ {
+ if( pCursor && !pView->IsSelected( pCursor ))
+ {
+ pView->Select( pCursor, TRUE );
+ }
+ return;
+ }
+ if( !bSelect && pView->GetSelectionCount() == 0 )
+ {
+ if( bSimpleTravel && ( !GetUpdateMode() || !pCursor) )
+ nFlags |= F_DESEL_ALL;
+ return;
+ }
+ if( bSelect && pView->GetSelectionCount() == pView->GetEntryCount())
+ return;
+ if( !bSingleSelToo && bSimpleTravel )
+ return;
+
+ if( !bSelect && pView->GetSelectionCount()==1 && pCursor &&
+ pView->IsSelected( pCursor ))
+ {
+ pView->Select( pCursor, FALSE );
+ if( bDestroyAnchor )
+ DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen
+ else
+ pAnchor = 0; // internen Anker immer loeschen
+ return;
+ }
+
+ if( bSimpleTravel && !pCursor && !GetUpdateMode() )
+ nFlags |= F_DESEL_ALL;
+
+ ShowCursor( FALSE );
+ BOOL bUpdate = GetUpdateMode();
+
+ nFlags |= F_IGNORE_SELECT; // EntryInserted soll nix tun
+ pEntry = pTree->First();
+ while( pEntry )
+ {
+ if( pView->Select( pEntry, bSelect ) )
+ {
+ if( bUpdate && pView->IsEntryVisible(pEntry) )
+ {
+ long nY = GetEntryLine( pEntry );
+ if( IsLineVisible( nY ) )
+ pView->PaintEntry1( pEntry, nY, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
+ }
+ }
+ pEntry = pTree->Next( pEntry );
+ }
+ nFlags &= ~F_IGNORE_SELECT;
+
+ if( bDestroyAnchor )
+ DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen
+ else
+ pAnchor = 0; // internen Anker immer loeschen
+ ShowCursor( TRUE );
+}
+
+void SvImpLBox::SetSelectionMode( SelectionMode eSelMode )
+{
+ aSelEng.SetSelectionMode( eSelMode);
+ if( eSelMode == SINGLE_SELECTION )
+ bSimpleTravel = TRUE;
+ else
+ bSimpleTravel = FALSE;
+ if( (nWinBits & WB_SIMPLEMODE) && (eSelMode == MULTIPLE_SELECTION) )
+ aSelEng.AddAlways( TRUE );
+}
+
+// ***********************************************************************
+// Drag & Drop
+// ***********************************************************************
+
+void SvImpLBox::SetDragDropMode( DragDropMode eDDMode )
+{
+ if( eDDMode && eDDMode != SV_DRAGDROP_APP_DROP )
+ {
+ aSelEng.ExpandSelectionOnMouseMove( FALSE );
+ aSelEng.EnableDrag( TRUE );
+ }
+ else
+ {
+ aSelEng.ExpandSelectionOnMouseMove( TRUE );
+ aSelEng.EnableDrag( FALSE );
+ }
+}
+
+void SvImpLBox::BeginDrag()
+{
+ nFlags &= (~F_FILLING);
+ if( !bAsyncBeginDrag )
+ {
+ BeginScroll();
+ pView->StartDrag( 0, aSelEng.GetMousePosPixel() );
+ EndScroll();
+ }
+ else
+ {
+ aAsyncBeginDragPos = aSelEng.GetMousePosPixel();
+ aAsyncBeginDragTimer.Start();
+ }
+}
+
+IMPL_LINK( SvImpLBox, BeginDragHdl, void*, EMPTYARG )
+{
+ pView->StartDrag( 0, aAsyncBeginDragPos );
+ return 0;
+}
+
+void SvImpLBox::PaintDDCursor( SvLBoxEntry* pInsertionPos )
+{
+ long nY;
+ if( pInsertionPos )
+ {
+ nY = GetEntryLine( pInsertionPos );
+ nY += pView->GetEntryHeight();
+ }
+ else
+ nY = 1;
+ RasterOp eOldOp = pView->GetRasterOp();
+ pView->SetRasterOp( ROP_INVERT );
+ Color aOldLineColor = pView->GetLineColor();
+ pView->SetLineColor( Color( COL_BLACK ) );
+ pView->DrawLine( Point( 0, nY ), Point( aOutputSize.Width(), nY ) );
+ pView->SetLineColor( aOldLineColor );
+ pView->SetRasterOp( eOldOp );
+}
+/* -----------------26.08.2003 12:52-----------------
+ Delete all sub menues of a PopupMenu, recursively
+ --------------------------------------------------*/
+void lcl_DeleteSubPopups(PopupMenu* pPopup)
+{
+ for(USHORT i = 0; i < pPopup->GetItemCount(); i++)
+ {
+ PopupMenu* pSubPopup = pPopup->GetPopupMenu( pPopup->GetItemId( i ));
+ if(pSubPopup)
+ {
+ lcl_DeleteSubPopups(pSubPopup);
+ delete pSubPopup;
+ }
+ }
+}
+
+bool SvImpLBox::Command( const CommandEvent& rCEvt )
+{
+ USHORT nCommand = rCEvt.GetCommand();
+
+ if( nCommand == COMMAND_CONTEXTMENU )
+ aEditTimer.Stop();
+
+ // Rollmaus-Event?
+ if ( ( ( nCommand == COMMAND_WHEEL )
+ || ( nCommand == COMMAND_STARTAUTOSCROLL )
+ || ( nCommand == COMMAND_AUTOSCROLL )
+ )
+ && pView->HandleScrollCommand( rCEvt, &aHorSBar, &aVerSBar )
+ )
+ {
+ return true;
+ }
+
+ if ( ( nCommand == COMMAND_CONTEXTMENU )
+ && !bContextMenuHandling
+ )
+ {
+ return false;
+ }
+
+ if( bContextMenuHandling && nCommand == COMMAND_CONTEXTMENU )
+ {
+ Point aPopupPos;
+ BOOL bClickedIsFreePlace = FALSE;
+ std::stack<SvLBoxEntry*> aSelRestore;
+
+ if( rCEvt.IsMouseEvent() )
+ { // change selection, if mouse pos doesn't fit to selection
+
+ aPopupPos = rCEvt.GetMousePosPixel();
+
+ SvLBoxEntry* pClickedEntry = GetEntry( aPopupPos );
+ if( pClickedEntry )
+ { // mouse in non empty area
+ BOOL bClickedIsSelected = FALSE;
+
+ // collect the currently selected entries
+ SvLBoxEntry* pSelected = pView->FirstSelected();
+ while( pSelected )
+ {
+ bClickedIsSelected |= ( pClickedEntry == pSelected );
+ pSelected = pView->NextSelected( pSelected );
+ }
+
+ // if the entry which the user clicked at is not selected
+ if( !bClickedIsSelected )
+ { // deselect all other and select the clicked one
+ pView->SelectAll( FALSE );
+ pView->SetCursor( pClickedEntry );
+ }
+ }
+ else if( aSelEng.GetSelectionMode() == SINGLE_SELECTION )
+ {//modified by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time)
+ bClickedIsFreePlace = TRUE;
+ INT32 nSelectedEntries = pView->GetSelectionCount();
+ SvLBoxEntry* pSelected = pView->FirstSelected();
+ for(USHORT nSel = 0; nSel < nSelectedEntries; nSel++ )
+ {
+ aSelRestore.push(pSelected);
+ pSelected = pView->NextSelected( pSelected );
+ }
+ pView->SelectAll( FALSE );
+ }
+ else
+ { // deselect all
+ pView->SelectAll( FALSE );
+ }
+ }
+ else
+ { // key event (or at least no mouse event)
+ INT32 nSelectionCount = pView->GetSelectionCount();
+
+ if( nSelectionCount )
+ { // now allways take first visible as base for positioning the menu
+ SvLBoxEntry* pSelected = pView->FirstSelected();
+ while( pSelected )
+ {
+ if( IsEntryInView( pSelected ) )
+ break;
+
+ pSelected = pView->NextSelected( pSelected );
+ }
+
+ if( !pSelected )
+ {
+ // no one was visible
+ pSelected = pView->FirstSelected();
+ pView->MakeVisible( pSelected );
+ }
+
+ aPopupPos = pView->GetFocusRect( pSelected, pView->GetEntryPosition( pSelected ).Y() ).Center();
+ }
+ else
+ aPopupPos = Point( 0, 0 );
+ }
+
+ PopupMenu* pPopup = pView->CreateContextMenu();
+
+ if( pPopup )
+ {
+ // do action for selected entry in popup menu
+ USHORT nMenuAction = pPopup->Execute( pView, aPopupPos );
+ if ( nMenuAction )
+ pView->ExcecuteContextMenuAction( nMenuAction );
+ lcl_DeleteSubPopups(pPopup);
+ delete pPopup;
+ }
+ //added by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time)
+ if( bClickedIsFreePlace )
+ {
+ while(!aSelRestore.empty())
+ {
+ SvLBoxEntry* pEntry = aSelRestore.top();
+ //#i19717# the entry is maybe already deleted
+ bool bFound = false;
+ for(ULONG nEntry = 0; nEntry < pView->GetEntryCount(); nEntry++)
+ if(pEntry == pView->GetEntry(nEntry))
+ {
+ bFound = true;
+ break;
+ }
+ if(bFound)
+ SetCurEntry( pEntry );
+ aSelRestore.pop();
+ }
+ }
+ return true;
+ }
+
+ const Point& rPos = rCEvt.GetMousePosPixel();
+ if( rPos.X() < aOutputSize.Width() && rPos.Y() < aOutputSize.Height() )
+ aSelEng.Command( rCEvt );
+
+ // strictly, this is not correct. However, it leads to a behavior compatible to the one at the time
+ // when this method did have a void return value ...
+ // A proper solution would be to give the EditEngine::Command also a boolean return value, and forward
+ // this (or false) to our caller
+ return true;
+}
+
+void SvImpLBox::BeginScroll()
+{
+ if( !(nFlags & F_IN_SCROLLING))
+ {
+ pView->NotifyBeginScroll();
+ nFlags |= F_IN_SCROLLING;
+ }
+}
+
+void SvImpLBox::EndScroll()
+{
+ if( nFlags & F_IN_SCROLLING)
+ {
+ pView->NotifyEndScroll();
+ nFlags &= (~F_IN_SCROLLING);
+ }
+}
+
+
+Rectangle SvImpLBox::GetVisibleArea() const
+{
+ Point aPos( pView->GetMapMode().GetOrigin() );
+ aPos.X() *= -1;
+ Rectangle aRect( aPos, aOutputSize );
+ return aRect;
+}
+
+void SvImpLBox::Invalidate()
+{
+ pView->SetClipRegion();
+}
+
+void SvImpLBox::SetCurEntry( SvLBoxEntry* pEntry )
+{
+ if ( ( aSelEng.GetSelectionMode() != SINGLE_SELECTION )
+ && ( aSelEng.GetSelectionMode() != NO_SELECTION )
+ )
+ SelAllDestrAnch( FALSE, TRUE, FALSE );
+ if ( pEntry )
+ MakeVisible( pEntry );
+ SetCursor( pEntry );
+ if ( pEntry && ( aSelEng.GetSelectionMode() != NO_SELECTION ) )
+ pView->Select( pEntry, TRUE );
+}
+
+IMPL_LINK( SvImpLBox, EditTimerCall, Timer *, EMPTYARG )
+{
+ if( pView->IsInplaceEditingEnabled() )
+ {
+ sal_Bool bIsMouseTriggered = aEditClickPos.X() >= 0;
+ if ( bIsMouseTriggered )
+ {
+ Point aCurrentMousePos = pView->GetPointerPosPixel();
+ if ( ( abs( aCurrentMousePos.X() - aEditClickPos.X() ) > 5 )
+ || ( abs( aCurrentMousePos.Y() - aEditClickPos.Y() ) > 5 )
+ )
+ {
+ return 0L;
+ }
+ }
+
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if( pEntry )
+ {
+ ShowCursor( FALSE );
+ pView->ImplEditEntry( pEntry );
+ ShowCursor( TRUE );
+ }
+ }
+ return 0;
+}
+
+BOOL SvImpLBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ if( rHEvt.GetMode() & HELPMODE_QUICK )
+ {
+ Point aPos( pView->ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
+ if( !GetVisibleArea().IsInside( aPos ))
+ return FALSE;
+
+ SvLBoxEntry* pEntry = GetEntry( aPos );
+ if( pEntry )
+ {
+ // Rechteck des Textes berechnen
+ SvLBoxTab* pTab;
+ SvLBoxString* pItem = (SvLBoxString*)(pView->GetItem( pEntry, aPos.X(), &pTab ));
+ if( !pItem || pItem->IsA() != SV_ITEM_ID_LBOXSTRING )
+ return FALSE;
+
+ aPos = GetEntryPosition( pEntry );
+ aPos.X() = pView->GetTabPos( pEntry, pTab ); //pTab->GetPos();
+ Size aSize( pItem->GetSize( pView, pEntry ) );
+ SvLBoxTab* pNextTab = NextTab( pTab );
+ BOOL bItemClipped = FALSE;
+ // wurde das Item von seinem rechten Nachbarn abgeschnitten?
+ if( pNextTab && pView->GetTabPos(pEntry,pNextTab) < aPos.X()+aSize.Width() )
+ {
+ aSize.Width() = pNextTab->GetPos() - pTab->GetPos();
+ bItemClipped = TRUE;
+ }
+ Rectangle aItemRect( aPos, aSize );
+
+ Rectangle aViewRect( GetVisibleArea() );
+
+ if( bItemClipped || !aViewRect.IsInside( aItemRect ) )
+ {
+ // rechten Item-Rand am View-Rand clippen
+ //if( aItemRect.Right() > aViewRect.Right() )
+ // aItemRect.Right() = aViewRect.Right();
+
+ Point aPt = pView->OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = pView->OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+
+ Help::ShowQuickHelp( pView, aItemRect,
+ pItem->GetText(), QUICKHELP_LEFT | QUICKHELP_VCENTER );
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+SvLBoxTab* SvImpLBox::NextTab( SvLBoxTab* pTab )
+{
+ USHORT nTabCount = pView->TabCount();
+ if( nTabCount <= 1 )
+ return 0;
+ for( USHORT nTab=0; nTab < (nTabCount-1); nTab++)
+ {
+ if( pView->aTabs[nTab]==pTab )
+ return (SvLBoxTab*)(pView->aTabs[nTab+1]);
+ }
+ return 0;
+}
+
+void SvImpLBox::EndSelection()
+{
+ DestroyAnchor();
+ nFlags &= ~F_START_EDITTIMER;
+}
+
+void SvImpLBox::RepaintScrollBars()
+{
+}
+
+void SvImpLBox::SetUpdateMode( BOOL bMode )
+{
+ if( bUpdateMode != bMode )
+ {
+ bUpdateMode = bMode;
+ if( bUpdateMode )
+ UpdateAll( FALSE );
+ }
+}
+
+void SvImpLBox::SetUpdateModeFast( BOOL bMode )
+{
+ if( bUpdateMode != bMode )
+ {
+ bUpdateMode = bMode;
+ if( bUpdateMode )
+ UpdateAll( FALSE, FALSE );
+ }
+}
+
+
+BOOL SvImpLBox::SetMostRight( SvLBoxEntry* pEntry )
+{
+ if( pView->nTreeFlags & TREEFLAG_RECALCTABS )
+ {
+ nFlags |= F_IGNORE_CHANGED_TABS;
+ pView->SetTabs();
+ nFlags &= ~F_IGNORE_CHANGED_TABS;
+ }
+
+ USHORT nLastTab = pView->aTabs.Count() - 1;
+ USHORT nLastItem = pEntry->ItemCount() - 1;
+ if( nLastTab != USHRT_MAX && nLastItem != USHRT_MAX )
+ {
+ if( nLastItem < nLastTab )
+ nLastTab = nLastItem;
+
+ SvLBoxTab* pTab = (SvLBoxTab*)pView->aTabs[ nLastTab ];
+ SvLBoxItem* pItem = pEntry->GetItem( nLastTab );
+
+ long nTabPos = pView->GetTabPos( pEntry, pTab );
+
+ long nMaxRight = GetOutputSize().Width();
+ Point aPos( pView->GetMapMode().GetOrigin() );
+ aPos.X() *= -1; // Umrechnung Dokumentkoord.
+ nMaxRight = nMaxRight + aPos.X() - 1;
+
+ long nNextTab = nTabPos < nMaxRight ? nMaxRight : nMaxRight + 50;
+ long nTabWidth = nNextTab - nTabPos + 1;
+ long nItemSize = pItem->GetSize(pView,pEntry).Width();
+ long nOffset = pTab->CalcOffset( nItemSize, nTabWidth );
+
+ long nRight = nTabPos + nOffset + nItemSize;
+ if( nRight > nMostRight )
+ {
+ nMostRight = nRight;
+ pMostRightEntry = pEntry;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void SvImpLBox::FindMostRight( SvLBoxEntry* pEntryToIgnore )
+{
+ nMostRight = -1;
+ pMostRightEntry = 0;
+ if( !pView->GetModel() )
+ return;
+
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pView->FirstVisible();
+ while( pEntry )
+ {
+ if( pEntry != pEntryToIgnore )
+ SetMostRight( pEntry );
+ pEntry = (SvLBoxEntry*)pView->NextVisible( pEntry );
+ }
+}
+
+void SvImpLBox::FindMostRight( SvLBoxEntry* pParent, SvLBoxEntry* pEntryToIgnore )
+{
+ if( !pParent )
+ FindMostRight( pEntryToIgnore );
+ else
+ FindMostRight_Impl( pParent, pEntryToIgnore );
+}
+
+void SvImpLBox::FindMostRight_Impl( SvLBoxEntry* pParent, SvLBoxEntry* pEntryToIgnore )
+{
+ SvTreeEntryList* pList = pTree->GetChildList( pParent );
+
+ if( !pList )
+ return;
+
+ ULONG nCount = pList->Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvLBoxEntry* pChild = (SvLBoxEntry*)pList->GetObject( nCur );
+ if( pChild != pEntryToIgnore )
+ {
+ SetMostRight( pChild );
+ if( pChild->HasChilds() && pView->IsExpanded( pChild ))
+ FindMostRight_Impl( pChild, pEntryToIgnore );
+ }
+ }
+}
+
+void SvImpLBox::NotifyTabsChanged()
+{
+ if( GetUpdateMode() && !(nFlags & F_IGNORE_CHANGED_TABS ) &&
+ nCurUserEvent == 0xffffffff )
+ {
+ nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent),(void*)0);
+ }
+}
+
+IMPL_LINK(SvImpLBox,MyUserEvent,void*, pArg )
+{
+ nCurUserEvent = 0xffffffff;
+ if( !pArg )
+ {
+ pView->Invalidate();
+ pView->Update();
+ }
+ else
+ {
+ FindMostRight( 0 );
+ ShowVerSBar();
+ pView->Invalidate( GetVisibleArea() );
+ }
+ return 0;
+}
+
+
+void SvImpLBox::StopUserEvent()
+{
+ if( nCurUserEvent != 0xffffffff )
+ {
+ Application::RemoveUserEvent( nCurUserEvent );
+ nCurUserEvent = 0xffffffff;
+ }
+}
+
+void SvImpLBox::ShowFocusRect( const SvLBoxEntry* pEntry )
+{
+ if( pEntry )
+ {
+ long nY = GetEntryLine( (SvLBoxEntry*)pEntry );
+ Rectangle aRect = pView->GetFocusRect( (SvLBoxEntry*)pEntry, nY );
+ Region aOldClip( pView->GetClipRegion());
+ Region aClipRegion( GetClipRegionRect() );
+ pView->SetClipRegion( aClipRegion );
+ pView->ShowFocus( aRect );
+ pView->SetClipRegion( aOldClip );
+
+ }
+ else
+ {
+ pView->HideFocus();
+ }
+}
+
+void SvImpLBox::SetTabBar( TabBar* _pTabBar )
+{
+ pTabBar = _pTabBar;
+}
+
+void SvImpLBox::CancelPendingEdit()
+{
+ if( aEditTimer.IsActive() )
+ aEditTimer.Stop();
+ nFlags &= ~F_START_EDITTIMER;
+}
+
+// -----------------------------------------------------------------------
+void SvImpLBox::implInitDefaultNodeImages()
+{
+ if ( s_pDefCollapsed )
+ // assume that all or nothing is initialized
+ return;
+
+ s_pDefCollapsed = new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED ) );
+ s_pDefCollapsedHC = new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED_HC ) );
+ s_pDefExpanded = new Image( SvtResId( RID_IMG_TREENODE_EXPANDED ) );
+ s_pDefExpandedHC = new Image( SvtResId( RID_IMG_TREENODE_EXPANDED_HC ) );
+}
+
+// -----------------------------------------------------------------------
+const Image& SvImpLBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode )
+{
+ implInitDefaultNodeImages();
+ return ( BMP_COLOR_NORMAL == _eMode ) ? *s_pDefExpanded : *s_pDefExpandedHC;
+}
+
+// -----------------------------------------------------------------------
+const Image& SvImpLBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode )
+{
+ implInitDefaultNodeImages();
+ return ( BMP_COLOR_NORMAL == _eMode ) ? *s_pDefCollapsed : *s_pDefCollapsedHC;
+}
+
+// -----------------------------------------------------------------------
+void SvImpLBox::CallEventListeners( ULONG nEvent, void* pData )
+{
+ if ( pView )
+ pView->CallImplEventListeners( nEvent, pData);
+}
+
+// -----------------------------------------------------------------------
+
+bool SvImpLBox::SetCurrentTabPos( USHORT _nNewPos )
+{
+ bool bRet = false;
+
+ if ( pView && _nNewPos < ( pView->TabCount() - 2 ) )
+ {
+ nCurTabPos = _nNewPos;
+ ShowCursor( TRUE );
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+bool SvImpLBox::IsSelectable( const SvLBoxEntry* pEntry )
+{
+ if( pEntry )
+ {
+ SvViewDataEntry* pViewDataNewCur = pView->GetViewDataEntry(const_cast<SvLBoxEntry*>(pEntry));
+ return (pViewDataNewCur == 0) || pViewDataNewCur->IsSelectable();
+ }
+ else
+ {
+ return false;
+ }
+}
+
diff --git a/svtools/source/contnr/svimpicn.cxx b/svtools/source/contnr/svimpicn.cxx
new file mode 100644
index 000000000000..2d4c9cf2df0e
--- /dev/null
+++ b/svtools/source/contnr/svimpicn.cxx
@@ -0,0 +1,4167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <limits.h>
+#ifndef _METRIC_HXX
+#include <vcl/metric.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#ifdef DBG_UTIL
+#include <vcl/sound.hxx>
+#endif
+
+#include <svtools/svlbox.hxx>
+#include <svtools/svicnvw.hxx>
+#include <svimpicn.hxx>
+#ifndef _SVLBITM_HXX
+#include <svtools/svlbitm.hxx>
+#endif
+#include <svl/svarray.hxx>
+
+
+
+#define VIEWMODE_ICON 0x0001 // Text unter Bitmap
+#define VIEWMODE_NAME 0x0002 // Text rechts neben Bitmap
+#define VIEWMODE_TEXT 0x0004 // Text ohne Bitmap
+
+#define DD_SCROLL_PIXEL 10
+
+// alle Angaben in Pixel
+
+#define ICONVIEW_OFFS_BMP_STRING 3
+
+// fuer das Bounding-Rectangle
+#define LROFFS_BOUND 2
+#define TBOFFS_BOUND 2
+
+// fuer das Focus-Rectangle um Icons
+#define LROFFS_ICON 2
+#define TBOFFS_ICON 2
+
+#define NAMEVIEW_OFFS_BMP_STRING 3
+
+// Abstaende von Fensterraendern
+#define LROFFS_WINBORDER 4
+#define TBOFFS_WINBORDER 4
+
+// Breitenoffset Highlight-Rect bei Text
+#define LROFFS_TEXT 2
+
+
+#define ICNVIEWDATA(xPtr) (SvIcnVwDataEntry*)(pView->GetViewDataEntry(xPtr))
+#define ICNVIEWDATA2(xPtr) (SvIcnVwDataEntry*)(pView->pView->GetViewDataEntry(xPtr))
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+// Hilfsfunktionen von Thomas Hosemann zur mehrzeiligen Ausgabe von
+// Strings. Die Funktionen werden spaeter in StarView integriert.
+// -------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+// keine doppelten Defines
+#ifdef TEXT_DRAW_CLIP
+#undef TEXT_DRAW_CLIP
+#endif
+#ifdef TEXT_DRAW_MULTILINE
+#undef TEXT_DRAW_MULTILINE
+#endif
+#ifdef TEXT_DRAW_WORDBREAK
+#undef TEXT_DRAW_WORDBREAK
+#endif
+
+// #define TEXT_DRAW_DISABLE ((USHORT)0x0001)
+// #define TEXT_DRAW_3DLOOK ((USHORT)0x0002)
+// #define TEXT_DRAW_MNEMONIC ((USHORT)0x0004)
+#define TEXT_DRAW_LEFT ((USHORT)0x0010)
+#define TEXT_DRAW_CENTER ((USHORT)0x0020)
+#define TEXT_DRAW_RIGHT ((USHORT)0x0040)
+#define TEXT_DRAW_TOP ((USHORT)0x0080)
+#define TEXT_DRAW_VCENTER ((USHORT)0x0100)
+#define TEXT_DRAW_BOTTOM ((USHORT)0x0200)
+#define TEXT_DRAW_ENDELLIPSIS ((USHORT)0x0400)
+#define TEXT_DRAW_PATHELLIPSIS ((USHORT)0x0800)
+#define TEXT_DRAW_CLIP ((USHORT)0x1000)
+#define TEXT_DRAW_MULTILINE ((USHORT)0x2000)
+#define TEXT_DRAW_WORDBREAK ((USHORT)0x4000)
+
+XubString GetEllipsisString( OutputDevice* pDev,
+ const XubString& rStr, long nMaxWidth,
+ USHORT nStyle = TEXT_DRAW_ENDELLIPSIS )
+{
+ XubString aStr = rStr;
+
+ if ( nStyle & TEXT_DRAW_ENDELLIPSIS )
+ {
+ USHORT nIndex = pDev->GetTextBreak( rStr, nMaxWidth );
+ if ( nIndex != STRING_LEN )
+ {
+ aStr.Erase( nIndex );
+ if ( nIndex > 1 )
+ {
+ aStr.AppendAscii("...");
+ while ( aStr.Len() &&
+ (pDev->GetTextWidth( aStr ) > nMaxWidth) )
+ {
+ if ( (nIndex > 1) || (nIndex == aStr.Len()) )
+ nIndex--;
+ aStr.Erase( nIndex, 1 );
+ }
+ }
+
+ if ( !aStr.Len() && (nStyle & TEXT_DRAW_CLIP) )
+ aStr += rStr.GetChar( 0 );
+ }
+ }
+
+ return aStr;
+}
+
+class TextLineInfo
+{
+private:
+ long mnWidth;
+ USHORT mnIndex;
+ USHORT mnLen;
+
+public:
+ TextLineInfo( long nWidth, USHORT nIndex, USHORT nLen )
+ {
+ mnWidth = nWidth;
+ mnIndex = nIndex;
+ mnLen = nLen;
+ }
+
+ long GetWidth() const { return mnWidth; }
+ USHORT GetIndex() const { return mnIndex; }
+ USHORT GetLen() const { return mnLen; }
+};
+
+#define MULTITEXTLINEINFO_RESIZE 16
+typedef TextLineInfo* PTextLineInfo;
+
+class MultiTextLineInfo
+{
+private:
+ PTextLineInfo* mpLines;
+ USHORT mnLines;
+ USHORT mnSize;
+
+public:
+ MultiTextLineInfo();
+ ~MultiTextLineInfo();
+
+ void AddLine( TextLineInfo* pLine );
+ void Clear();
+
+ TextLineInfo* GetLine( USHORT nLine ) const
+ { return mpLines[nLine]; }
+ USHORT Count() const { return mnLines; }
+
+private:
+ MultiTextLineInfo( const MultiTextLineInfo& );
+ MultiTextLineInfo& operator=( const MultiTextLineInfo& );
+};
+
+MultiTextLineInfo::MultiTextLineInfo()
+{
+ mpLines = new PTextLineInfo[MULTITEXTLINEINFO_RESIZE];
+ mnLines = 0;
+ mnSize = MULTITEXTLINEINFO_RESIZE;
+}
+
+MultiTextLineInfo::~MultiTextLineInfo()
+{
+ for ( USHORT i = 0; i < mnLines; i++ )
+ delete mpLines[i];
+ delete [] mpLines;
+}
+
+void MultiTextLineInfo::AddLine( TextLineInfo* pLine )
+{
+ if ( mnSize == mnLines )
+ {
+ mnSize += MULTITEXTLINEINFO_RESIZE;
+ PTextLineInfo* pNewLines = new PTextLineInfo[mnSize];
+ memcpy( pNewLines, mpLines, mnLines*sizeof(PTextLineInfo) );
+ mpLines = pNewLines;
+ }
+
+ mpLines[mnLines] = pLine;
+ mnLines++;
+}
+
+void MultiTextLineInfo::Clear()
+{
+ for ( USHORT i = 0; i < mnLines; i++ )
+ delete mpLines[i];
+ mnLines = 0;
+}
+
+// -----------------------------------------------------------------------
+
+long GetTextLines( OutputDevice* pDev, MultiTextLineInfo& rLineInfo,
+ long nWidth, const XubString& rStr,
+ USHORT nStyle = TEXT_DRAW_WORDBREAK )
+{
+ rLineInfo.Clear();
+ if ( !rStr.Len() )
+ return 0;
+ if ( nWidth <= 0 )
+ nWidth = 1;
+
+ USHORT nStartPos = 0; // Start-Position der Zeile
+ USHORT nLastLineLen = 0; // Zeilenlaenge bis zum vorherigen Wort
+ USHORT nLastWordPos = 0; // Position des letzten Wortanfangs
+ USHORT i = 0;
+ USHORT nPos; // StartPositon der Zeile (nur Temp)
+ USHORT nLen; // Laenge der Zeile (nur Temp)
+ USHORT nStrLen = rStr.Len();
+ long nMaxLineWidth = 0; // Maximale Zeilenlaenge
+ long nLineWidth; // Aktuelle Zeilenlaenge
+ long nLastLineWidth = 0; // Zeilenlaenge der letzten Zeile
+ xub_Unicode c;
+ xub_Unicode c2;
+ const xub_Unicode* pStr = rStr.GetBuffer();
+ BOOL bHardBreak = FALSE;
+
+ do
+ {
+ c = pStr[i];
+
+ // Auf Zeilenende ermitteln
+ if ( (c == _CR) || (c == _LF) )
+ bHardBreak = TRUE;
+ else
+ bHardBreak = FALSE;
+
+ // Testen, ob ein Wortende erreicht ist
+ if ( bHardBreak || (i == nStrLen) ||
+ (((c == ' ') || (c == '-')) && (nStyle & TEXT_DRAW_WORDBREAK)) )
+ {
+ nLen = i-nStartPos;
+ if ( c == '-' )
+ nLen++;
+ nLineWidth = pDev->GetTextWidth( rStr, nStartPos, nLen );
+
+ // Findet ein Zeilenumbruch statt
+ if ( bHardBreak || (i == nStrLen) ||
+ ((nLineWidth >= nWidth) && (nStyle & TEXT_DRAW_WORDBREAK)) )
+ {
+ nPos = nStartPos;
+
+ if ( (nLineWidth >= nWidth) && (nStyle & TEXT_DRAW_WORDBREAK) )
+ {
+ nLineWidth = nLastLineWidth;
+ nLen = nLastLineLen;
+ nStartPos = nLastWordPos;
+ nLastLineLen = i-nStartPos;
+ nLastWordPos = nStartPos+nLastLineLen+1;
+ if ( c == '-' )
+ nLastLineLen++;
+ else if ( bHardBreak && (i > nStartPos) )
+ i--;
+ }
+ else
+ {
+ nStartPos = i;
+ // Zeilenende-Zeichen und '-' beruecksichtigen
+ if ( bHardBreak )
+ {
+ nStartPos++;
+ c2 = pStr[i+1];
+ if ( (c != c2) && ((c2 == _CR) || (c2 == _LF)) )
+ {
+ nStartPos++;
+ i++;
+ }
+ }
+ else if ( c != '-' )
+ nStartPos++;
+ nLastWordPos = nStartPos;
+ nLastLineLen = 0;
+ }
+
+ if ( nLineWidth > nMaxLineWidth )
+ nMaxLineWidth = nLineWidth;
+
+ if ( nLen || bHardBreak )
+ rLineInfo.AddLine( new TextLineInfo( nLineWidth, nPos, nLen ) );
+
+ // Testen, ob aktuelles Wort noch auf die Zeile passt,
+ // denn ansonsten mueessen wir es auftrennen
+ if ( nLastLineLen )
+ {
+ nLineWidth = pDev->GetTextWidth( rStr, nStartPos, nLastLineLen );
+ if ( nLineWidth > nWidth )
+ {
+ // Wenn ein Wortumbruch in einem Wort stattfindet,
+ // ist die maximale Zeilenlaenge die Laenge
+ // des laengsten Wortes
+ if ( nLineWidth > nMaxLineWidth )
+ nMaxLineWidth = nLineWidth;
+
+ // Solange Wort auftrennen, bis es auf eine Zeile passt
+ do
+ {
+ nPos = pDev->GetTextBreak( rStr, nWidth, nStartPos, nLastLineLen );
+ nLen = nPos-nStartPos;
+ if ( !nLen )
+ {
+ nPos++;
+ nLen++;
+ }
+ nLineWidth = pDev->GetTextWidth( rStr, nStartPos, nLen );
+ rLineInfo.AddLine( new TextLineInfo( nLineWidth, nStartPos, nLen ) );
+ nStartPos = nPos;
+ nLastLineLen = nLastLineLen - nLen;
+ nLineWidth = pDev->GetTextWidth( rStr, nStartPos, nLastLineLen );
+ }
+ while ( nLineWidth > nWidth );
+ }
+ nLastLineWidth = nLineWidth;
+
+ // Bei Stringende muessen wir die letzte Zeile auch noch
+ // dranhaengen
+ if ( (i == nStrLen) && nLastLineLen )
+ rLineInfo.AddLine( new TextLineInfo( nLastLineWidth, nStartPos, nLastLineLen ) );
+ }
+ else
+ nLastLineWidth = 0;
+ }
+ else
+ {
+ nLastLineWidth = nLineWidth;
+ nLastLineLen = nLen;
+ nLastWordPos = nStartPos+nLastLineLen;
+ if ( c != '-' )
+ nLastWordPos++;
+ }
+ }
+
+ i++;
+ }
+ while ( i <= nStrLen );
+
+ return nMaxLineWidth;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT GetTextLines( OutputDevice* pDev, const Rectangle& rRect,
+ const XubString& rStr,
+ USHORT nStyle = TEXT_DRAW_WORDBREAK,
+ long* pMaxWidth = NULL )
+{
+ MultiTextLineInfo aMultiLineInfo;
+ long nMaxWidth = GetTextLines( pDev, aMultiLineInfo,
+ rRect.GetWidth(), rStr, nStyle );
+ if ( pMaxWidth )
+ *pMaxWidth = nMaxWidth;
+ return aMultiLineInfo.Count();
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle GetTextRect( OutputDevice* pDev, const Rectangle& rRect,
+ const XubString& rStr,
+ USHORT nStyle = TEXT_DRAW_WORDBREAK )
+{
+ Rectangle aRect = rRect;
+ USHORT nLines;
+ long nWidth = rRect.GetWidth();
+ long nMaxWidth;
+ long nTextHeight;
+
+ if ( nStyle & TEXT_DRAW_MULTILINE )
+ {
+ MultiTextLineInfo aMultiLineInfo;
+ TextLineInfo* pLineInfo;
+ USHORT nFormatLines;
+
+ nMaxWidth = 0;
+ GetTextLines( pDev, aMultiLineInfo, nWidth, rStr, nStyle );
+ nFormatLines = aMultiLineInfo.Count();
+ nTextHeight = pDev->GetTextHeight();
+ nLines = (USHORT)(aRect.GetHeight()/nTextHeight);
+ if ( nFormatLines <= nLines )
+ nLines = nFormatLines;
+ else
+ {
+ if ( !(nStyle & TEXT_DRAW_ENDELLIPSIS) )
+ nLines = nFormatLines;
+ else
+ nMaxWidth = nWidth;
+ }
+ for ( USHORT i = 0; i < nLines; i++ )
+ {
+ pLineInfo = aMultiLineInfo.GetLine( i );
+ if ( pLineInfo->GetWidth() > nMaxWidth )
+ nMaxWidth = pLineInfo->GetWidth();
+ }
+ }
+ else
+ {
+ nLines = 1;
+ nMaxWidth = pDev->GetTextWidth( rStr );
+ nTextHeight = pDev->GetTextHeight();
+ if ( (nMaxWidth > nWidth) && (nStyle & TEXT_DRAW_ENDELLIPSIS) )
+ nMaxWidth = nWidth;
+ }
+
+ if ( nStyle & TEXT_DRAW_RIGHT )
+ aRect.Left() = aRect.Right()-nMaxWidth+1;
+ else if ( nStyle & TEXT_DRAW_CENTER )
+ {
+ aRect.Left() += (nWidth-nMaxWidth)/2;
+ aRect.Right() = aRect.Left()+nMaxWidth-1;
+ }
+ else
+ aRect.Right() = aRect.Left()+nMaxWidth-1;
+
+ if ( nStyle & TEXT_DRAW_BOTTOM )
+ aRect.Top() = aRect.Bottom()-(nTextHeight*nLines)+1;
+ else if ( nStyle & TEXT_DRAW_VCENTER )
+ {
+ aRect.Top() += (aRect.GetHeight()-(nTextHeight*nLines))/2;
+ aRect.Bottom() = aRect.Top()+(nTextHeight*nLines)-1;
+ }
+ else
+ aRect.Bottom() = aRect.Top()+(nTextHeight*nLines)-1;
+
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void DrawText( OutputDevice* pDev, const Rectangle& rRect,
+ const XubString& rStr, USHORT nStyle = 0 )
+{
+ if ( !rStr.Len() || rRect.IsEmpty() )
+ return;
+
+ Point aPos = rRect.TopLeft();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ FontAlign eAlign = pDev->GetFont().GetAlign();
+
+ if ( ((nWidth <= 0) || (nHeight <= 0)) && (nStyle & TEXT_DRAW_CLIP) )
+ return;
+
+ // Mehrzeiligen Text behandeln wir anders
+ if ( nStyle & TEXT_DRAW_MULTILINE )
+ {
+ String aLastLine;
+ Region aOldRegion;
+ MultiTextLineInfo aMultiLineInfo;
+ TextLineInfo* pLineInfo;
+ long nTextHeight = pDev->GetTextHeight();
+ long nMaxTextWidth;
+ USHORT i;
+ USHORT nLines = (USHORT)(nHeight/nTextHeight);
+ USHORT nFormatLines;
+ BOOL bIsClipRegion = FALSE;
+ nMaxTextWidth = GetTextLines( pDev, aMultiLineInfo, nWidth, rStr, nStyle );
+
+ nFormatLines = aMultiLineInfo.Count();
+ if ( nFormatLines > nLines )
+ {
+ if ( nStyle & TEXT_DRAW_ENDELLIPSIS )
+ {
+ // Letzte Zeile zusammenbauen und kuerzen
+ nFormatLines = nLines-1;
+ pLineInfo = aMultiLineInfo.GetLine( nFormatLines );
+ aLastLine = rStr.Copy( pLineInfo->GetIndex() );
+ aLastLine.ConvertLineEnd( LINEEND_LF );
+ aLastLine.SearchAndReplace( _LF, ' ' );
+ aLastLine = GetEllipsisString( pDev, aLastLine, nWidth, nStyle );
+ nStyle &= ~(TEXT_DRAW_VCENTER | TEXT_DRAW_BOTTOM);
+ nStyle |= TEXT_DRAW_TOP;
+ }
+ }
+ else
+ {
+ if ( nMaxTextWidth <= nWidth )
+ nStyle &= ~TEXT_DRAW_CLIP;
+ }
+
+ // Clipping setzen
+ if ( nStyle & TEXT_DRAW_CLIP )
+ {
+ bIsClipRegion = pDev->IsClipRegion();
+ if ( bIsClipRegion )
+ {
+ aOldRegion = pDev->GetClipRegion();
+ pDev->IntersectClipRegion( rRect );
+ }
+ else
+ {
+ Region aRegion( rRect );
+ pDev->SetClipRegion( aRegion );
+ }
+ }
+
+ // Vertikales Alignment
+ if ( nStyle & TEXT_DRAW_BOTTOM )
+ aPos.Y() += nHeight-(nFormatLines*nTextHeight);
+ else if ( nStyle & TEXT_DRAW_VCENTER )
+ aPos.Y() += (nHeight-(nFormatLines*nTextHeight))/2;
+
+ // Font Alignment
+ if ( eAlign == ALIGN_BOTTOM )
+ aPos.Y() += nTextHeight;
+ else if ( eAlign == ALIGN_BASELINE )
+ aPos.Y() += pDev->GetFontMetric().GetAscent();
+
+ // Alle Zeilen ausgeben, bis auf die letzte
+ for ( i = 0; i < nFormatLines; i++ )
+ {
+ pLineInfo = aMultiLineInfo.GetLine( i );
+ if ( nStyle & TEXT_DRAW_RIGHT )
+ aPos.X() += nWidth-pLineInfo->GetWidth();
+ else if ( nStyle & TEXT_DRAW_CENTER )
+ aPos.X() += (nWidth-pLineInfo->GetWidth())/2;
+ pDev->DrawText( aPos, rStr, pLineInfo->GetIndex(), pLineInfo->GetLen() );
+ aPos.Y() += nTextHeight;
+ aPos.X() = rRect.Left();
+ }
+
+ // Gibt es noch eine letzte Zeile, dann diese linksbuendig ausgeben,
+ // da die Zeile gekuerzt wurde
+ if ( aLastLine.Len() )
+ pDev->DrawText( aPos, aLastLine );
+
+ // Clipping zuruecksetzen
+ if ( nStyle & TEXT_DRAW_CLIP )
+ {
+ if ( bIsClipRegion )
+ pDev->SetClipRegion( aOldRegion );
+ else
+ pDev->SetClipRegion();
+ }
+ }
+ else
+ {
+ XubString aStr = rStr;
+ Size aTextSize(pDev->GetTextWidth( aStr ), pDev->GetTextHeight());
+
+ // Evt. Text kuerzen
+ if ( aTextSize.Width() > nWidth )
+ {
+ if ( nStyle & TEXT_DRAW_ENDELLIPSIS )
+ {
+ aStr = GetEllipsisString( pDev, rStr, nWidth, nStyle );
+ nStyle &= ~(TEXT_DRAW_CENTER | TEXT_DRAW_RIGHT);
+ nStyle |= TEXT_DRAW_LEFT;
+ aTextSize.Width() = pDev->GetTextWidth(aStr);
+ }
+ }
+ else
+ {
+ if ( aTextSize.Height() <= nHeight )
+ nStyle &= ~TEXT_DRAW_CLIP;
+ }
+
+ // Vertikales Alignment
+ if ( nStyle & TEXT_DRAW_RIGHT )
+ aPos.X() += nWidth-aTextSize.Width();
+ else if ( nStyle & TEXT_DRAW_CENTER )
+ aPos.X() += (nWidth-aTextSize.Width())/2;
+
+ // Font Alignment
+ if ( eAlign == ALIGN_BOTTOM )
+ aPos.Y() += aTextSize.Height();
+ else if ( eAlign == ALIGN_BASELINE )
+ aPos.Y() += pDev->GetFontMetric().GetAscent();
+
+ if ( nStyle & TEXT_DRAW_BOTTOM )
+ aPos.Y() += nHeight-aTextSize.Height();
+ else if ( nStyle & TEXT_DRAW_VCENTER )
+ aPos.Y() += (nHeight-aTextSize.Height())/2;
+
+ if ( nStyle & TEXT_DRAW_CLIP )
+ {
+ BOOL bIsClipRegion = pDev->IsClipRegion();
+ if ( bIsClipRegion )
+ {
+ Region aOldRegion = pDev->GetClipRegion();
+ pDev->IntersectClipRegion( rRect );
+ pDev->DrawText( aPos, aStr );
+ pDev->SetClipRegion( aOldRegion );
+ }
+ else
+ {
+ Region aRegion( rRect );
+ pDev->SetClipRegion( aRegion );
+ pDev->DrawText( aPos, aStr );
+ pDev->SetClipRegion();
+ }
+ }
+ else
+ pDev->DrawText( aPos, aStr );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+
+#define DRAWTEXT_FLAGS (TEXT_DRAW_CENTER|TEXT_DRAW_TOP|TEXT_DRAW_ENDELLIPSIS|\
+ TEXT_DRAW_CLIP|TEXT_DRAW_MULTILINE|TEXT_DRAW_WORDBREAK)
+
+
+class ImpIcnCursor
+{
+ SvImpIconView* pView;
+ SvPtrarr* pColumns;
+ SvPtrarr* pRows;
+ BOOL* pGridMap;
+ long nGridDX, nGridDY;
+ long nGridCols, nGridRows;
+ long nCols;
+ long nRows;
+ short nDeltaWidth;
+ short nDeltaHeight;
+ SvLBoxEntry* pCurEntry;
+ void SetDeltas();
+ void ImplCreate();
+ void Create() { if( !pColumns ) ImplCreate(); }
+
+ USHORT GetSortListPos( SvPtrarr* pList, long nValue, int bVertical);
+ SvLBoxEntry* SearchCol(USHORT nCol,USHORT nTop,USHORT nBottom,USHORT nPref,
+ BOOL bDown, BOOL bSimple );
+ SvLBoxEntry* SearchRow(USHORT nRow,USHORT nRight,USHORT nLeft,USHORT nPref,
+ BOOL bRight, BOOL bSimple );
+
+ void ExpandGrid();
+ void CreateGridMap();
+ // Rueckgabe FALSE: Eintrag liegt nicht in der GridMap. rGridx,y werden
+ // dann an nGridCols, nGridRows geclippt
+ BOOL GetGrid( const Point& rDocPos, USHORT& rGridX, USHORT& rGridY ) const;
+ void SetGridUsed( USHORT nDX, USHORT nDY, BOOL bUsed )
+ {
+ pGridMap[ (nDY * nGridCols) + nDX ] = bUsed;
+ }
+ BOOL IsGridUsed( USHORT nDX, USHORT nDY )
+ {
+ return pGridMap[ (nDY * nGridCols) + nDX ];
+ }
+public:
+ ImpIcnCursor( SvImpIconView* pOwner );
+ ~ImpIcnCursor();
+ void Clear( BOOL bGridToo = TRUE );
+
+ // fuer Cursortravelling usw.
+ SvLBoxEntry* GoLeftRight( SvLBoxEntry*, BOOL bRight );
+ SvLBoxEntry* GoUpDown( SvLBoxEntry*, BOOL bDown );
+
+ // Rueckgaebe: FALSE == Das leere Rect steht hinter dem letzten
+ // Eintrag; d.h. beim naechsten Einfuegen ergibt sich das naechste
+ // leere Rechteck durch Addition. Hinweis: Das Rechteck kann dann
+ // ausserhalb des View-Space liegen
+ BOOL FindEmptyGridRect( Rectangle& rRect );
+
+ // Erzeugt fuer jede Zeile (Hoehe=nGridDY) eine nach BoundRect.Left()
+ // sortierte Liste der Eintraege, die in ihr stehen. Eine Liste kann
+ // leer sein. Die Listen gehen in das Eigentum des Rufenden ueber und
+ // muessen mit DestroyGridAdjustData geloescht werden
+ void CreateGridAjustData( SvPtrarr& pLists, SvLBoxEntry* pRow=0);
+ static void DestroyGridAdjustData( SvPtrarr& rLists );
+ void SetGridUsed( const Rectangle&, BOOL bUsed = TRUE );
+};
+
+
+
+
+SvImpIconView::SvImpIconView( SvIconView* pCurView, SvLBoxTreeList* pTree,
+ WinBits nWinStyle ) :
+ aVerSBar( pCurView, WB_DRAG | WB_VSCROLL ),
+ aHorSBar( pCurView, WB_DRAG | WB_HSCROLL )
+{
+ pView = pCurView;
+ pModel = pTree;
+ pCurParent = 0;
+ pZOrderList = new SvPtrarr;
+ SetWindowBits( nWinStyle );
+ nHorDist = 0;
+ nVerDist = 0;
+ nFlags = 0;
+ nCurUserEvent = 0;
+ nMaxVirtWidth = 200;
+ pDDRefEntry = 0;
+ pDDDev = 0;
+ pDDBufDev = 0;
+ pDDTempDev = 0;
+ eTextMode = ShowTextShort;
+ pImpCursor = new ImpIcnCursor( this );
+
+ aVerSBar.SetScrollHdl( LINK( this, SvImpIconView, ScrollUpDownHdl ) );
+ aHorSBar.SetScrollHdl( LINK( this, SvImpIconView, ScrollLeftRightHdl ) );
+ nHorSBarHeight = aHorSBar.GetSizePixel().Height();
+ nVerSBarWidth = aVerSBar.GetSizePixel().Width();
+
+ aMouseMoveTimer.SetTimeout( 20 );
+ aMouseMoveTimer.SetTimeoutHdl(LINK(this,SvImpIconView,MouseMoveTimeoutHdl));
+
+ aEditTimer.SetTimeout( 800 );
+ aEditTimer.SetTimeoutHdl(LINK(this,SvImpIconView,EditTimeoutHdl));
+
+ Clear( TRUE );
+}
+
+SvImpIconView::~SvImpIconView()
+{
+ StopEditTimer();
+ CancelUserEvent();
+ delete pZOrderList;
+ delete pImpCursor;
+ delete pDDDev;
+ delete pDDBufDev;
+ delete pDDTempDev;
+ ClearSelectedRectList();
+}
+
+void SvImpIconView::Clear( BOOL bInCtor )
+{
+ StopEditTimer();
+ CancelUserEvent();
+ nMaxBmpWidth = 0;
+ nMaxBmpHeight = 0;
+ nMaxTextWidth = 0;
+ bMustRecalcBoundingRects = FALSE;
+ nMaxBoundHeight = 0;
+
+ //XXX
+ nFlags |= F_GRID_INSERT;
+ nFlags &= ~F_PAINTED;
+ SetNextEntryPos( Point( LROFFS_WINBORDER, TBOFFS_WINBORDER ) );
+ pCursor = 0;
+ if( !bInCtor )
+ {
+ pImpCursor->Clear();
+ aVirtOutputSize.Width() = 0;
+ aVirtOutputSize.Height() = 0;
+ pZOrderList->Remove(0,pZOrderList->Count());
+ MapMode aMapMode( pView->GetMapMode());
+ aMapMode.SetOrigin( Point() );
+ pView->SetMapMode( aMapMode );
+ if( pView->IsUpdateMode() )
+ pView->Invalidate();
+ }
+ AdjustScrollBars();
+}
+
+void SvImpIconView::SetWindowBits( WinBits nWinStyle )
+{
+ nWinBits = nWinStyle;
+ nViewMode = VIEWMODE_TEXT;
+ if( nWinStyle & WB_NAME )
+ nViewMode = VIEWMODE_NAME;
+ if( nWinStyle & WB_ICON )
+ nViewMode = VIEWMODE_ICON;
+}
+
+
+IMPL_LINK( SvImpIconView, ScrollUpDownHdl, ScrollBar *, pScrollBar )
+{
+ pView->EndEditing( TRUE );
+ // Pfeil hoch: delta=-1; Pfeil runter: delta=+1
+ Scroll( 0, pScrollBar->GetDelta(), TRUE );
+ return 0;
+}
+
+IMPL_LINK( SvImpIconView, ScrollLeftRightHdl, ScrollBar *, pScrollBar )
+{
+ pView->EndEditing( TRUE );
+ // Pfeil links: delta=-1; Pfeil rechts: delta=+1
+ Scroll( pScrollBar->GetDelta(), 0, TRUE );
+ return 0;
+}
+
+void SvImpIconView::ChangedFont()
+{
+ StopEditTimer();
+ ImpArrange();
+}
+
+
+void SvImpIconView::CheckAllSizes()
+{
+ nMaxTextWidth = 0;
+ nMaxBmpWidth = 0;
+ nMaxBmpHeight = 0;
+ SvLBoxEntry* pEntry = pModel->First();
+ while( pEntry )
+ {
+ CheckSizes( pEntry );
+ pEntry = pModel->Next( pEntry );
+ }
+}
+
+void SvImpIconView::CheckSizes( SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData )
+{
+ Size aSize;
+
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+
+ SvLBoxString* pStringItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if( pStringItem )
+ {
+ aSize = GetItemSize( pView, pEntry, pStringItem, pViewData );
+ if( aSize.Width() > nMaxTextWidth )
+ {
+ nMaxTextWidth = aSize.Width();
+ if( !(nFlags & F_GRIDMODE ) )
+ bMustRecalcBoundingRects = TRUE;
+ }
+ }
+ SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if( pBmpItem )
+ {
+ aSize = GetItemSize( pView, pEntry, pBmpItem, pViewData );
+ if( aSize.Width() > nMaxBmpWidth )
+ {
+ nMaxBmpWidth = aSize.Width();
+ nMaxBmpWidth += (2*LROFFS_ICON);
+ if( !(nFlags & F_GRIDMODE ) )
+ bMustRecalcBoundingRects = TRUE;
+ }
+ if( aSize.Height() > nMaxBmpHeight )
+ {
+ nMaxBmpHeight = aSize.Height();
+ nMaxBmpHeight += (2*TBOFFS_ICON);;
+ if( !(nFlags & F_GRIDMODE ) )
+ bMustRecalcBoundingRects = TRUE;
+ }
+ }
+}
+
+void SvImpIconView::EntryInserted( SvLBoxEntry* pEntry )
+{
+ if( pModel->GetParent(pEntry) == pCurParent )
+ {
+ StopEditTimer();
+ DBG_ASSERT(pZOrderList->GetPos(pEntry)==0xffff,"EntryInserted:ZOrder?");
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ if( nFlags & F_GRIDMODE )
+ pImpCursor->Clear( FALSE );
+ else
+ pImpCursor->Clear( TRUE );
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ CheckSizes( pEntry, pViewData );
+ if( pView->IsUpdateMode() )
+ {
+ FindBoundingRect( pEntry, pViewData );
+ PaintEntry( pEntry, pViewData );
+ }
+ else
+ InvalidateBoundingRect( pViewData->aRect );
+ }
+}
+
+void SvImpIconView::RemovingEntry( SvLBoxEntry* pEntry )
+{
+ if( pModel->GetParent(pEntry) == pCurParent)
+ {
+ StopEditTimer();
+ DBG_ASSERT(pZOrderList->GetPos(pEntry)!=0xffff,"RemovingEntry:ZOrder?");
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( IsBoundingRectValid( pViewData->aRect ) )
+ {
+ // bei gueltigem Bounding-Rect muss in EntryRemoved eine
+ // Sonderbehandlung erfolgen
+ nFlags |= F_ENTRY_REMOVED;
+ pView->Invalidate( pViewData->aRect );
+ }
+ if( pEntry == pCursor )
+ {
+ SvLBoxEntry* pNewCursor = GetNewCursor();
+ ShowCursor( FALSE );
+ pCursor = 0; // damit er nicht deselektiert wird
+ SetCursor( pNewCursor );
+ }
+ USHORT nPos = pZOrderList->GetPos( (void*)pEntry );
+ pZOrderList->Remove( nPos, 1 );
+ pImpCursor->Clear();
+ }
+}
+
+void SvImpIconView::EntryRemoved()
+{
+ if( (nFlags & (F_ENTRY_REMOVED | F_PAINTED)) == (F_ENTRY_REMOVED | F_PAINTED))
+ {
+ // Ein Eintrag mit gueltigem BoundRect wurde geloescht und wir
+ // haben schon mal gepaintet. In diesem Fall muessen wir die
+ // Position des naechsten Eintrags, der eingefuegt wird oder noch
+ // kein gueltiges BoundRect hat, "suchen" d.h. ein "Loch" in
+ // der View auffuellen.
+ nFlags &= ~( F_ENTRY_REMOVED | F_GRID_INSERT );
+ }
+}
+
+
+void SvImpIconView::MovingEntry( SvLBoxEntry* pEntry )
+{
+ DBG_ASSERT(pEntry,"MovingEntry: 0!");
+ pNextCursor = 0;
+ StopEditTimer();
+ if( pModel->GetParent(pEntry) == pCurParent )
+ {
+ DBG_ASSERT(pZOrderList->GetPos(pEntry)!=0xffff,"MovingEntry:ZOrder?");
+ nFlags |= F_MOVING_SIBLING;
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( IsBoundingRectValid( pViewData->aRect ) )
+ pView->Invalidate( pViewData->aRect );
+ // falls Eintrag seinen Parent wechselt vorsichtshalber
+ // die neue Cursorposition berechnen
+ if( pEntry == pCursor )
+ pNextCursor = GetNewCursor();
+ pImpCursor->Clear();
+ }
+}
+
+
+void SvImpIconView::EntryMoved( SvLBoxEntry* pEntry )
+{
+ ShowCursor( FALSE );
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( pModel->GetParent(pEntry)==pCurParent )
+ {
+ if( nFlags & F_MOVING_SIBLING )
+ {
+ // die Neu-Positionierung eines Eintrags bei D&D innerhalb
+ // einer IconView findet bereits in NotifyMoving statt
+ // (MovingEntry/EntryMoved wird dann nicht mehr gerufen)
+ ToTop( pEntry );
+ }
+ else
+ {
+ pImpCursor->Clear();
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ DBG_ASSERT(pZOrderList->Count()==pModel->GetChildCount(pCurParent),"EntryMoved:Bad zorder count");
+ FindBoundingRect( pEntry, pViewData );
+ }
+ PaintEntry( pEntry, pViewData );
+ }
+ else
+ {
+ if( pEntry == pCursor )
+ {
+ DBG_ASSERT(pNextCursor,"EntryMoved: Next cursor bad");
+ SetCursor( pNextCursor );
+ }
+ pImpCursor->Clear();
+ USHORT nPos = pZOrderList->GetPos( (void*)pEntry );
+ pZOrderList->Remove( nPos, 1 );
+ pView->Select( pEntry, FALSE );
+ // wenn er nochmal in dieser View auftaucht, muss sein
+ // Bounding-Rect neu berechnet werden
+ InvalidateBoundingRect( pViewData->aRect );
+ }
+ nFlags &= (~F_MOVING_SIBLING);
+}
+
+void SvImpIconView::TreeInserted( SvLBoxEntry* pEntry )
+{
+ EntryMoved( pEntry ); // vorlaeufig
+}
+
+void SvImpIconView::EntryExpanded( SvLBoxEntry* )
+{
+}
+
+void SvImpIconView::EntryCollapsed( SvLBoxEntry*)
+{
+}
+
+void SvImpIconView::CollapsingEntry( SvLBoxEntry* )
+{
+}
+
+void SvImpIconView::EntrySelected( SvLBoxEntry* pEntry, BOOL bSelect )
+{
+ if( pModel->GetParent(pEntry) != pCurParent )
+ return;
+
+ // bei SingleSelection dafuer sorgen, dass der Cursor immer
+ // auf dem (einzigen) selektierten Eintrag steht
+ if( bSelect && pCursor &&
+ pView->GetSelectionMode() == SINGLE_SELECTION &&
+ pEntry != pCursor )
+ {
+ SetCursor( pEntry );
+ DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?");
+ }
+ // bei Gummibandselektion ist uns das zu teuer
+ if( !(nFlags & F_RUBBERING ))
+ ToTop( pEntry );
+ if( pView->IsUpdateMode() )
+ {
+ if( pEntry == pCursor )
+ ShowCursor( FALSE );
+ if( nFlags & F_RUBBERING )
+ PaintEntry( pEntry );
+ else
+ pView->Invalidate( GetBoundingRect( pEntry ) );
+ if( pEntry == pCursor )
+ ShowCursor( TRUE );
+ }
+}
+
+void SvImpIconView::SetNextEntryPos(const Point& rPos)
+{
+ aPrevBoundRect.SetPos( rPos );
+ aPrevBoundRect.Right() = LONG_MAX; // dont know
+}
+
+Point SvImpIconView::FindNextEntryPos( const Size& rBoundSize )
+{
+ if( nFlags & F_GRIDMODE )
+ {
+ if( nFlags & F_GRID_INSERT )
+ {
+ if( aPrevBoundRect.Right() != LONG_MAX )
+ {
+ // passt der naechste Entry noch in die Zeile ?
+ long nNextWidth = aPrevBoundRect.Right() + nGridDX + LROFFS_WINBORDER;
+ if( nNextWidth > aVirtOutputSize.Width() )
+ {
+ // darf aVirtOutputSize verbreitert werden ?
+ if( nNextWidth < nMaxVirtWidth )
+ {
+ // verbreitern & in Zeile aufnehmen
+ aPrevBoundRect.Left() += nGridDX;
+ }
+ else
+ {
+ // erhoehen & neue Zeile beginnen
+ aPrevBoundRect.Top() += nGridDY;
+ aPrevBoundRect.Left() = LROFFS_WINBORDER;
+ }
+ }
+ else
+ {
+ // in die Zeile aufnehmen
+ aPrevBoundRect.Left() += nGridDX;
+ }
+ }
+ aPrevBoundRect.SetSize( Size( nGridDX, nGridDY ) );
+ }
+ else
+ {
+ if( !pImpCursor->FindEmptyGridRect( aPrevBoundRect ) )
+ {
+ // mitten in den Entries gibts keine Loecher mehr,
+ // wir koennen also wieder ins "Fast Insert" springen
+ nFlags |= F_GRID_INSERT;
+ }
+ }
+ }
+ else
+ {
+ if( aPrevBoundRect.Right() != LONG_MAX )
+ {
+ // passt der naechste Entry noch in die Zeile ?
+ long nNextWidth=aPrevBoundRect.Right()+rBoundSize.Width()+LROFFS_BOUND+nHorDist;
+ if( nNextWidth > aVirtOutputSize.Width() )
+ {
+ // darf aVirtOutputSize verbreitert werden ?
+ if( nNextWidth < nMaxVirtWidth )
+ {
+ // verbreitern & in Zeile aufnehmen
+ aPrevBoundRect.SetPos( aPrevBoundRect.TopRight() );
+ aPrevBoundRect.Left() += nHorDist;
+ }
+ else
+ {
+ // erhoehen & neue Zeile beginnen
+ aPrevBoundRect.Top() += nMaxBoundHeight + nVerDist + TBOFFS_BOUND;
+ aPrevBoundRect.Left() = LROFFS_WINBORDER;
+ }
+ }
+ else
+ {
+ // in die Zeile aufnehmen
+ aPrevBoundRect.SetPos( aPrevBoundRect.TopRight() );
+ aPrevBoundRect.Left() += nHorDist;
+ }
+ }
+ aPrevBoundRect.SetSize( rBoundSize );
+ }
+ return aPrevBoundRect.TopLeft();
+}
+
+void SvImpIconView::ResetVirtSize()
+{
+ StopEditTimer();
+ aVirtOutputSize.Width() = 0;
+ aVirtOutputSize.Height() = 0;
+ BOOL bLockedEntryFound = FALSE;
+ nFlags &= (~F_GRID_INSERT);
+ SvLBoxEntry* pCur = pModel->FirstChild( pCurParent );
+ while( pCur )
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur);
+ if( pViewData->IsEntryPosLocked() )
+ {
+ // VirtSize u.a. anpassen
+ if( !IsBoundingRectValid( pViewData->aRect ) )
+ FindBoundingRect( pCur, pViewData );
+ else
+ AdjustVirtSize( pViewData->aRect );
+ bLockedEntryFound = TRUE;
+ }
+ else
+ InvalidateBoundingRect( pViewData->aRect );
+
+ pCur = pModel->NextSibling( pCur );
+ }
+ if( !bLockedEntryFound )
+ {
+ //XXX
+ nFlags |= F_GRID_INSERT;
+ }
+
+ SetNextEntryPos( Point( LROFFS_WINBORDER, TBOFFS_WINBORDER ) );
+ pImpCursor->Clear();
+}
+
+
+void SvImpIconView::AdjustVirtSize( const Rectangle& rRect )
+{
+ long nHeightOffs = 0;
+ long nWidthOffs = 0;
+
+ if( aVirtOutputSize.Width() < (rRect.Right()+LROFFS_WINBORDER) )
+ nWidthOffs = (rRect.Right()+LROFFS_WINBORDER) - aVirtOutputSize.Width();
+
+ if( aVirtOutputSize.Height() < (rRect.Bottom()+TBOFFS_WINBORDER) )
+ nHeightOffs = (rRect.Bottom()+TBOFFS_WINBORDER) - aVirtOutputSize.Height();
+
+ if( nWidthOffs || nHeightOffs )
+ {
+ Range aRange;
+ aVirtOutputSize.Width() += nWidthOffs;
+ aRange.Max() = aVirtOutputSize.Width();
+ aHorSBar.SetRange( aRange );
+
+ aVirtOutputSize.Height() += nHeightOffs;
+ aRange.Max() = aVirtOutputSize.Height();
+ aVerSBar.SetRange( aRange );
+
+ pImpCursor->Clear();
+ AdjustScrollBars();
+ }
+}
+
+void SvImpIconView::Arrange()
+{
+ nMaxVirtWidth = aOutputSize.Width();
+ ImpArrange();
+}
+
+void SvImpIconView::ImpArrange()
+{
+ StopEditTimer();
+ ShowCursor( FALSE );
+ ResetVirtSize();
+ bMustRecalcBoundingRects = FALSE;
+ MapMode aMapMode( pView->GetMapMode());
+ aMapMode.SetOrigin( Point() );
+ pView->SetMapMode( aMapMode );
+ CheckAllSizes();
+ RecalcAllBoundingRectsSmart();
+ pView->Invalidate();
+ ShowCursor( TRUE );
+}
+
+void SvImpIconView::Paint( const Rectangle& rRect )
+{
+ if( !pView->IsUpdateMode() )
+ return;
+
+#if defined(DBG_UTIL) && defined(OV_DRAWGRID)
+ if( nFlags & F_GRIDMODE )
+ {
+ Color aOldColor = pView->GetLineColor();
+ Color aNewColor( COL_BLACK );
+ pView->SetLineColor( aNewColor );
+ Point aOffs( pView->GetMapMode().GetOrigin());
+ Size aXSize( pView->GetOutputSizePixel() );
+ for( long nDX = nGridDX; nDX <= aXSize.Width(); nDX += nGridDX )
+ {
+ Point aStart( nDX+LROFFS_BOUND, 0 );
+ Point aEnd( nDX+LROFFS_BOUND, aXSize.Height());
+ aStart -= aOffs;
+ aEnd -= aOffs;
+ pView->DrawLine( aStart, aEnd );
+ }
+ for( long nDY = nGridDY; nDY <= aXSize.Height(); nDY += nGridDY )
+ {
+ Point aStart( 0, nDY+TBOFFS_BOUND );
+ Point aEnd( aXSize.Width(), nDY+TBOFFS_BOUND );
+ aStart -= aOffs;
+ aEnd -= aOffs;
+ pView->DrawLine( aStart, aEnd );
+ }
+ pView->SetLineColor( aOldColor );
+ }
+#endif
+ nFlags |= F_PAINTED;
+
+ if( !(pModel->HasChilds( pCurParent ) ))
+ return;
+ if( !pCursor )
+ pCursor = pModel->FirstChild( pCurParent );
+
+ USHORT nCount = pZOrderList->Count();
+ if( !nCount )
+ return;
+
+ SvPtrarr* pNewZOrderList = new SvPtrarr;
+ SvPtrarr* pPaintedEntries = new SvPtrarr;
+
+ USHORT nPos = 0;
+ while( nCount )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pZOrderList->GetObject(nPos ));
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ const Rectangle& rBoundRect = GetBoundingRect( pEntry, pViewData );
+ if( rRect.IsOver( rBoundRect ) )
+ {
+ PaintEntry( pEntry, rBoundRect.TopLeft(), pViewData );
+ // Eintraege, die neu gezeichnet werden, auf Top setzen
+ pPaintedEntries->Insert( pEntry, pPaintedEntries->Count() );
+ }
+ else
+ pNewZOrderList->Insert( pEntry, pNewZOrderList->Count() );
+
+ nCount--;
+ nPos++;
+ }
+ delete pZOrderList;
+ pZOrderList = pNewZOrderList;
+ nCount = pPaintedEntries->Count();
+ if( nCount )
+ {
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ pZOrderList->Insert( pPaintedEntries->GetObject( nCur ),pZOrderList->Count());
+ }
+ delete pPaintedEntries;
+
+ Rectangle aRect;
+ if( GetResizeRect( aRect ))
+ PaintResizeRect( aRect );
+}
+
+BOOL SvImpIconView::GetResizeRect( Rectangle& rRect )
+{
+ if( aHorSBar.IsVisible() && aVerSBar.IsVisible() )
+ {
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin());
+ aOrigin *= -1;
+ aOrigin.X() += aOutputSize.Width();
+ aOrigin.Y() += aOutputSize.Height();
+ rRect.SetPos( aOrigin );
+ rRect.SetSize( Size( nVerSBarWidth, nHorSBarHeight));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SvImpIconView::PaintResizeRect( const Rectangle& rRect )
+{
+ const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings();
+ Color aNewColor = rStyleSettings.GetFaceColor();
+ Color aOldColor = pView->GetFillColor();
+ pView->SetFillColor( aNewColor );
+ pView->DrawRect( rRect );
+ pView->SetFillColor( aOldColor );
+}
+
+void SvImpIconView::RepaintSelectionItems()
+{
+ DBG_ERROR("RepaintSelectionItems");
+ pView->Invalidate(); // vorlaeufig
+}
+
+SvLBoxItem* SvImpIconView::GetItem( SvLBoxEntry* pEntry,
+ const Point& rAbsPos )
+{
+ Rectangle aRect;
+ SvLBoxString* pStringItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if( pStringItem )
+ {
+ aRect = CalcTextRect( pEntry, pStringItem );
+ if( aRect.IsInside( rAbsPos ) )
+ return pStringItem;
+ }
+ SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if( pBmpItem )
+ {
+ aRect = CalcBmpRect( pEntry );
+ if( aRect.IsInside( rAbsPos ) )
+ return pBmpItem;
+ }
+ return 0;
+}
+
+void SvImpIconView::CalcDocPos( Point& aMaeuschenPos )
+{
+ aMaeuschenPos -= pView->GetMapMode().GetOrigin();
+}
+
+void SvImpIconView::MouseButtonDown( const MouseEvent& rMEvt)
+{
+ StopEditTimer();
+ pView->GrabFocus();
+ Point aDocPos( rMEvt.GetPosPixel() );
+ if(aDocPos.X()>=aOutputSize.Width() || aDocPos.Y()>=aOutputSize.Height())
+ return;
+ CalcDocPos( aDocPos );
+ SvLBoxEntry* pEntry = GetEntry( aDocPos );
+ if( !pEntry )
+ {
+ if( pView->GetSelectionMode() != SINGLE_SELECTION )
+ {
+ if( !rMEvt.IsMod1() ) // Ctrl
+ {
+ pView->SelectAll( FALSE );
+ ClearSelectedRectList();
+ }
+ else
+ nFlags |= F_ADD_MODE;
+ nFlags |= F_RUBBERING;
+ aCurSelectionRect.SetPos( aDocPos );
+ pView->CaptureMouse();
+ }
+ return;
+ }
+
+ BOOL bSelected = pView->IsSelected( pEntry );
+ BOOL bEditingEnabled = pView->IsInplaceEditingEnabled();
+
+ if( rMEvt.GetClicks() == 2 )
+ {
+ DeselectAllBut( pEntry );
+ pView->pHdlEntry = pEntry;
+ pView->DoubleClickHdl();
+ }
+ else
+ {
+ // Inplace-Editing ?
+ if( rMEvt.IsMod2() ) // Alt?
+ {
+ if( bEditingEnabled )
+ {
+ SvLBoxItem* pItem = GetItem(pEntry,aDocPos);
+ if( pItem )
+ pView->EditingRequest( pEntry, pItem, aDocPos);
+ }
+ }
+ else if( pView->GetSelectionMode() == SINGLE_SELECTION )
+ {
+ DeselectAllBut( pEntry );
+ SetCursor( pEntry );
+ pView->Select( pEntry, TRUE );
+ if( bEditingEnabled && bSelected && !rMEvt.GetModifier() &&
+ rMEvt.IsLeft() && IsTextHit( pEntry, aDocPos ) )
+ {
+ nFlags |= F_START_EDITTIMER_IN_MOUSEUP;
+ }
+ }
+ else
+ {
+ if( !rMEvt.GetModifier() )
+ {
+ if( !bSelected )
+ {
+ DeselectAllBut( pEntry );
+ SetCursor( pEntry );
+ pView->Select( pEntry, TRUE );
+ }
+ else
+ {
+ // erst im Up deselektieren, falls Move per D&D!
+ nFlags |= F_DOWN_DESELECT;
+ if( bEditingEnabled && IsTextHit( pEntry, aDocPos ) &&
+ rMEvt.IsLeft())
+ {
+ nFlags |= F_START_EDITTIMER_IN_MOUSEUP;
+ }
+ }
+ }
+ else if( rMEvt.IsMod1() )
+ nFlags |= F_DOWN_CTRL;
+ }
+ }
+}
+
+void SvImpIconView::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ aMouseMoveTimer.Stop();
+ pView->ReleaseMouse();
+ // HACK, da Einar noch nicht PrepareCommandEvent aufruft
+ if( rMEvt.IsRight() && (nFlags & (F_DOWN_CTRL | F_DOWN_DESELECT) ))
+ nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
+
+ if( nFlags & F_RUBBERING )
+ {
+ aMouseMoveTimer.Stop();
+ AddSelectedRect( aCurSelectionRect );
+ HideSelectionRect();
+ nFlags &= ~(F_RUBBERING | F_ADD_MODE);
+ }
+
+ SvLBoxEntry* pEntry = pView->GetEntry( rMEvt.GetPosPixel(), TRUE );
+ if( pEntry )
+ {
+ if( nFlags & F_DOWN_CTRL )
+ {
+ // Ctrl & MultiSelection
+ ToggleSelection( pEntry );
+ SetCursor( pEntry );
+ }
+ else if( nFlags & F_DOWN_DESELECT )
+ {
+ DeselectAllBut( pEntry );
+ SetCursor( pEntry );
+ pView->Select( pEntry, TRUE );
+ }
+ }
+
+ nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
+ if( nFlags & F_START_EDITTIMER_IN_MOUSEUP )
+ {
+ StartEditTimer();
+ nFlags &= ~F_START_EDITTIMER_IN_MOUSEUP;
+ }
+}
+
+void SvImpIconView::MouseMove( const MouseEvent& rMEvt )
+{
+ if( nFlags & F_RUBBERING )
+ {
+ const Point& rPosPixel = rMEvt.GetPosPixel();
+ if( !aMouseMoveTimer.IsActive() )
+ {
+ aMouseMoveEvent = rMEvt;
+ aMouseMoveTimer.Start();
+ // ausserhalb des Fensters liegende Move-Events muessen
+ // vom Timer kommen, damit die Scrollgeschwindigkeit
+ // unabhaengig von Mausbewegungen ist.
+ if( rPosPixel.X() < 0 || rPosPixel.Y() < 0 )
+ return;
+ const Size& rSize = pView->GetOutputSizePixel();
+ if( rPosPixel.X() > rSize.Width() || rPosPixel.Y() > rSize.Height())
+ return;
+ }
+
+ if( &rMEvt != &aMouseMoveEvent )
+ aMouseMoveEvent = rMEvt;
+
+ long nScrollDX, nScrollDY;
+
+ CalcScrollOffsets(rMEvt.GetPosPixel(),nScrollDX,nScrollDY,FALSE );
+ BOOL bSelRectHidden = FALSE;
+ if( nScrollDX || nScrollDY )
+ {
+ HideSelectionRect();
+ bSelRectHidden = TRUE;
+ pView->Scroll( nScrollDX, nScrollDY );
+ }
+ Point aDocPos( rMEvt.GetPosPixel() );
+ aDocPos = pView->PixelToLogic( aDocPos );
+ Rectangle aRect( aCurSelectionRect.TopLeft(), aDocPos );
+ if( aRect != aCurSelectionRect )
+ {
+ HideSelectionRect();
+ bSelRectHidden = TRUE;
+ BOOL bAdd = (nFlags & F_ADD_MODE) ? TRUE : FALSE;
+ SelectRect( aRect, bAdd, &aSelectedRectList );
+ }
+ if( bSelRectHidden )
+ DrawSelectionRect( aRect );
+ }
+}
+
+BOOL SvImpIconView::KeyInput( const KeyEvent& rKEvt )
+{
+ StopEditTimer();
+ BOOL bKeyUsed = TRUE;
+ BOOL bMod1 = rKEvt.GetKeyCode().IsMod1();
+ BOOL bInAddMode = (BOOL)((nFlags & F_ADD_MODE) != 0);
+ int bDeselAll = (pView->GetSelectionMode() != SINGLE_SELECTION) &&
+ !bInAddMode;
+ SvLBoxEntry* pNewCursor;
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+ switch( nCode )
+ {
+ case KEY_UP:
+ if( pCursor )
+ {
+ MakeVisible( pCursor );
+ pNewCursor = pImpCursor->GoUpDown(pCursor,FALSE);
+ if( pNewCursor )
+ {
+ if( bDeselAll )
+ pView->SelectAll( FALSE );
+ ShowCursor( FALSE );
+ MakeVisible( pNewCursor );
+ SetCursor( pNewCursor );
+ if( !bInAddMode )
+ pView->Select( pCursor, TRUE );
+ }
+ else
+ {
+ Rectangle aRect( GetBoundingRect( pCursor ) );
+ if( aRect.Top())
+ {
+ aRect.Bottom() -= aRect.Top();
+ aRect.Top() = 0;
+ MakeVisible( aRect );
+ }
+ }
+ }
+ break;
+
+ case KEY_DOWN:
+ if( pCursor )
+ {
+ pNewCursor=pImpCursor->GoUpDown( pCursor,TRUE );
+ if( pNewCursor )
+ {
+ MakeVisible( pCursor );
+ if( bDeselAll )
+ pView->SelectAll( FALSE );
+ ShowCursor( FALSE );
+ MakeVisible( pNewCursor );
+ SetCursor( pNewCursor );
+ if( !bInAddMode )
+ pView->Select( pCursor, TRUE );
+ }
+ }
+ break;
+
+ case KEY_RIGHT:
+ if( pCursor )
+ {
+ pNewCursor=pImpCursor->GoLeftRight(pCursor,TRUE );
+ if( pNewCursor )
+ {
+ MakeVisible( pCursor );
+ if( bDeselAll )
+ pView->SelectAll( FALSE );
+ ShowCursor( FALSE );
+ MakeVisible( pNewCursor );
+ SetCursor( pNewCursor );
+ if( !bInAddMode )
+ pView->Select( pCursor, TRUE );
+ }
+ }
+ break;
+
+ case KEY_LEFT:
+ if( pCursor )
+ {
+ MakeVisible( pCursor );
+ pNewCursor = pImpCursor->GoLeftRight(pCursor,FALSE );
+ if( pNewCursor )
+ {
+ if( bDeselAll )
+ pView->SelectAll( FALSE );
+ ShowCursor( FALSE );
+ MakeVisible( pNewCursor );
+ SetCursor( pNewCursor );
+ if( !bInAddMode )
+ pView->Select( pCursor, TRUE );
+ }
+ else
+ {
+ Rectangle aRect( GetBoundingRect(pCursor));
+ if( aRect.Left() )
+ {
+ aRect.Right() -= aRect.Left();
+ aRect.Left() = 0;
+ MakeVisible( aRect );
+ }
+ }
+ }
+ break;
+
+ case KEY_ESCAPE:
+ if( nFlags & F_RUBBERING )
+ {
+ HideSelectionRect();
+ pView->SelectAll( FALSE );
+ nFlags &= ~F_RUBBERING;
+ }
+ break;
+
+ case KEY_F8:
+ if( rKEvt.GetKeyCode().IsShift() )
+ {
+ if( nFlags & F_ADD_MODE )
+ nFlags &= (~F_ADD_MODE);
+ else
+ nFlags |= F_ADD_MODE;
+ }
+ break;
+
+#ifdef OS2
+ case KEY_F9:
+ if( rKEvt.GetKeyCode().IsShift() )
+ {
+ if( pCursor && pView->IsInplaceEditingEnabled() )
+ pView->EditEntry( pCursor );
+ }
+ break;
+#endif
+
+ case KEY_SPACE:
+ if( pCursor )
+ {
+ ToggleSelection( pCursor );
+ }
+ break;
+
+
+ case KEY_PAGEDOWN:
+ break;
+ case KEY_PAGEUP:
+ break;
+
+ case KEY_ADD:
+ case KEY_DIVIDE :
+ if( bMod1 )
+ pView->SelectAll( TRUE );
+ break;
+
+ case KEY_SUBTRACT:
+ case KEY_COMMA :
+ if( bMod1 )
+ pView->SelectAll( FALSE );
+ break;
+
+ case KEY_RETURN:
+ if( bMod1 )
+ {
+ if( pCursor && pView->IsInplaceEditingEnabled() )
+ pView->EditEntry( pCursor );
+ }
+ break;
+
+ default:
+ bKeyUsed = FALSE;
+
+ }
+ return bKeyUsed;
+}
+
+
+void SvImpIconView::PositionScrollBars( long nRealWidth, long nRealHeight )
+{
+ // hor scrollbar
+ Point aPos( 0, nRealHeight );
+ aPos.Y() -= nHorSBarHeight;
+
+#ifdef WIN
+ // vom linken und unteren Rand ein Pixel abschneiden
+ aPos.Y()++;
+ aPos.X()--;
+#endif
+#ifdef OS2
+ aPos.Y()++;
+#endif
+ if( aHorSBar.GetPosPixel() != aPos )
+ aHorSBar.SetPosPixel( aPos );
+
+ // ver scrollbar
+ aPos.X() = nRealWidth; aPos.Y() = 0;
+ aPos.X() -= nVerSBarWidth;
+
+#if defined(WIN) || defined(WNT)
+ aPos.X()++;
+ aPos.Y()--;
+#endif
+
+#ifdef OS2
+ aPos.Y()--;
+ aPos.X()++;
+#endif
+
+ if( aVerSBar.GetPosPixel() != aPos )
+ aVerSBar.SetPosPixel( aPos );
+}
+
+
+
+void SvImpIconView::AdjustScrollBars()
+{
+ long nVirtHeight = aVirtOutputSize.Height();
+ long nVirtWidth = aVirtOutputSize.Width();
+
+ Size aOSize( pView->Control::GetOutputSizePixel() );
+ long nRealHeight = aOSize.Height();
+ long nRealWidth = aOSize.Width();
+
+ PositionScrollBars( nRealWidth, nRealHeight );
+
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+
+ long nVisibleWidth;
+ if( nRealWidth > nVirtWidth )
+ nVisibleWidth = nVirtWidth + aOrigin.X();
+ else
+ nVisibleWidth = nRealWidth;
+
+ long nVisibleHeight;
+ if( nRealHeight > nVirtHeight )
+ nVisibleHeight = nVirtHeight + aOrigin.Y();
+ else
+ nVisibleHeight = nRealHeight;
+
+ bool bVerSBar = (pView->nWindowStyle & WB_VSCROLL) ? true : false;
+ bool bHorSBar = (pView->nWindowStyle & WB_HSCROLL) ? true : false;
+
+ USHORT nResult = 0;
+ if( nVirtHeight )
+ {
+ // activate ver scrollbar ?
+ if( bVerSBar || ( nVirtHeight > nVisibleHeight) )
+ {
+ nResult = 0x0001;
+ nRealWidth -= nVerSBarWidth;
+
+ if( nRealWidth > nVirtWidth )
+ nVisibleWidth = nVirtWidth + aOrigin.X();
+ else
+ nVisibleWidth = nRealWidth;
+
+ nFlags |= F_HOR_SBARSIZE_WITH_VBAR;
+ }
+ // activate hor scrollbar ?
+ if( bHorSBar || (nVirtWidth > nVisibleWidth) )
+ {
+ nResult |= 0x0002;
+ nRealHeight -= nHorSBarHeight;
+
+ if( nRealHeight > nVirtHeight )
+ nVisibleHeight = nVirtHeight + aOrigin.Y();
+ else
+ nVisibleHeight = nRealHeight;
+
+ // brauchen wir jetzt doch eine senkrechte Scrollbar ?
+ if( !(nResult & 0x0001) && // nur wenn nicht schon da
+ ( (nVirtHeight > nVisibleHeight) || bVerSBar) )
+ {
+ nResult = 3; // both are active
+ nRealWidth -= nVerSBarWidth;
+
+ if( nRealWidth > nVirtWidth )
+ nVisibleWidth = nVirtWidth + aOrigin.X();
+ else
+ nVisibleWidth = nRealWidth;
+
+ nFlags |= F_VER_SBARSIZE_WITH_HBAR;
+ }
+ }
+ }
+
+ // size ver scrollbar
+ long nThumb = aVerSBar.GetThumbPos();
+ Size aSize( nVerSBarWidth, nRealHeight );
+#if defined(WIN) || defined(WNT)
+ aSize.Height() += 2;
+#endif
+#ifdef OS2
+ aSize.Height() += 3;
+#endif
+ if( aSize != aVerSBar.GetSizePixel() )
+ aVerSBar.SetSizePixel( aSize );
+ aVerSBar.SetVisibleSize( nVisibleHeight );
+ aVerSBar.SetPageSize( (nVisibleHeight*75)/100 );
+ if( nResult & 0x0001 )
+ {
+ aVerSBar.SetThumbPos( nThumb );
+ aVerSBar.Show();
+ }
+ else
+ {
+ aVerSBar.SetThumbPos( 0 );
+ aVerSBar.Hide();
+ }
+
+ // size hor scrollbar
+ nThumb = aHorSBar.GetThumbPos();
+ aSize.Width() = nRealWidth;
+ aSize.Height() = nHorSBarHeight;
+#if defined(WIN) || defined(WNT)
+ aSize.Width()++;
+#endif
+#ifdef OS2
+ aSize.Width() += 3;
+ if( nResult & 0x0001 ) // vertikale Scrollbar ?
+ aSize.Width()--;
+#endif
+#if defined(WIN) || defined(WNT)
+ if( nResult & 0x0001 ) // vertikale Scrollbar ?
+ {
+ aSize.Width()++;
+ nRealWidth++;
+ }
+#endif
+ if( aSize != aHorSBar.GetSizePixel() )
+ aHorSBar.SetSizePixel( aSize );
+ aHorSBar.SetVisibleSize( nVisibleWidth ); //nRealWidth );
+ aHorSBar.SetPageSize( (nVisibleWidth*75)/100 );
+ if( nResult & 0x0002 )
+ {
+ aHorSBar.SetThumbPos( nThumb );
+ aHorSBar.Show();
+ }
+ else
+ {
+ aHorSBar.SetThumbPos( 0 );
+ aHorSBar.Hide();
+ }
+
+#ifdef OS2
+ nRealWidth++;
+#endif
+ aOutputSize.Width() = nRealWidth;
+#if defined(WIN) || defined(WNT)
+ if( nResult & 0x0002 ) // hor scrollbar ?
+ nRealHeight++; // weil unterer Rand geclippt wird
+#endif
+#ifdef OS2
+ if( nResult & 0x0002 ) // hor scrollbar ?
+ nRealHeight++;
+#endif
+ aOutputSize.Height() = nRealHeight;
+}
+
+void __EXPORT SvImpIconView::Resize()
+{
+ StopEditTimer();
+ Rectangle aRect;
+ if( GetResizeRect(aRect) )
+ pView->Invalidate( aRect );
+ aOutputSize = pView->GetOutputSizePixel();
+ pImpCursor->Clear();
+
+#if 1
+ const Size& rSize = pView->Control::GetOutputSizePixel();
+ PositionScrollBars( rSize.Width(), rSize.Height() );
+ // Die ScrollBars werden asynchron ein/ausgeblendet, damit abgeleitete
+ // Klassen im Resize ein Arrange durchfuehren koennen, ohne dass
+ // die ScrollBars aufblitzen (SfxExplorerIconView!)
+ nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpIconView,UserEventHdl),0);
+#else
+ AdjustScrollBars();
+ if( GetResizeRect(aRect) )
+ PaintResizeRect( aRect );
+#endif
+}
+
+BOOL SvImpIconView::CheckHorScrollBar()
+{
+ if( !pZOrderList || !aHorSBar.IsVisible() )
+ return FALSE;
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+ if(!(pView->nWindowStyle & WB_HSCROLL) && !aOrigin.X() )
+ {
+ long nWidth = aOutputSize.Width();
+ USHORT nCount = pZOrderList->Count();
+ long nMostRight = 0;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pZOrderList->operator[](nCur);
+ long nRight = GetBoundingRect(pEntry).Right();
+ if( nRight > nWidth )
+ return FALSE;
+ if( nRight > nMostRight )
+ nMostRight = nRight;
+ }
+ aHorSBar.Hide();
+ aOutputSize.Height() += nHorSBarHeight;
+ aVirtOutputSize.Width() = nMostRight;
+ aHorSBar.SetThumbPos( 0 );
+ Range aRange;
+ aRange.Max() = nMostRight - 1;
+ aHorSBar.SetRange( aRange );
+ if( aVerSBar.IsVisible() )
+ {
+ Size aSize( aVerSBar.GetSizePixel());
+ aSize.Height() += nHorSBarHeight;
+ aVerSBar.SetSizePixel( aSize );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SvImpIconView::CheckVerScrollBar()
+{
+ if( !pZOrderList || !aVerSBar.IsVisible() )
+ return FALSE;
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+ if(!(pView->nWindowStyle & WB_VSCROLL) && !aOrigin.Y() )
+ {
+ long nDeepest = 0;
+ long nHeight = aOutputSize.Height();
+ USHORT nCount = pZOrderList->Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pZOrderList->operator[](nCur);
+ long nBottom = GetBoundingRect(pEntry).Bottom();
+ if( nBottom > nHeight )
+ return FALSE;
+ if( nBottom > nDeepest )
+ nDeepest = nBottom;
+ }
+ aVerSBar.Hide();
+ aOutputSize.Width() += nVerSBarWidth;
+ aVirtOutputSize.Height() = nDeepest;
+ aVerSBar.SetThumbPos( 0 );
+ Range aRange;
+ aRange.Max() = nDeepest - 1;
+ aVerSBar.SetRange( aRange );
+ if( aHorSBar.IsVisible() )
+ {
+ Size aSize( aHorSBar.GetSizePixel());
+ aSize.Width() += nVerSBarWidth;
+ aHorSBar.SetSizePixel( aSize );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+// blendet Scrollbars aus, wenn sie nicht mehr benoetigt werden
+void SvImpIconView::CheckScrollBars()
+{
+ CheckVerScrollBar();
+ if( CheckHorScrollBar() )
+ CheckVerScrollBar();
+}
+
+
+void __EXPORT SvImpIconView::GetFocus()
+{
+ if( pCursor )
+ {
+ pView->SetEntryFocus( pCursor, TRUE );
+ ShowCursor( TRUE );
+ }
+}
+
+void __EXPORT SvImpIconView::LoseFocus()
+{
+ StopEditTimer();
+ if( pCursor )
+ pView->SetEntryFocus( pCursor,FALSE );
+ ShowCursor( FALSE );
+}
+
+void SvImpIconView::UpdateAll()
+{
+ AdjustScrollBars();
+ pImpCursor->Clear();
+ pView->Invalidate();
+}
+
+void SvImpIconView::PaintEntry( SvLBoxEntry* pEntry, SvIcnVwDataEntry* pViewData )
+{
+ Point aPos( GetEntryPosition( pEntry ) );
+ PaintEntry( pEntry, aPos, pViewData );
+}
+
+void SvImpIconView::PaintEmphasis( const Rectangle& rRect, BOOL bSelected,
+ BOOL bCursored, OutputDevice* pOut )
+{
+ // HACK fuer D&D
+ if( nFlags & F_NO_EMPHASIS )
+ return;
+
+ if( !pOut )
+ pOut = pView;
+
+ // Selektion painten
+ Color aOldFillColor = pOut->GetFillColor();
+ Color aOldLineColor = pOut->GetLineColor();
+ Color aNewColor;
+ const StyleSettings& rStyleSettings = pOut->GetSettings().GetStyleSettings();
+ if( bSelected )
+ {
+ aNewColor = rStyleSettings.GetHighlightColor();
+ }
+ else
+ {
+#ifndef OS2
+ aNewColor =rStyleSettings.GetFieldColor();
+#else
+ aNewColor = pOut->GetBackground().GetColor();
+#endif
+ }
+
+ if( bCursored )
+ {
+ pOut->SetLineColor( Color( COL_BLACK ) );
+ }
+ pOut->SetFillColor( aNewColor );
+ pOut->DrawRect( rRect );
+ pOut->SetFillColor( aOldFillColor );
+ pOut->SetLineColor( aOldLineColor );
+}
+
+void SvImpIconView::PaintItem( const Rectangle& rRect,
+ SvLBoxItem* pItem, SvLBoxEntry* pEntry, USHORT nPaintFlags,
+ OutputDevice* pOut )
+{
+ if( nViewMode == VIEWMODE_ICON && pItem->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ const String& rStr = ((SvLBoxString*)pItem)->GetText();
+ DrawText( pOut, rRect, rStr, DRAWTEXT_FLAGS );
+ }
+ else
+ {
+ Point aPos( rRect.TopLeft() );
+ const Size& rSize = GetItemSize( pView, pEntry, pItem );
+ if( nPaintFlags & PAINTFLAG_HOR_CENTERED )
+ aPos.X() += (rRect.GetWidth() - rSize.Width() ) / 2;
+ if( nPaintFlags & PAINTFLAG_VER_CENTERED )
+ aPos.Y() += (rRect.GetHeight() - rSize.Height() ) / 2;
+ pItem->Paint( aPos, *(SvLBox*)pOut, 0, pEntry );
+ }
+}
+
+void SvImpIconView::PaintEntry( SvLBoxEntry* pEntry, const Point& rPos,
+ SvIcnVwDataEntry* pViewData, OutputDevice* pOut )
+{
+ if( !pView->IsUpdateMode() )
+ return;
+
+ if( !pOut )
+ pOut = pView;
+
+ SvLBoxContextBmp* pBmpItem;
+
+ pView->PreparePaint( pEntry );
+
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+
+ SvLBoxString* pStringItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+
+ BOOL bSelected = pViewData->IsSelected();
+ BOOL bCursored = pViewData->IsCursored();
+
+ Font aTempFont( pOut->GetFont() );
+ // waehrend D&D nicht die Fontfarbe wechseln, da sonst auch die
+ // Emphasis gezeichnet werden muss! (weisser Adler auf weissem Grund)
+ if( bSelected && !(nFlags & F_NO_EMPHASIS) )
+ {
+ const StyleSettings& rStyleSettings = pOut->GetSettings().GetStyleSettings();
+ Font aNewFont( aTempFont );
+ aNewFont.SetColor( rStyleSettings.GetHighlightTextColor() );
+ pOut->SetFont( aNewFont );
+ }
+ Rectangle aTextRect( CalcTextRect(pEntry,pStringItem,&rPos,FALSE,pViewData));
+ Rectangle aBmpRect( CalcBmpRect(pEntry, &rPos, pViewData ) );
+
+ switch( nViewMode )
+ {
+ case VIEWMODE_ICON:
+ pBmpItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ PaintEmphasis( aBmpRect, bSelected, bCursored, pOut );
+ PaintItem( aBmpRect, pBmpItem, pEntry,
+ PAINTFLAG_HOR_CENTERED | PAINTFLAG_VER_CENTERED, pOut );
+ PaintEmphasis( aTextRect, bSelected, FALSE, pOut );
+ PaintItem( aTextRect, pStringItem, pEntry, PAINTFLAG_HOR_CENTERED, pOut );
+ break;
+
+ case VIEWMODE_NAME:
+ pBmpItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ PaintEmphasis( aBmpRect, bSelected, bCursored, pOut );
+ PaintItem( aBmpRect, pBmpItem, pEntry, PAINTFLAG_VER_CENTERED, pOut );
+ PaintEmphasis( aTextRect, bSelected, FALSE, pOut );
+ PaintItem( aTextRect, pStringItem, pEntry,PAINTFLAG_VER_CENTERED, pOut );
+ break;
+
+ case VIEWMODE_TEXT:
+ PaintEmphasis( aTextRect, bSelected, bCursored, pOut );
+ PaintItem( aTextRect, pStringItem, pEntry, PAINTFLAG_VER_CENTERED, pOut );
+ break;
+ }
+ pOut->SetFont( aTempFont );
+}
+
+void SvImpIconView::SetEntryPosition( SvLBoxEntry* pEntry, const Point& rPos,
+ BOOL bAdjustAtGrid, BOOL bCheckScrollBars )
+{
+ if( pModel->GetParent(pEntry) == pCurParent )
+ {
+ ShowCursor( FALSE );
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ Rectangle aBoundRect( GetBoundingRect( pEntry, pViewData ));
+ pView->Invalidate( aBoundRect );
+ ToTop( pEntry );
+ if( rPos != aBoundRect.TopLeft() )
+ {
+ Point aGridOffs = pViewData->aGridRect.TopLeft() -
+ pViewData->aRect.TopLeft();
+ pImpCursor->Clear();
+ nFlags &= ~F_GRID_INSERT;
+ aBoundRect.SetPos( rPos );
+ pViewData->aRect = aBoundRect;
+ pViewData->aGridRect.SetPos( rPos + aGridOffs );
+ AdjustVirtSize( aBoundRect );
+ }
+ //HACK(Billigloesung, die noch verbessert werden muss)
+ if( bAdjustAtGrid )
+ {
+ AdjustAtGrid( pEntry );
+ ToTop( pEntry );
+ }
+ if( bCheckScrollBars && pView->IsUpdateMode() )
+ CheckScrollBars();
+
+ PaintEntry( pEntry, pViewData );
+ ShowCursor( TRUE );
+ }
+}
+
+void SvImpIconView::ViewDataInitialized( SvLBoxEntry*)
+{
+}
+
+void SvImpIconView::ModelHasEntryInvalidated( SvListEntry* pEntry )
+{
+ if( pEntry == pCursor )
+ ShowCursor( FALSE );
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ pView->Invalidate( pViewData->aRect );
+
+ if( nFlags & F_GRIDMODE )
+ Center( (SvLBoxEntry*)pEntry, pViewData );
+ else
+ pViewData->aRect.SetSize( CalcBoundingSize(
+ (SvLBoxEntry*)pEntry, pViewData ) );
+
+ ViewDataInitialized( (SvLBoxEntry*)pEntry );
+ pView->Invalidate( pViewData->aRect );
+ if( pEntry == pCursor )
+ ShowCursor( TRUE );
+}
+
+
+void SvImpIconView::InvalidateEntry( SvLBoxEntry* pEntry )
+{
+ const Rectangle& rRect = GetBoundingRect( pEntry );
+ pView->Invalidate( rRect );
+}
+
+void SvImpIconView::SetNoSelection()
+{
+}
+
+void SvImpIconView::SetDragDropMode( DragDropMode )
+{
+}
+
+void SvImpIconView::SetSelectionMode( SelectionMode )
+{
+}
+
+BOOL SvImpIconView::IsEntryInView( SvLBoxEntry* )
+{
+ return FALSE;
+}
+
+SvLBoxEntry* SvImpIconView::GetDropTarget( const Point& rPos )
+{
+ Point aDocPos( rPos );
+ CalcDocPos( aDocPos );
+ SvLBoxEntry* pTarget = GetEntry( aDocPos );
+ if( !pTarget || !pTarget->HasChilds() )
+ pTarget = pCurParent;
+ return pTarget;
+}
+
+SvLBoxEntry* SvImpIconView::GetEntry( const Point& rDocPos )
+{
+ CheckBoundingRects();
+ SvLBoxEntry* pTarget = 0;
+ // Z-Order-Liste vom Ende her absuchen
+ USHORT nCount = pZOrderList->Count();
+ while( nCount )
+ {
+ nCount--;
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pZOrderList->GetObject(nCount));
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( pViewData->aRect.IsInside( rDocPos ) )
+ {
+ pTarget = pEntry;
+ break;
+ }
+ }
+ return pTarget;
+}
+
+SvLBoxEntry* SvImpIconView::GetNextEntry( const Point& rDocPos, SvLBoxEntry* pCurEntry )
+{
+ CheckBoundingRects();
+ SvLBoxEntry* pTarget = 0;
+ USHORT nStartPos = pZOrderList->GetPos( (void*)pCurEntry );
+ if( nStartPos != USHRT_MAX )
+ {
+ USHORT nCount = pZOrderList->Count();
+ for( USHORT nCur = nStartPos+1; nCur < nCount; nCur++ )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pZOrderList->GetObject(nCur));
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( pViewData->aRect.IsInside( rDocPos ) )
+ {
+ pTarget = pEntry;
+ break;
+ }
+ }
+ }
+ return pTarget;
+}
+
+SvLBoxEntry* SvImpIconView::GetPrevEntry( const Point& rDocPos, SvLBoxEntry* pCurEntry )
+{
+ CheckBoundingRects();
+ SvLBoxEntry* pTarget = 0;
+ USHORT nStartPos = pZOrderList->GetPos( (void*)pCurEntry );
+ if( nStartPos != USHRT_MAX && nStartPos != 0 )
+ {
+ nStartPos--;
+ do
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pZOrderList->GetObject(nStartPos));
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( pViewData->aRect.IsInside( rDocPos ) )
+ {
+ pTarget = pEntry;
+ break;
+ }
+ } while( nStartPos > 0 );
+ }
+ return pTarget;
+}
+
+
+Point SvImpIconView::GetEntryPosition( SvLBoxEntry* pEntry )
+{
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ DBG_ASSERT(pViewData,"Entry not in model");
+ return pViewData->aRect.TopLeft();
+}
+
+const Rectangle& SvImpIconView::GetBoundingRect( SvLBoxEntry* pEntry, SvIcnVwDataEntry* pViewData )
+{
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+ DBG_ASSERT(pViewData,"Entry not in model");
+ if( !IsBoundingRectValid( pViewData->aRect ))
+ FindBoundingRect( pEntry, pViewData );
+ return pViewData->aRect;
+}
+
+void SvImpIconView::SetSpaceBetweenEntries( long nHor, long nVer )
+{
+ nHorDist = nHor;
+ nVerDist = nVer;
+}
+
+Rectangle SvImpIconView::CalcBmpRect( SvLBoxEntry* pEntry, const Point* pPos,
+ SvIcnVwDataEntry* pViewData )
+{
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+
+ Rectangle aBound = GetBoundingRect( pEntry, pViewData );
+ if( pPos )
+ aBound.SetPos( *pPos );
+ Point aPos( aBound.TopLeft() );
+
+ switch( nViewMode )
+ {
+ case VIEWMODE_ICON:
+ {
+ aPos.X() += ( aBound.GetWidth() - nMaxBmpWidth ) / 2;
+ Size aSize( nMaxBmpWidth, nMaxBmpHeight );
+ // das Bitmap-Rechteck soll nicht das TextRect beruehren
+ aSize.Height() -= 3;
+ return Rectangle( aPos, aSize );
+ }
+
+ case VIEWMODE_NAME:
+ return Rectangle( aPos,
+ Size( nMaxBmpWidth, aBound.GetHeight() ));
+
+ case VIEWMODE_TEXT:
+ return Rectangle( aPos, aBound.GetSize() );
+
+ default:
+ {
+ Rectangle aRect;
+ return aRect;
+ }
+ }
+}
+
+Rectangle SvImpIconView::CalcTextRect( SvLBoxEntry* pEntry,
+ SvLBoxString* pItem, const Point* pPos, BOOL bForInplaceEdit,
+ SvIcnVwDataEntry* pViewData )
+{
+ long nBmpHeight, nBmpWidth;
+
+ if( !pItem )
+ pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+
+ Size aTextSize( GetItemSize( pView, pEntry, pItem, pViewData ));
+ aTextSize.Width() += 2*LROFFS_TEXT;
+
+ Size aContextBmpSize(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)->GetSize(pView,pEntry));
+ Rectangle aBound = GetBoundingRect( pEntry, pViewData );
+ if( pPos )
+ aBound.SetPos( *pPos );
+ Point aPos( aBound.TopLeft() );
+
+ switch( nViewMode )
+ {
+ case VIEWMODE_ICON:
+ nBmpHeight = aContextBmpSize.Height();
+ if( nBmpHeight < nMaxBmpHeight )
+ nBmpHeight = nMaxBmpHeight;
+ aPos.Y() += nBmpHeight;
+
+ // beim Inplace-Editieren, spendieren wir ein bisschen mehr Platz
+ if( bForInplaceEdit )
+ {
+ // 20% rauf
+ long nMinWidth = (( (aContextBmpSize.Width()*10) / 100 ) * 2 ) +
+ aContextBmpSize.Width();
+ if( nMinWidth > aBound.GetWidth() )
+ nMinWidth = aBound.GetWidth();
+
+ if( aTextSize.Width() < nMinWidth )
+ aTextSize.Width() = nMinWidth;
+
+ // beim Inplace-Ed. darfs auch untere Eintraege ueberlappen
+ Rectangle aMaxGridTextRect = CalcMaxTextRect(pEntry, pViewData);
+ Size aOptSize = aMaxGridTextRect.GetSize();
+ if( aOptSize.Height() > aTextSize.Height() )
+ aTextSize.Height() = aOptSize.Height();
+ }
+
+
+ aPos.X() += ( aBound.GetWidth() - aTextSize.Width() ) / 2;
+ break;
+
+ case VIEWMODE_NAME:
+ nBmpWidth = aContextBmpSize.Width();
+ if( nBmpWidth < nMaxBmpWidth )
+ nBmpWidth = nMaxBmpWidth;
+ aPos.X() += nBmpWidth;
+ // vertikal ausrichten
+ aPos.Y() += ( nBmpWidth - aTextSize.Height() ) / 2;
+ break;
+ }
+
+ Rectangle aRect( aPos, aTextSize );
+// KNALLT BEIM D&D, WENN GECLIPPT WIRD (In DrawText von Thomas)
+// ClipAtVirtOutRect( aRect );
+ return aRect;
+}
+
+
+long SvImpIconView::CalcBoundingWidth( SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const
+{
+ DBG_ASSERT(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP),"No Bitmaps");
+ DBG_ASSERT(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING),"No Text");
+ long nStringWidth = GetItemSize( pView, pEntry, pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING),pViewData).Width();
+ nStringWidth += 2*LROFFS_TEXT;
+ long nBmpWidth = pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)->GetSize(pView,pEntry).Width();
+ long nWidth = 0;
+
+ switch( nViewMode )
+ {
+ case VIEWMODE_ICON:
+ nWidth = Max( nStringWidth, nBmpWidth );
+ nWidth = Max( nWidth, nMaxBmpWidth );
+ break;
+
+ case VIEWMODE_NAME:
+ nWidth = Max( nBmpWidth, nMaxBmpWidth );
+ nWidth += NAMEVIEW_OFFS_BMP_STRING; // Abstand Bitmap String
+ nWidth += nStringWidth;
+ break;
+
+ case VIEWMODE_TEXT:
+ nWidth = nStringWidth;
+ break;
+ }
+ return nWidth;
+}
+
+long SvImpIconView::CalcBoundingHeight( SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const
+{
+ DBG_ASSERT(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP),"No Bitmaps");
+ DBG_ASSERT(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING),"No Text");
+ long nStringHeight = GetItemSize(pView,pEntry,pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING),pViewData).Height();
+ long nBmpHeight = pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)->GetSize(pView,pEntry).Height();
+ long nHeight = 0;
+
+ switch( nViewMode )
+ {
+ case VIEWMODE_ICON:
+ nHeight = Max( nBmpHeight, nMaxBmpHeight );
+ nHeight += ICONVIEW_OFFS_BMP_STRING; // Abstand Bitmap String
+ nHeight += nStringHeight;
+ break;
+
+ case VIEWMODE_NAME:
+ nHeight = Max( nBmpHeight, nMaxBmpHeight );
+ nHeight = Max( nHeight, nStringHeight );
+ break;
+
+ case VIEWMODE_TEXT:
+ nHeight = nStringHeight;
+ break;
+ }
+ if( nHeight > nMaxBoundHeight )
+ {
+ ((SvImpIconView*)this)->nMaxBoundHeight = nHeight;
+ ((SvImpIconView*)this)->aHorSBar.SetLineSize( nHeight / 2 );
+ ((SvImpIconView*)this)->aVerSBar.SetLineSize( nHeight / 2 );
+ }
+ return nHeight;
+}
+
+Size SvImpIconView::CalcBoundingSize( SvLBoxEntry* pEntry,
+ SvIcnVwDataEntry* pViewData ) const
+{
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+ return Size( CalcBoundingWidth(pEntry,pViewData),
+ CalcBoundingHeight(pEntry,pViewData) );
+}
+
+void SvImpIconView::RecalcAllBoundingRects()
+{
+ nMaxBoundHeight = 0;
+ pZOrderList->Remove(0, pZOrderList->Count() );
+ SvLBoxEntry* pEntry = pModel->FirstChild( pCurParent );
+ while( pEntry )
+ {
+ FindBoundingRect( pEntry );
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ pEntry = pModel->NextSibling( pEntry );
+ }
+ bMustRecalcBoundingRects = FALSE;
+ AdjustScrollBars();
+}
+
+void SvImpIconView::RecalcAllBoundingRectsSmart()
+{
+ nMaxBoundHeight = 0;
+ pZOrderList->Remove(0, pZOrderList->Count() );
+ SvLBoxEntry* pEntry = pModel->FirstChild( pCurParent );
+ while( pEntry )
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( IsBoundingRectValid( pViewData->aRect ))
+ {
+ Size aBoundSize( pViewData->aRect.GetSize() );
+ if( aBoundSize.Height() > nMaxBoundHeight )
+ nMaxBoundHeight = aBoundSize.Height();
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ }
+ else
+ {
+ FindBoundingRect( pEntry, pViewData );
+ }
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ pEntry = pModel->NextSibling( pEntry );
+ }
+ AdjustScrollBars();
+}
+
+void SvImpIconView::UpdateBoundingRects()
+{
+ SvLBoxEntry* pEntry = pModel->FirstChild( pCurParent );
+ while( pEntry )
+ {
+ GetBoundingRect( pEntry );
+ pEntry = pModel->NextSibling( pEntry );
+ }
+}
+
+void SvImpIconView::FindBoundingRect( SvLBoxEntry* pEntry,
+ SvIcnVwDataEntry* pViewData )
+{
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+
+ Size aSize( CalcBoundingSize( pEntry, pViewData ) );
+ Point aPos;
+
+ DBG_ASSERT(!pViewData->IsEntryPosLocked(),"Locked entry pos in FindBoundingRect");
+ // damits in der IconView nicht drunter & drueber geht
+ if( pViewData->IsEntryPosLocked() && IsBoundingRectValid(pViewData->aRect) )
+ {
+ AdjustVirtSize( pViewData->aRect );
+ return;
+ }
+
+ aPos = FindNextEntryPos( aSize );
+
+ if( nFlags & F_GRIDMODE )
+ {
+ Rectangle aGridRect( aPos, Size(nGridDX, nGridDY) );
+ pViewData->aGridRect = aGridRect;
+ Center( pEntry, pViewData );
+ AdjustVirtSize( pViewData->aRect );
+ pImpCursor->SetGridUsed( pViewData->aRect );
+ }
+ else
+ {
+ pViewData->aRect = Rectangle( aPos, aSize );
+ AdjustVirtSize( pViewData->aRect );
+ }
+}
+
+
+void SvImpIconView::SetCursor( SvLBoxEntry* pEntry )
+{
+ if( pEntry == pCursor )
+ return;
+
+ ShowCursor( FALSE );
+ if( pCursor )
+ {
+ pView->SetEntryFocus( pCursor, FALSE );
+ if( pView->GetSelectionMode() == SINGLE_SELECTION )
+ pView->Select( pCursor, FALSE );
+ }
+ pCursor = pEntry;
+ ToTop( pCursor );
+ if( pCursor )
+ {
+ pView->SetEntryFocus(pCursor, TRUE );
+ if( pView->GetSelectionMode() == SINGLE_SELECTION )
+ pView->Select( pCursor, TRUE );
+ ShowCursor( TRUE );
+ }
+}
+
+
+void SvImpIconView::ShowCursor( BOOL bShow )
+{
+ if( !pCursor || !bShow || !pView->HasFocus() )
+ {
+ pView->HideFocus();
+ return;
+ }
+ Rectangle aRect ( CalcFocusRect( pCursor ) );
+ pView->ShowFocus( aRect );
+}
+
+
+void SvImpIconView::HideDDIcon()
+{
+ pView->Update();
+ ImpHideDDIcon();
+ pDDBufDev = pDDDev;
+ pDDDev = 0;
+}
+
+void SvImpIconView::ImpHideDDIcon()
+{
+ if( pDDDev )
+ {
+ Size aSize( pDDDev->GetOutputSizePixel() );
+ // pView restaurieren
+ pView->DrawOutDev( aDDLastRectPos, aSize, Point(), aSize, *pDDDev );
+ }
+}
+
+
+void SvImpIconView::ShowDDIcon( SvLBoxEntry* pRefEntry, const Point& rPosPix )
+{
+ pView->Update();
+ if( pRefEntry != pDDRefEntry )
+ {
+ DELETEZ(pDDDev);
+ DELETEZ(pDDBufDev);
+ }
+ BOOL bSelected = pView->SvListView::Select( pRefEntry, FALSE );
+ if( !pDDDev )
+ {
+ if( pDDBufDev )
+ {
+ // nicht bei jedem Move ein Device anlegen, da dies besonders
+ // auf Remote-Clients zu langsam ist
+ pDDDev = pDDBufDev;
+ pDDBufDev = 0;
+ }
+ else
+ {
+ pDDDev = new VirtualDevice( *pView );
+ pDDDev->SetFont( pView->GetFont() );
+ }
+ }
+ else
+ {
+ ImpHideDDIcon();
+ }
+ const Rectangle& rRect = GetBoundingRect( pRefEntry );
+ pDDDev->SetOutputSizePixel( rRect.GetSize() );
+
+ Point aPos( rPosPix );
+ CalcDocPos( aPos );
+
+ Size aSize( pDDDev->GetOutputSizePixel() );
+ pDDRefEntry = pRefEntry;
+ aDDLastEntryPos = aPos;
+ aDDLastRectPos = aPos;
+
+ // Hintergrund sichern
+ pDDDev->DrawOutDev( Point(), aSize, aPos, aSize, *pView );
+ // Icon in pView malen
+ nFlags |= F_NO_EMPHASIS;
+ PaintEntry( pRefEntry, aPos );
+ nFlags &= ~F_NO_EMPHASIS;
+ if( bSelected )
+ pView->SvListView::Select( pRefEntry, TRUE );
+}
+
+void SvImpIconView::HideShowDDIcon( SvLBoxEntry* pRefEntry, const Point& rPosPix )
+{
+/* In Notfaellen folgenden flackernden Code aktivieren:
+
+ HideDDIcon();
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+*/
+ if( !pDDDev )
+ {
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+ }
+
+ if( pRefEntry != pDDRefEntry )
+ {
+ HideDDIcon();
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+ }
+
+ Point aEmptyPoint;
+
+ Point aCurEntryPos( rPosPix );
+ CalcDocPos( aCurEntryPos );
+
+ const Rectangle& rRect = GetBoundingRect( pRefEntry );
+ Size aEntrySize( rRect.GetSize() );
+ Rectangle aPrevEntryRect( aDDLastEntryPos, aEntrySize );
+ Rectangle aCurEntryRect( aCurEntryPos, aEntrySize );
+
+ if( !aPrevEntryRect.IsOver( aCurEntryRect ) )
+ {
+ HideDDIcon();
+ ShowDDIcon( pRefEntry, rPosPix );
+ return;
+ }
+
+ // Ueberlappung des neuen und alten D&D-Pointers!
+
+ Rectangle aFullRect( aPrevEntryRect.Union( aCurEntryRect ) );
+ if( !pDDTempDev )
+ {
+ pDDTempDev = new VirtualDevice( *pView );
+ pDDTempDev->SetFont( pView->GetFont() );
+ }
+
+ Size aFullSize( aFullRect.GetSize() );
+ Point aFullPos( aFullRect.TopLeft() );
+
+ pDDTempDev->SetOutputSizePixel( aFullSize );
+
+ // Hintergrund (mit dem alten D&D-Pointer!) sichern
+ pDDTempDev->DrawOutDev( aEmptyPoint, aFullSize, aFullPos, aFullSize, *pView );
+ // den alten Buffer in den neuen Buffer pasten
+ aDDLastRectPos = aDDLastRectPos - aFullPos;
+
+ pDDTempDev->DrawOutDev(
+ aDDLastRectPos,
+ pDDDev->GetOutputSizePixel(),
+ aEmptyPoint,
+ pDDDev->GetOutputSizePixel(),
+ *pDDDev );
+
+ // Swap
+ VirtualDevice* pTemp = pDDDev;
+ pDDDev = pDDTempDev;
+ pDDTempDev = pTemp;
+
+ // in den restaurierten Hintergrund den neuen D&D-Pointer zeichnen
+ pDDTempDev->SetOutputSizePixel( pDDDev->GetOutputSizePixel() );
+ pDDTempDev->DrawOutDev(
+ aEmptyPoint, aFullSize, aEmptyPoint, aFullSize, *pDDDev );
+ Point aRelPos = aCurEntryPos - aFullPos;
+ nFlags |= F_NO_EMPHASIS;
+ PaintEntry( pRefEntry, aRelPos, 0, pDDTempDev );
+ nFlags &= ~F_NO_EMPHASIS;
+
+ aDDLastRectPos = aFullPos;
+ aDDLastEntryPos = aCurEntryPos;
+
+ pView->DrawOutDev(
+ aDDLastRectPos,
+ pDDDev->GetOutputSizePixel(),
+ aEmptyPoint,
+ pDDDev->GetOutputSizePixel(),
+ *pDDTempDev );
+
+ BOOL bSelected = pView->SvListView::Select( pRefEntry, FALSE );
+ if( bSelected )
+ pView->SvListView::Select( pRefEntry, TRUE );
+}
+
+void SvImpIconView::ShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL )
+{
+ CheckBoundingRects();
+ Rectangle aRect;
+ if( pEntry != pCurParent &&
+ (pEntry->HasChilds() || pEntry->HasChildsOnDemand()) )
+ aRect = CalcBmpRect( pEntry );
+ else
+ {
+ aRect.SetSize( aOutputSize );
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin());
+ aOrigin *= -1; // in Doc-Koord wandeln
+ aRect.SetPos( aOrigin );
+ aRect.Left()++; aRect.Top()++;
+ aRect.Right()--; aRect.Bottom()--;
+ }
+ ImpDrawXORRect( aRect );
+}
+
+BOOL SvImpIconView::NotifyMoving( SvLBoxEntry* pTarget, SvLBoxEntry* pEntry,
+ SvLBoxEntry*& rpNewPar, ULONG& rNewChildPos )
+{
+ if( pTarget == pCurParent && pModel->GetParent(pEntry) == pCurParent )
+ {
+ // D&D innerhalb einer Childlist
+ StopEditTimer();
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ Size aSize( pViewData->aRect.GetSize() );
+ Point aNewPos = FindNextEntryPos( aSize );
+ AdjustVirtSize( Rectangle( aNewPos, aSize ) );
+ SetEntryPosition( pEntry, aNewPos, FALSE, TRUE );
+ return FALSE;
+ }
+ return pView->SvLBox::NotifyMoving(pTarget,pEntry,rpNewPar,rNewChildPos);
+}
+
+BOOL SvImpIconView::NotifyCopying( SvLBoxEntry* pTarget, SvLBoxEntry* pEntry,
+ SvLBoxEntry*& rpNewParent, ULONG& rNewChildPos )
+{
+ return pView->SvLBox::NotifyCopying(pTarget,pEntry,rpNewParent,rNewChildPos);
+}
+
+void SvImpIconView::WriteDragServerInfo( const Point& rPos, SvLBoxDDInfo* pInfo)
+{
+ SvLBoxEntry* pCurEntry = GetCurEntry();
+ Point aEntryPos;
+ if( pCurEntry )
+ {
+ aEntryPos = rPos;
+ aEntryPos -= GetEntryPosition( pCurEntry );
+ }
+ pInfo->nMouseRelX = aEntryPos.X();
+ pInfo->nMouseRelY = aEntryPos.Y();
+}
+
+void SvImpIconView::ReadDragServerInfo( const Point& rPos, SvLBoxDDInfo* pInfo )
+{
+ Point aDropPos( rPos );
+ aDropPos.X() -= pInfo->nMouseRelX;
+ aDropPos.Y() -= pInfo->nMouseRelY;
+ SetNextEntryPos( aDropPos );
+}
+
+void SvImpIconView::InvalidateBoundingRect( SvLBoxEntry* pEntry )
+{
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ InvalidateBoundingRect( pViewData->aRect );
+}
+
+void SvImpIconView::PrepareCommandEvent( const Point& rPt )
+{
+ aMouseMoveTimer.Stop();
+ StopEditTimer();
+ nFlags |= F_CMD_ARRIVED;
+ SvLBoxEntry* pEntry = pView->GetEntry( rPt, TRUE );
+ if( (nFlags & F_DOWN_CTRL) && pEntry && !pView->IsSelected(pEntry) )
+ pView->Select( pEntry, TRUE );
+ nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT);
+}
+
+void SvImpIconView::SttDrag( const Point& rPos )
+{
+ PrepareCommandEvent( rPos );
+
+ nFlags |= F_DRAG_SOURCE;
+ ShowCursor( FALSE );
+}
+
+void SvImpIconView::EndDrag()
+{
+ ShowCursor( TRUE );
+ nFlags &= (~F_DRAG_SOURCE);
+}
+
+void SvImpIconView::ToTop( SvLBoxEntry* pEntry )
+{
+ DBG_ASSERT(pZOrderList->GetPos(pEntry)!=0xffff,"ToTop:ZOrder?");
+ if( pZOrderList->GetObject( pZOrderList->Count() -1 ) != pEntry )
+ {
+ USHORT nPos = pZOrderList->GetPos( (void*)pEntry );
+ pZOrderList->Remove( nPos, 1 );
+ pZOrderList->Insert( pEntry, pZOrderList->Count() );
+ }
+}
+
+void SvImpIconView::SetCurParent( SvLBoxEntry* pNewParent )
+{
+ Clear();
+ pCurParent = pNewParent;
+ ImpArrange();
+}
+
+void SvImpIconView::ClipAtVirtOutRect( Rectangle& rRect ) const
+{
+ if( rRect.Bottom() >= aVirtOutputSize.Height() )
+ rRect.Bottom() = aVirtOutputSize.Height() - 1;
+ if( rRect.Right() >= aVirtOutputSize.Width() )
+ rRect.Right() = aVirtOutputSize.Width() - 1;
+ if( rRect.Top() < 0 )
+ rRect.Top() = 0;
+ if( rRect.Left() < 0 )
+ rRect.Left() = 0;
+}
+
+// rRect: Bereich des Dokumentes (in Dokumentkoordinaten), der
+// sichtbar gemacht werden soll.
+// bScrBar == TRUE: Das Rect wurde aufgrund eines ScrollBar-Events berechnet
+
+void SvImpIconView::MakeVisible( const Rectangle& rRect, BOOL bScrBar )
+{
+ Rectangle aRect( rRect );
+ ClipAtVirtOutRect( aRect );
+ MapMode aMapMode( pView->GetMapMode() );
+ Point aOrigin( aMapMode.GetOrigin() );
+ // in Dokumentkoordinate umwandeln
+ aOrigin *= -1;
+
+ Rectangle aOutputArea( aOrigin, aOutputSize );
+ if( aOutputArea.IsInside( aRect ) )
+ return; // ist schon sichtbar
+
+ long nDy;
+ if( aRect.Top() < aOutputArea.Top() )
+ {
+ // nach oben scrollen (nDy < 0)
+ nDy = aRect.Top() - aOutputArea.Top();
+ }
+ else if( aRect.Bottom() > aOutputArea.Bottom() )
+ {
+ // nach unten scrollen (nDy > 0)
+ nDy = aRect.Bottom() - aOutputArea.Bottom();
+ }
+ else
+ nDy = 0;
+
+ long nDx;
+ if( aRect.Left() < aOutputArea.Left() )
+ {
+ // nach links scrollen (nDx < 0)
+ nDx = aRect.Left() - aOutputArea.Left();
+ }
+ else if( aRect.Right() > aOutputArea.Right() )
+ {
+ // nach rechts scrollen (nDx > 0)
+ nDx = aRect.Right() - aOutputArea.Right();
+ }
+ else
+ nDx = 0;
+
+ aOrigin.X() += nDx;
+ aOrigin.Y() += nDy;
+ aOutputArea.SetPos( aOrigin );
+
+ pView->Update();
+
+ // Origin fuer SV invertieren (damit wir in
+ // Dokumentkoordinaten scrollen/painten koennen)
+ aOrigin *= -1;
+ aMapMode.SetOrigin( aOrigin );
+ pView->SetMapMode( aMapMode );
+
+ // in umgekehrte Richtung scrollen!
+ pView->Control::Scroll( -nDx, -nDy, aOutputArea, TRUE );
+ if( aHorSBar.IsVisible() || aVerSBar.IsVisible() )
+ {
+ if( !bScrBar )
+ {
+ aOrigin *= -1;
+ // Thumbs korrigieren
+ if(aHorSBar.IsVisible() && aHorSBar.GetThumbPos() != aOrigin.X())
+ aHorSBar.SetThumbPos( aOrigin.X() );
+ if(aVerSBar.IsVisible() && aVerSBar.GetThumbPos() != aOrigin.Y())
+ aVerSBar.SetThumbPos( aOrigin.Y() );
+ }
+ }
+ // pruefen, ob ScrollBars noch benoetigt werden
+ CheckScrollBars();
+ pView->Update();
+}
+
+
+SvLBoxEntry* SvImpIconView::GetNewCursor()
+{
+ SvLBoxEntry* pNewCursor;
+ if( pCursor )
+ {
+ pNewCursor = pImpCursor->GoLeftRight( pCursor, FALSE );
+ if( !pNewCursor )
+ {
+ pNewCursor = pImpCursor->GoLeftRight( pCursor, TRUE );
+ if( !pNewCursor )
+ {
+ pNewCursor = pImpCursor->GoUpDown( pCursor, FALSE );
+ if( !pNewCursor )
+ pNewCursor = pImpCursor->GoUpDown( pCursor, TRUE );
+ }
+ }
+ }
+ else
+ pNewCursor = pModel->FirstChild( pCurParent );
+ DBG_ASSERT(!pNewCursor|| (pCursor&&pCursor!=pNewCursor),"GetNewCursor failed");
+ return pNewCursor;
+}
+
+
+USHORT SvImpIconView:: GetSelectionCount() const
+{
+ USHORT nSelected = 0;
+ SvLBoxEntry* pEntry = pModel->FirstChild( pCurParent);
+ while( pEntry )
+ {
+ if( pView->IsSelected( pEntry ) )
+ nSelected++;
+ pEntry = pModel->NextSibling( pEntry );
+ }
+ return nSelected;
+}
+
+
+void SvImpIconView::ToggleSelection( SvLBoxEntry* pEntry )
+{
+ BOOL bSel;
+ if( pView->IsSelected( pEntry ) )
+ bSel = FALSE;
+ else
+ bSel = TRUE;
+ pView->Select( pEntry, bSel );
+}
+
+void SvImpIconView::DeselectAllBut( SvLBoxEntry* pThisEntryNot )
+{
+ ClearSelectedRectList();
+ SvLBoxEntry* pEntry = pModel->FirstChild( pCurParent );
+ while( pEntry )
+ {
+ if( pEntry != pThisEntryNot && pView->IsSelected( pEntry ))
+ pView->Select( pEntry, FALSE );
+ pEntry = pModel->NextSibling( pEntry );
+ }
+}
+
+#define ICN_ROWS 50
+#define ICN_COLS 30
+
+ImpIcnCursor::ImpIcnCursor( SvImpIconView* pOwner )
+{
+ pView = pOwner;
+ pColumns = 0;
+ pRows = 0;
+ pCurEntry = 0;
+ nDeltaWidth = 0;
+ nDeltaHeight= 0;
+ nCols = 0;
+ nRows = 0;
+ nGridCols = 0;
+ nGridRows = 0;
+ pGridMap = 0;
+}
+
+ImpIcnCursor::~ImpIcnCursor()
+{
+ delete[] pColumns;
+ delete[] pRows;
+ delete pGridMap;
+}
+
+USHORT ImpIcnCursor::GetSortListPos( SvPtrarr* pList, long nValue,
+ int bVertical )
+{
+ USHORT nCount = (USHORT)pList->Count();
+ if( !nCount )
+ return 0;
+
+ USHORT nCurPos = 0;
+ long nPrevValue = LONG_MIN;
+ while( nCount )
+ {
+ const Rectangle& rRect=
+ pView->GetBoundingRect((SvLBoxEntry*)(pList->GetObject(nCurPos)));
+ long nCurValue;
+ if( bVertical )
+ nCurValue = rRect.Top();
+ else
+ nCurValue = rRect.Left();
+ if( nValue >= nPrevValue && nValue <= nCurValue )
+ return (USHORT)nCurPos;
+ nPrevValue = nCurValue;
+ nCount--;
+ nCurPos++;
+ }
+ return pList->Count();
+}
+
+void ImpIcnCursor::ImplCreate()
+{
+ pView->CheckBoundingRects();
+ DBG_ASSERT(pColumns==0&&pRows==0,"ImplCreate: Not cleared");
+
+ SetDeltas();
+
+ pColumns = new SvPtrarr[ nCols ];
+ pRows = new SvPtrarr[ nRows ];
+
+ DELETEZ(pGridMap);
+
+ SvLBoxTreeList* pModel = pView->pModel;
+ SvLBoxEntry* pEntry = pModel->FirstChild( pView->pCurParent );
+ while( pEntry )
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA2(pEntry);
+ // const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ Rectangle rRect( pView->CalcBmpRect( pEntry,0,pViewData ) );
+ short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / nDeltaHeight );
+ short nX = (short)( ((rRect.Left()+rRect.Right())/2) / nDeltaWidth );
+
+ // Rundungsfehler abfangen
+ if( nY >= nRows )
+ nY = sal::static_int_cast< short >(nRows - 1);
+ if( nX >= nCols )
+ nX = sal::static_int_cast< short >(nCols - 1);
+
+ USHORT nIns = GetSortListPos( &pColumns[nX], rRect.Top(), TRUE );
+ pColumns[ nX ].Insert( pEntry, nIns );
+
+ nIns = GetSortListPos( &pRows[nY], rRect.Left(), FALSE );
+ pRows[ nY ].Insert( pEntry, nIns );
+
+ pViewData->nX = nX;
+ pViewData->nY = nY;
+
+ pEntry = pModel->NextSibling( pEntry );
+ }
+}
+
+void ImpIcnCursor::CreateGridMap()
+{
+ if( pGridMap )
+ return;
+
+ const Size& rSize = pView->aVirtOutputSize;
+ long nWidth = rSize.Width();
+ if( nWidth < pView->nMaxVirtWidth )
+ nWidth = pView->nMaxVirtWidth;
+ nWidth -= 2*LROFFS_WINBORDER;
+ if( nWidth <= 0 )
+ nWidth = 1;
+
+ nGridDX = pView->nGridDX;
+ nGridDY = pView->nGridDY;
+
+ // Hinweis: Wegen der Abrundung bei Berechnung von nGridCols
+ // ist es moeglich, dass Eintrage nicht im Grid liegen. Diese
+ // wurden typischerweise manuell verschoben und gelockt
+ nGridCols = nWidth / nGridDX;
+ if( !nGridCols ) nGridCols = 1;
+
+ nGridRows = rSize.Height() / nGridDY;
+ // nRows nicht abrunden, da zur Vermeidung von Ueberlappungen
+ // das gesamte BoundingRect des Eintrags zur Markierung im Grid
+ // herangezogen wird.
+ if( (nGridRows * nGridDY) < rSize.Height() )
+ nGridRows++;
+ else if( !nGridRows )
+ nGridRows = 1;
+
+ //XXX
+ //nGridRows += 50; // in fuenfziger-Schritten
+
+ pGridMap = new BOOL[ nGridRows*nGridCols];
+ memset( (void*)pGridMap, 0, nGridRows*nGridCols );
+
+ SvLBoxTreeList* pModel = pView->pModel;
+ SvLBoxEntry* pEntry = pModel->FirstChild( pView->pCurParent );
+ while( pEntry )
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA2(pEntry);
+ const Rectangle& rRect = pViewData->aRect;
+ // nur, wenn der Entry schon plaziert ist
+ if( pView->IsBoundingRectValid( rRect ))
+ {
+ // Alle vom Eintrag beruehrten Grids kennzeichnen
+ SetGridUsed( pView->GetBoundingRect( pEntry, pViewData ) );
+ }
+ pEntry = pModel->NextSibling( pEntry );
+ }
+}
+
+BOOL ImpIcnCursor::GetGrid( const Point& rDocPos, USHORT& rGridX, USHORT& rGridY ) const
+{
+ Point aPos( rDocPos );
+ aPos.X() -= LROFFS_WINBORDER;
+ aPos.Y() -= TBOFFS_WINBORDER;
+ rGridX = (USHORT)(aPos.X() / nGridDX);
+ rGridY = (USHORT)(aPos.Y() / nGridDY);
+ BOOL bInGrid = TRUE;
+ if( rGridX >= nGridCols )
+ {
+ rGridX = sal::static_int_cast< USHORT >(nGridCols - 1);
+ bInGrid = FALSE;
+ }
+ if( rGridY >= nGridRows )
+ {
+ rGridY = sal::static_int_cast< USHORT >(nGridRows - 1);
+ if( !bInGrid )
+ return FALSE; // beide Koordinaten nicht im Grid
+ }
+ return TRUE;
+}
+
+void ImpIcnCursor::SetGridUsed( const Rectangle& rRect, BOOL bUsed )
+{
+ CreateGridMap();
+ USHORT nTLX, nTLY, nBRX, nBRY;
+
+ BOOL bTLInGrid = GetGrid( rRect.TopLeft(), nTLX, nTLY );
+ BOOL bBRInGrid = GetGrid( rRect.BottomRight(), nBRX, nBRY );
+
+ if( !bTLInGrid && !bBRInGrid )
+ return;
+
+ for( USHORT nCurY = nTLY; nCurY <= nBRY; nCurY++ )
+ {
+ for( USHORT nCurX = nTLX; nCurX <= nBRX; nCurX++ )
+ {
+ SetGridUsed( nCurX, nCurY, bUsed );
+ }
+ }
+}
+
+void ImpIcnCursor::Clear( BOOL bGridToo )
+{
+ if( pColumns )
+ {
+ delete[] pColumns;
+ delete[] pRows;
+ pColumns = 0;
+ pRows = 0;
+ pCurEntry = 0;
+ nDeltaWidth = 0;
+ nDeltaHeight = 0;
+ }
+ if( bGridToo && pGridMap )
+ {
+ DELETEZ(pGridMap);
+ nGridRows = 0;
+ nGridCols = 0;
+ }
+}
+
+SvLBoxEntry* ImpIcnCursor::SearchCol(USHORT nCol,USHORT nTop,USHORT nBottom,
+ USHORT, BOOL bDown, BOOL bSimple )
+{
+ DBG_ASSERT(pCurEntry,"SearchCol: No reference entry");
+ SvPtrarr* pList = &(pColumns[ nCol ]);
+ USHORT nCount = pList->Count();
+ if( !nCount )
+ return 0;
+
+ const Rectangle& rRefRect = pView->GetBoundingRect(pCurEntry);
+
+ if( bSimple )
+ {
+ USHORT nListPos = pList->GetPos( pCurEntry );
+ DBG_ASSERT(nListPos!=0xffff,"Entry not in Col-List");
+ if( bDown )
+ {
+ while( nListPos < nCount-1 )
+ {
+ nListPos++;
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ if( rRect.Top() > rRefRect.Top() )
+ return pEntry;
+ }
+ return 0;
+ }
+ else
+ {
+ while( nListPos )
+ {
+ nListPos--;
+ if( nListPos < nCount )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ if( rRect.Top() < rRefRect.Top() )
+ return pEntry;
+ }
+ }
+ return 0;
+ }
+ }
+
+ if( nTop > nBottom )
+ {
+ USHORT nTemp = nTop;
+ nTop = nBottom;
+ nBottom = nTemp;
+ }
+ long nMinDistance = LONG_MAX;
+ SvLBoxEntry* pResult = 0;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pList->GetObject( nCur ));
+ if( pEntry != pCurEntry )
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA2(pEntry);
+ USHORT nY = pViewData->nY;
+ if( nY >= nTop && nY <= nBottom )
+ {
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ long nDistance = rRect.Top() - rRefRect.Top();
+ if( nDistance < 0 )
+ nDistance *= -1;
+ if( nDistance && nDistance < nMinDistance )
+ {
+ nMinDistance = nDistance;
+ pResult = pEntry;
+ }
+ }
+ }
+ }
+ return pResult;
+}
+
+SvLBoxEntry* ImpIcnCursor::SearchRow(USHORT nRow,USHORT nLeft,USHORT nRight,
+ USHORT, BOOL bRight, BOOL bSimple )
+{
+ DBG_ASSERT(pCurEntry,"SearchRow: No reference entry");
+ SvPtrarr* pList = &(pRows[ nRow ]);
+ USHORT nCount = pList->Count();
+ if( !nCount )
+ return 0;
+
+ const Rectangle& rRefRect = pView->GetBoundingRect(pCurEntry);
+
+ if( bSimple )
+ {
+ USHORT nListPos = pList->GetPos( pCurEntry );
+ DBG_ASSERT(nListPos!=0xffff,"Entry not in Row-List");
+ if( bRight )
+ {
+ while( nListPos < nCount-1 )
+ {
+ nListPos++;
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ if( rRect.Left() > rRefRect.Left() )
+ return pEntry;
+ }
+ return 0;
+ }
+ else
+ {
+ while( nListPos )
+ {
+ nListPos--;
+ if( nListPos < nCount )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pList->GetObject( nListPos );
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ if( rRect.Left() < rRefRect.Left() )
+ return pEntry;
+ }
+ }
+ return 0;
+ }
+
+ }
+ if( nRight < nLeft )
+ {
+ USHORT nTemp = nRight;
+ nRight = nLeft;
+ nLeft = nTemp;
+ }
+ long nMinDistance = LONG_MAX;
+ SvLBoxEntry* pResult = 0;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pList->GetObject( nCur ));
+ if( pEntry != pCurEntry )
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA2(pEntry);
+ USHORT nX = pViewData->nX;
+ if( nX >= nLeft && nX <= nRight )
+ {
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ long nDistance = rRect.Left() - rRefRect.Left();
+ if( nDistance < 0 )
+ nDistance *= -1;
+ if( nDistance && nDistance < nMinDistance )
+ {
+ nMinDistance = nDistance;
+ pResult = pEntry;
+ }
+ }
+ }
+ }
+ return pResult;
+}
+
+
+
+/*
+ Sucht ab dem uebergebenen Eintrag den naechsten rechts- bzw.
+ linksstehenden. Suchverfahren am Beispiel bRight = TRUE:
+
+ c
+ b c
+ a b c
+ S 1 1 1 ====> Suchrichtung
+ a b c
+ b c
+ c
+
+ S : Startposition
+ 1 : erstes Suchrechteck
+ a,b,c : 2., 3., 4. Suchrechteck
+*/
+
+SvLBoxEntry* ImpIcnCursor::GoLeftRight( SvLBoxEntry* pIcnEntry, BOOL bRight )
+{
+ SvLBoxEntry* pResult;
+ pCurEntry = pIcnEntry;
+ Create();
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA2(pIcnEntry);
+ USHORT nY = pViewData->nY;
+ USHORT nX = pViewData->nX;
+ DBG_ASSERT(nY< nRows,"GoLeftRight:Bad column");
+ DBG_ASSERT(nX< nCols,"GoLeftRight:Bad row");
+ // Nachbar auf gleicher Zeile ?
+ if( bRight )
+ pResult = SearchRow(
+ nY, nX, sal::static_int_cast< USHORT >(nCols-1), nX, TRUE, TRUE );
+ else
+ pResult = SearchRow( nY, nX ,0, nX, FALSE, TRUE );
+ if( pResult )
+ return pResult;
+
+ long nCurCol = nX;
+
+ long nColOffs, nLastCol;
+ if( bRight )
+ {
+ nColOffs = 1;
+ nLastCol = nCols;
+ }
+ else
+ {
+ nColOffs = -1;
+ nLastCol = -1; // 0-1
+ }
+
+ USHORT nRowMin = nY;
+ USHORT nRowMax = nY;
+ do
+ {
+ SvLBoxEntry* pEntry = SearchCol((USHORT)nCurCol,nRowMin,nRowMax,nY,TRUE, FALSE);
+ if( pEntry )
+ return pEntry;
+ if( nRowMin )
+ nRowMin--;
+ if( nRowMax < (nRows-1))
+ nRowMax++;
+ nCurCol += nColOffs;
+ } while( nCurCol != nLastCol );
+ return 0;
+}
+
+SvLBoxEntry* ImpIcnCursor::GoUpDown( SvLBoxEntry* pIcnEntry, BOOL bDown)
+{
+ SvLBoxEntry* pResult;
+ pCurEntry = pIcnEntry;
+ Create();
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA2(pIcnEntry);
+ USHORT nY = pViewData->nY;
+ USHORT nX = pViewData->nX;
+ DBG_ASSERT(nY<nRows,"GoUpDown:Bad column");
+ DBG_ASSERT(nX<nCols,"GoUpDown:Bad row");
+
+ // Nachbar in gleicher Spalte ?
+ if( bDown )
+ pResult = SearchCol(
+ nX, nY, sal::static_int_cast< USHORT >(nRows-1), nY, TRUE, TRUE );
+ else
+ pResult = SearchCol( nX, nY ,0, nY, FALSE, TRUE );
+ if( pResult )
+ return pResult;
+
+ long nCurRow = nY;
+
+ long nRowOffs, nLastRow;
+ if( bDown )
+ {
+ nRowOffs = 1;
+ nLastRow = nRows;
+ }
+ else
+ {
+ nRowOffs = -1;
+ nLastRow = -1; // 0-1
+ }
+
+ USHORT nColMin = nX;
+ USHORT nColMax = nX;
+ do
+ {
+ SvLBoxEntry* pEntry = SearchRow((USHORT)nCurRow,nColMin,nColMax,nX,TRUE, FALSE);
+ if( pEntry )
+ return pEntry;
+ if( nColMin )
+ nColMin--;
+ if( nColMax < (nCols-1))
+ nColMax++;
+ nCurRow += nRowOffs;
+ } while( nCurRow != nLastRow );
+ return 0;
+}
+
+void ImpIcnCursor::SetDeltas()
+{
+ const Size& rSize = pView->aVirtOutputSize;
+ if( pView->nFlags & F_GRIDMODE )
+ {
+ nGridDX = pView->nGridDX;
+ nGridDY = pView->nGridDY;
+ }
+ else
+ {
+ nGridDX = 20;
+ nGridDY = 20;
+ }
+ nCols = rSize.Width() / nGridDX;
+ if( !nCols )
+ nCols = 1;
+ nRows = rSize.Height() / nGridDY;
+ if( (nRows * nGridDY) < rSize.Height() )
+ nRows++;
+ if( !nRows )
+ nRows = 1;
+
+ nDeltaWidth = (short)(rSize.Width() / nCols);
+ nDeltaHeight = (short)(rSize.Height() / nRows);
+ if( !nDeltaHeight )
+ {
+ nDeltaHeight = 1;
+ DBG_WARNING("SetDeltas:Bad height");
+ }
+ if( !nDeltaWidth )
+ {
+ nDeltaWidth = 1;
+ DBG_WARNING("SetDeltas:Bad width");
+ }
+}
+
+
+void ImpIcnCursor::ExpandGrid()
+{
+ if( pGridMap )
+ {
+ long nNewGridRows = nGridRows + 20;
+ unsigned char* pTempMap = new unsigned char[ nNewGridRows * nGridCols ];
+ memcpy( pTempMap, pGridMap, nGridRows * nGridCols );
+ delete pGridMap;
+ pGridMap = pTempMap;
+ nGridRows = nNewGridRows;
+ }
+}
+
+BOOL ImpIcnCursor::FindEmptyGridRect( Rectangle& rRect )
+{
+ CreateGridMap();
+ USHORT nCount = (USHORT)(nGridCols * nGridRows);
+ if( !nCount )
+ return FALSE;
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ if( !pGridMap[ nCur ] )
+ {
+ USHORT nCol = (USHORT)(nCur % nGridCols);
+ USHORT nRow = (USHORT)(nCur / nGridCols);
+ rRect.Top() = nRow * nGridDY + TBOFFS_WINBORDER;
+ rRect.Bottom() = rRect.Top() + nGridDY;
+ rRect.Left() = nCol * nGridDX+ LROFFS_WINBORDER;
+ rRect.Right() = rRect.Left() + nGridDX;
+ SetGridUsed( nCol, nRow, TRUE );
+
+ //XXX
+ //if( nRow + 5 > nGridRows )
+ // ExpandGrid();
+ DBG_ASSERT(pGridMap[nCur],"SetGridUsed failed");
+ return TRUE;
+ }
+ }
+ // Gridmap ist voll: Um eine Zeile erweitern
+ rRect.Top() = nGridRows * nGridDY + TBOFFS_WINBORDER;
+ rRect.Bottom() = rRect.Top() + nGridDY;
+ rRect.Left() = LROFFS_WINBORDER;
+ rRect.Right() = rRect.Left() + nGridDX;
+ return FALSE;
+ //XXX
+ //ExpandGrid();
+ //return TRUE;
+}
+
+void ImpIcnCursor::CreateGridAjustData( SvPtrarr& rLists, SvLBoxEntry* pRefEntry)
+{
+ if( !pRefEntry )
+ {
+ USHORT nAdjustRows = (USHORT)(pView->aVirtOutputSize.Height() / pView->nGridDY);
+ nAdjustRows++; // wg. Abrundung!
+
+ if( !nAdjustRows )
+ return;
+ for( USHORT nCurList = 0; nCurList < nAdjustRows; nCurList++ )
+ {
+ SvPtrarr* pRow = new SvPtrarr;
+ rLists.Insert( (void*)pRow, nCurList );
+ }
+ SvLBoxEntry* pEntry = pView->pModel->FirstChild( pView->pCurParent );
+ while( pEntry )
+ {
+ const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
+ USHORT nIns = GetSortListPos((SvPtrarr*)rLists[nY],rRect.Left(),FALSE);
+ ((SvPtrarr*)rLists[ nY ])->Insert( pEntry, nIns );
+ pEntry = pView->pModel->NextSibling( pEntry );
+ }
+ }
+ else
+ {
+ // Aufbau eines hor. "Schlauchs" auf der RefEntry-Zeile
+
+ // UEBERLEGEN: BoundingRect nehmen wg. Ueberlappungen???
+
+ Rectangle rRefRect( pView->CalcBmpRect( pRefEntry ) );
+ //const Rectangle& rRefRect = pView->GetBoundingRect( pRefEntry );
+ short nRefRow = (short)( ((rRefRect.Top()+rRefRect.Bottom())/2) / pView->nGridDY );
+ SvPtrarr* pRow = new SvPtrarr;
+ rLists.Insert( (void*)pRow, 0 );
+ SvLBoxEntry* pEntry = pView->pModel->FirstChild( pView->pCurParent );
+ while( pEntry )
+ {
+ Rectangle rRect( pView->CalcBmpRect(pEntry) );
+ //const Rectangle& rRect = pView->GetBoundingRect( pEntry );
+ short nY = (short)( ((rRect.Top()+rRect.Bottom())/2) / pView->nGridDY );
+ if( nY == nRefRow )
+ {
+ USHORT nIns = GetSortListPos( pRow, rRect.Left(), FALSE );
+ pRow->Insert( pEntry, nIns );
+ }
+ pEntry = pView->pModel->NextSibling( pEntry );
+ }
+ }
+}
+
+//static
+void ImpIcnCursor::DestroyGridAdjustData( SvPtrarr& rLists )
+{
+ USHORT nCount = rLists.Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvPtrarr* pArr = (SvPtrarr*)rLists[ nCur ];
+ delete pArr;
+ }
+ rLists.Remove( 0, rLists.Count() );
+}
+
+void SvImpIconView::SetGrid( long nDX, long nDY )
+{
+ nGridDX = nDX;
+ nGridDY = nDY;
+ nFlags |= F_GRIDMODE;
+}
+
+Rectangle SvImpIconView::CalcMaxTextRect( const SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const
+{
+ Rectangle aRect = pViewData->aGridRect;
+ long nBmpHeight = ((SvLBoxEntry*)pEntry)->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)->GetSize(pView,(SvLBoxEntry*)pEntry).Height();
+ aRect.Top() += nBmpHeight;
+ aRect.Top() += ICONVIEW_OFFS_BMP_STRING;
+ if( aRect.Top() > aRect.Bottom())
+ aRect.Top() = aRect.Bottom();
+ aRect.Left() += LROFFS_BOUND;
+ aRect.Left()++;
+ aRect.Right() -= LROFFS_BOUND;
+ aRect.Right()--;
+ if( aRect.Left() > aRect.Right())
+ aRect.Left() = aRect.Right();
+ if( GetTextMode( pEntry, pViewData ) == ShowTextFull )
+ aRect.Bottom() = LONG_MAX;
+ return aRect;
+}
+
+void SvImpIconView::Center( SvLBoxEntry* pEntry,
+ SvIcnVwDataEntry* pViewData ) const
+{
+ SvLBoxString* pStringItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ const String& rEntryText = pStringItem->GetText();
+
+ Rectangle aTextRect = CalcMaxTextRect(pEntry,pViewData);
+ aTextRect = GetTextRect( pView, aTextRect, rEntryText, DRAWTEXT_FLAGS );
+ pViewData->aTextSize = aTextRect.GetSize();
+
+ pViewData->aRect = pViewData->aGridRect;
+ Size aSize( CalcBoundingSize( pEntry, pViewData ) );
+ long nBorder = pViewData->aGridRect.GetWidth() - aSize.Width();
+ pViewData->aRect.Left() += nBorder / 2;
+ pViewData->aRect.Right() -= nBorder / 2;
+ pViewData->aRect.Bottom() = pViewData->aRect.Top() + aSize.Height();
+}
+
+
+// Die Deltas entsprechen Offsets, um die die View auf dem Doc verschoben wird
+// links, hoch: Offsets < 0
+// rechts, runter: Offsets > 0
+void SvImpIconView::Scroll( long nDeltaX, long nDeltaY, BOOL bScrollBar )
+{
+ const MapMode& rMapMode = pView->GetMapMode();
+ Point aOrigin( rMapMode.GetOrigin() );
+ // in Dokumentkoordinate umwandeln
+ aOrigin *= -1;
+ aOrigin.Y() += nDeltaY;
+ aOrigin.X() += nDeltaX;
+ Rectangle aRect( aOrigin, aOutputSize );
+ MakeVisible( aRect, bScrollBar );
+}
+
+
+const Size& SvImpIconView::GetItemSize( SvIconView* pIconView,
+ SvLBoxEntry* pEntry, SvLBoxItem* pItem, const SvIcnVwDataEntry* pViewData) const
+{
+ if( (nFlags & F_GRIDMODE) && pItem->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(pEntry);
+ return pViewData->aTextSize;
+ }
+ else
+ return pItem->GetSize( pIconView, pEntry );
+}
+
+Rectangle SvImpIconView::CalcFocusRect( SvLBoxEntry* pEntry )
+{
+#if !defined(OS2)
+ SvLBoxString* pStringItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ DBG_ASSERT(pStringItem,"Text not set");
+ return CalcTextRect( pEntry, pStringItem );
+#else
+ return CalcBmpRect( pEntry );
+#endif
+}
+
+
+void SvImpIconView::SelectRect( const Rectangle& rRect, BOOL bAdd,
+ SvPtrarr* pOtherRects, short nBorderOffs )
+{
+ if( !pZOrderList || !pZOrderList->Count() )
+ return;
+
+ CheckBoundingRects();
+ pView->Update();
+ USHORT nCount = pZOrderList->Count();
+
+ Rectangle aRect( rRect );
+ aRect.Justify();
+ if( nBorderOffs )
+ {
+ aRect.Left() -= nBorderOffs;
+ aRect.Right() += nBorderOffs;
+ aRect.Top() -= nBorderOffs;
+ aRect.Bottom() += nBorderOffs;
+ }
+ BOOL bCalcOverlap = (bAdd && pOtherRects && pOtherRects->Count()) ? TRUE : FALSE;
+
+ for( USHORT nPos = 0; nPos < nCount; nPos++ )
+ {
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)(pZOrderList->GetObject(nPos ));
+
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ DBG_ASSERT(pViewData,"Entry not in model");
+ if( !IsBoundingRectValid( pViewData->aRect ))
+ FindBoundingRect( pEntry, pViewData );
+ const Rectangle& rBoundRect = pViewData->aRect;
+ BOOL bSelected = pViewData->IsSelected();
+
+ BOOL bOverlaps;
+ if( bCalcOverlap )
+ bOverlaps = IsOver( pOtherRects, rBoundRect );
+ else
+ bOverlaps = FALSE;
+ BOOL bOver = aRect.IsOver( rBoundRect );
+
+ if( bOver && !bOverlaps )
+ {
+ // Ist im neuen Selektionsrechteck und in keinem alten
+ // => selektieren
+ if( !bSelected )
+ pView->Select( pEntry, TRUE );
+ }
+ else if( !bAdd )
+ {
+ // ist ausserhalb des Selektionsrechtecks
+ // => Selektion entfernen
+ if( bSelected )
+ pView->Select( pEntry, FALSE );
+ }
+ else if( bAdd && bOverlaps )
+ {
+ // Der Eintrag befindet sich in einem alten (=>Aufspannen
+ // mehrerer Rechtecke mit Ctrl!) Selektionsrechteck
+
+ // Hier ist noch ein Bug! Der Selektionsstatus eines Eintrags
+ // in einem vorherigen Rechteck, muss restauriert werden, wenn
+ // er vom aktuellen Selektionsrechteck beruehrt wurde, jetzt aber
+ // nicht mehr in ihm liegt. Ich gehe hier der Einfachheit halber
+ // pauschal davon aus, dass die Eintraege in den alten Rechtecken
+ // alle selektiert sind. Ebenso ist es falsch, die Schnittmenge
+ // nur zu deselektieren.
+ // Loesungsmoeglichkeit: Snapshot der Selektion vor dem Auf-
+ // spannen des Rechtecks merken
+ if( rBoundRect.IsOver( rRect))
+ {
+ // Schnittmenge zwischen alten Rects & aktuellem Rect desel.
+ if( bSelected )
+ pView->Select( pEntry, FALSE );
+ }
+ else
+ {
+ // Eintrag eines alten Rects selektieren
+ if( !bSelected )
+ pView->Select( pEntry, TRUE );
+ }
+ }
+ else if( !bOver && bSelected )
+ {
+ // Der Eintrag liegt voellig ausserhalb und wird deshalb desel.
+ pView->Select( pEntry, FALSE );
+ }
+ }
+ pView->Update();
+}
+
+BOOL SvImpIconView::IsOver( SvPtrarr* pRectList, const Rectangle& rBoundRect ) const
+{
+ USHORT nCount = pRectList->Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ Rectangle* pRect = (Rectangle*)pRectList->GetObject( nCur );
+ if( rBoundRect.IsOver( *pRect ))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SvImpIconView::AddSelectedRect( const Rectangle& rRect, short nBorderOffs )
+{
+ Rectangle* pRect = new Rectangle( rRect );
+ pRect->Justify();
+ if( nBorderOffs )
+ {
+ pRect->Left() -= nBorderOffs;
+ pRect->Right() += nBorderOffs;
+ pRect->Top() -= nBorderOffs;
+ pRect->Bottom() += nBorderOffs;
+ }
+ aSelectedRectList.Insert( (void*)pRect, aSelectedRectList.Count() );
+}
+
+void SvImpIconView::ClearSelectedRectList()
+{
+ USHORT nCount = aSelectedRectList.Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ Rectangle* pRect = (Rectangle*)aSelectedRectList.GetObject( nCur );
+ delete pRect;
+ }
+ aSelectedRectList.Remove( 0, aSelectedRectList.Count() );
+}
+
+
+void SvImpIconView::DrawSelectionRect( const Rectangle& rRect )
+{
+ pView->HideTracking();
+ nFlags |= F_SELRECT_VISIBLE;
+ pView->ShowTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ aCurSelectionRect = rRect;
+}
+
+void SvImpIconView::HideSelectionRect()
+{
+ if( nFlags & F_SELRECT_VISIBLE )
+ {
+ pView->HideTracking();
+ nFlags &= ~F_SELRECT_VISIBLE;
+ }
+}
+
+void SvImpIconView::ImpDrawXORRect( const Rectangle& rRect )
+{
+ RasterOp eOldOp = pView->GetRasterOp();
+ pView->SetRasterOp( ROP_XOR );
+ Color aOldColor = pView->GetFillColor();
+ pView->SetFillColor();
+ pView->DrawRect( rRect );
+ pView->SetFillColor( aOldColor );
+ pView->SetRasterOp( eOldOp );
+}
+
+void SvImpIconView::CalcScrollOffsets( const Point& rPosPixel,
+ long& rX, long& rY, BOOL bInDragDrop, USHORT nBorderWidth)
+{
+ // Scrolling der View, falls sich der Mauszeiger im Grenzbereich des
+ // Fensters befindet
+ long nPixelToScrollX = 0;
+ long nPixelToScrollY = 0;
+ Size aWndSize = aOutputSize;
+
+ nBorderWidth = (USHORT)(Min( (long)(aWndSize.Height()-1), (long)nBorderWidth ));
+ nBorderWidth = (USHORT)(Min( (long)(aWndSize.Width()-1), (long)nBorderWidth ));
+
+ if ( rPosPixel.X() < nBorderWidth )
+ {
+ if( bInDragDrop )
+ nPixelToScrollX = -DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollX = rPosPixel.X()- nBorderWidth;
+ }
+ else if ( rPosPixel.X() > aWndSize.Width() - nBorderWidth )
+ {
+ if( bInDragDrop )
+ nPixelToScrollX = DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollX = rPosPixel.X() - (aWndSize.Width() - nBorderWidth);
+ }
+ if ( rPosPixel.Y() < nBorderWidth )
+ {
+ if( bInDragDrop )
+ nPixelToScrollY = -DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollY = rPosPixel.Y() - nBorderWidth;
+ }
+ else if ( rPosPixel.Y() > aWndSize.Height() - nBorderWidth )
+ {
+ if( bInDragDrop )
+ nPixelToScrollY = DD_SCROLL_PIXEL;
+ else
+ nPixelToScrollY = rPosPixel.Y() - (aWndSize.Height() - nBorderWidth);
+ }
+
+ rX = nPixelToScrollX;
+ rY = nPixelToScrollY;
+}
+
+IMPL_LINK(SvImpIconView, MouseMoveTimeoutHdl, Timer*, pTimer )
+{
+ pTimer->Start();
+ MouseMove( aMouseMoveEvent );
+ return 0;
+}
+
+void SvImpIconView::EndTracking()
+{
+ pView->ReleaseMouse();
+ if( nFlags & F_RUBBERING )
+ {
+ aMouseMoveTimer.Stop();
+ nFlags &= ~(F_RUBBERING | F_ADD_MODE);
+ }
+}
+
+BOOL SvImpIconView::IsTextHit( SvLBoxEntry* pEntry, const Point& rDocPos )
+{
+ SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if( pItem )
+ {
+ Rectangle aRect( CalcTextRect( pEntry, pItem ));
+ if( aRect.IsInside( rDocPos ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+IMPL_LINK(SvImpIconView, EditTimeoutHdl, Timer*, EMPTYARG )
+{
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if( pView->IsInplaceEditingEnabled() && pEntry &&
+ pView->IsSelected( pEntry ))
+ {
+ pView->EditEntry( pEntry );
+ }
+ return 0;
+}
+
+
+//
+// Funktionen zum Ausrichten der Eintraege am Grid
+//
+
+// pStart == 0: Alle Eintraege werden ausgerichtet
+// sonst: Alle Eintraege der Zeile ab einschliesslich pStart werden ausgerichtet
+void SvImpIconView::AdjustAtGrid( SvLBoxEntry* pStart )
+{
+ SvPtrarr aLists;
+ pImpCursor->CreateGridAjustData( aLists, pStart );
+ USHORT nCount = aLists.Count();
+ for( USHORT nCur = 0; nCur < nCount; nCur++ )
+ {
+ AdjustAtGrid( *(SvPtrarr*)aLists[ nCur ], pStart );
+ }
+ ImpIcnCursor::DestroyGridAdjustData( aLists );
+ CheckScrollBars();
+}
+
+// Richtet eine Zeile aus, erweitert ggf. die Breite; Bricht die Zeile nicht um
+void SvImpIconView::AdjustAtGrid( const SvPtrarr& rRow, SvLBoxEntry* pStart )
+{
+ if( !rRow.Count() )
+ return;
+
+ BOOL bGo;
+ if( !pStart )
+ bGo = TRUE;
+ else
+ bGo = FALSE;
+
+ long nCurRight = 0;
+ for( USHORT nCur = 0; nCur < rRow.Count(); nCur++ )
+ {
+ SvLBoxEntry* pCur = (SvLBoxEntry*)rRow[ nCur ];
+ if( !bGo && pCur == pStart )
+ bGo = TRUE;
+
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur);
+ // Massgebend (fuer das menschliche Auge) ist die Bitmap, da sonst
+ // durch lange Texte der Eintrag stark springen kann
+ const Rectangle& rBoundRect = GetBoundingRect( pCur, pViewData );
+ Rectangle aCenterRect( CalcBmpRect( pCur, 0, pViewData ));
+ if( bGo && !pViewData->IsEntryPosLocked() )
+ {
+ long nWidth = aCenterRect.GetSize().Width();
+ Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) );
+ while( aNewPos.X() < nCurRight )
+ aNewPos.X() += nGridDX;
+ if( aNewPos != rBoundRect.TopLeft() )
+ SetEntryPosition( pCur, aNewPos );
+ nCurRight = aNewPos.X() + nWidth;
+ }
+ else
+ {
+ nCurRight = rBoundRect.Right();
+ }
+ }
+}
+
+// Richtet Rect am Grid aus, garantiert jedoch nicht, dass die
+// neue Pos. frei ist. Die Pos. kann fuer SetEntryPos verwendet werden.
+// Das CenterRect beschreibt den Teil des BoundRects, der fuer
+// die Berechnung des Ziel-Rechtecks verwendet wird.
+Point SvImpIconView::AdjustAtGrid( const Rectangle& rCenterRect,
+ const Rectangle& rBoundRect ) const
+{
+ Point aPos( rCenterRect.TopLeft() );
+ Size aSize( rCenterRect.GetSize() );
+
+ aPos.X() -= LROFFS_WINBORDER;
+ aPos.Y() -= TBOFFS_WINBORDER;
+
+ // align (ref ist mitte des rects)
+ short nGridX = (short)((aPos.X()+(aSize.Width()/2)) / nGridDX);
+ short nGridY = (short)((aPos.Y()+(aSize.Height()/2)) / nGridDY);
+ aPos.X() = nGridX * nGridDX;
+ aPos.Y() = nGridY * nGridDY;
+ // hor. center
+ aPos.X() += (nGridDX - rBoundRect.GetSize().Width() ) / 2;
+
+ aPos.X() += LROFFS_WINBORDER;
+ aPos.Y() += TBOFFS_WINBORDER;
+
+ return aPos;
+}
+
+
+void SvImpIconView::SetTextMode( SvIconViewTextMode eMode, SvLBoxEntry* pEntry )
+{
+ if( !pEntry )
+ {
+ if( eTextMode != eMode )
+ {
+ if( eTextMode == ShowTextDontKnow )
+ eTextMode = ShowTextShort;
+ eTextMode = eMode;
+ pView->Arrange();
+ }
+ }
+ else
+ {
+ SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pEntry);
+ if( pViewData->eTextMode != eMode )
+ {
+ pViewData->eTextMode = eMode;
+ pModel->InvalidateEntry( pEntry );
+ AdjustVirtSize( pViewData->aRect );
+ }
+ }
+}
+
+SvIconViewTextMode SvImpIconView::GetTextMode( const SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const
+{
+ if( !pEntry )
+ return eTextMode;
+ else
+ {
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(((SvLBoxEntry*)pEntry));
+ return pViewData->GetTextMode();
+ }
+}
+
+SvIconViewTextMode SvImpIconView::GetEntryTextModeSmart( const SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const
+{
+ DBG_ASSERT(pEntry,"GetEntryTextModeSmart: Entry not set");
+ if( !pViewData )
+ pViewData = ICNVIEWDATA(((SvLBoxEntry*)pEntry));
+ SvIconViewTextMode eMode = pViewData->GetTextMode();
+ if( eMode == ShowTextDontKnow )
+ return eTextMode;
+ return eMode;
+}
+
+void SvImpIconView::ShowFocusRect( const SvLBoxEntry* pEntry )
+{
+ if( !pEntry )
+ pView->HideFocus();
+ else
+ {
+ Rectangle aRect ( CalcFocusRect( (SvLBoxEntry*)pEntry ) );
+ pView->ShowFocus( aRect );
+ }
+}
+
+IMPL_LINK(SvImpIconView, UserEventHdl, void*, EMPTYARG )
+{
+ nCurUserEvent = 0;
+ AdjustScrollBars();
+ Rectangle aRect;
+ if( GetResizeRect(aRect) )
+ PaintResizeRect( aRect );
+ return 0;
+}
+
+void SvImpIconView::CancelUserEvent()
+{
+ if( nCurUserEvent )
+ {
+ Application::RemoveUserEvent( nCurUserEvent );
+ nCurUserEvent = 0;
+ }
+}
+
+
diff --git a/svtools/source/contnr/svlbitm.cxx b/svtools/source/contnr/svlbitm.cxx
new file mode 100644
index 000000000000..d260f984c2b0
--- /dev/null
+++ b/svtools/source/contnr/svlbitm.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_svtools.hxx"
+
+
+#include <svtools/svlbox.hxx>
+#include <svtools/svlbitm.hxx>
+#include <vcl/svapp.hxx>
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/decoview.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/salnativewidgets.hxx>
+
+#define TABOFFS_NOT_VALID -2000000
+
+struct SvLBoxButtonData_Impl
+{
+ SvLBoxEntry* pEntry;
+ BOOL bDefaultImages;
+ BOOL bShowRadioButton;
+
+ SvLBoxButtonData_Impl() : pEntry( NULL ), bDefaultImages( FALSE ), bShowRadioButton( FALSE ) {}
+};
+
+
+DBG_NAME(SvLBoxButtonData)
+
+void SvLBoxButtonData::InitData( BOOL bImagesFromDefault, bool _bRadioBtn, const Control* pCtrl )
+{
+ pImpl = new SvLBoxButtonData_Impl;
+
+ bDataOk = FALSE;
+ eState = SV_BUTTON_UNCHECKED;
+ pImpl->bDefaultImages = bImagesFromDefault;
+ pImpl->bShowRadioButton = ( _bRadioBtn != false );
+
+ if ( bImagesFromDefault )
+ SetDefaultImages( pCtrl );
+}
+
+SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings )
+{
+ DBG_CTOR(SvLBoxButtonData,0);
+
+ InitData( TRUE, false, pControlForSettings );
+}
+
+SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings, bool _bRadioBtn )
+{
+ DBG_CTOR(SvLBoxButtonData,0);
+
+ InitData( TRUE, _bRadioBtn, pControlForSettings );
+}
+
+SvLBoxButtonData::SvLBoxButtonData()
+{
+ DBG_CTOR(SvLBoxButtonData,0);
+
+ InitData( FALSE, false );
+}
+
+SvLBoxButtonData::~SvLBoxButtonData()
+{
+ DBG_DTOR(SvLBoxButtonData,0);
+
+ delete pImpl;
+#ifdef DBG_UTIL
+ pImpl = NULL;
+#endif
+}
+
+void SvLBoxButtonData::CallLink()
+{
+ DBG_CHKTHIS(SvLBoxButtonData,0);
+ aLink.Call( this );
+}
+
+USHORT SvLBoxButtonData::GetIndex( USHORT nItemState )
+{
+ DBG_CHKTHIS(SvLBoxButtonData,0);
+ nItemState &= 0x000F;
+ USHORT nIdx;
+ switch( nItemState )
+ {
+ case SV_ITEMSTATE_UNCHECKED:
+ nIdx = SV_BMP_UNCHECKED; break;
+ case SV_ITEMSTATE_CHECKED:
+ nIdx = SV_BMP_CHECKED; break;
+ case SV_ITEMSTATE_TRISTATE:
+ nIdx = SV_BMP_TRISTATE; break;
+ case SV_ITEMSTATE_UNCHECKED | SV_ITEMSTATE_HILIGHTED:
+ nIdx = SV_BMP_HIUNCHECKED; break;
+ case SV_ITEMSTATE_CHECKED | SV_ITEMSTATE_HILIGHTED:
+ nIdx = SV_BMP_HICHECKED; break;
+ case SV_ITEMSTATE_TRISTATE | SV_ITEMSTATE_HILIGHTED:
+ nIdx = SV_BMP_HITRISTATE; break;
+ default:
+ nIdx = SV_BMP_UNCHECKED;
+ }
+ return nIdx;
+}
+
+void SvLBoxButtonData::SetWidthAndHeight()
+{
+ DBG_CHKTHIS(SvLBoxButtonData,0);
+ Size aSize = aBmps[0].GetSizePixel();
+ nWidth = aSize.Width();
+ nHeight = aSize.Height();
+ bDataOk = TRUE;
+}
+
+
+void SvLBoxButtonData::StoreButtonState( SvLBoxEntry* pActEntry, USHORT nItemFlags )
+{
+ DBG_CHKTHIS(SvLBoxButtonData,0);
+ pImpl->pEntry = pActEntry;
+ eState = ConvertToButtonState( nItemFlags );
+}
+
+SvButtonState SvLBoxButtonData::ConvertToButtonState( USHORT nItemFlags ) const
+{
+ DBG_CHKTHIS(SvLBoxButtonData,0);
+ nItemFlags &= (SV_ITEMSTATE_UNCHECKED |
+ SV_ITEMSTATE_CHECKED |
+ SV_ITEMSTATE_TRISTATE);
+ switch( nItemFlags )
+ {
+ case SV_ITEMSTATE_UNCHECKED:
+ return SV_BUTTON_UNCHECKED;
+
+ case SV_ITEMSTATE_CHECKED:
+ return SV_BUTTON_CHECKED;
+
+ case SV_ITEMSTATE_TRISTATE:
+ return SV_BUTTON_TRISTATE;
+ default:
+ return SV_BUTTON_UNCHECKED;
+ }
+}
+
+SvLBoxEntry* SvLBoxButtonData::GetActEntry() const
+{
+ DBG_ASSERT( pImpl, "-SvLBoxButtonData::GetActEntry(): don't use me that way!" );
+ return pImpl->pEntry;
+}
+
+void SvLBoxButtonData::SetDefaultImages( const Control* pCtrl )
+{
+ const AllSettings& rSettings = pCtrl? pCtrl->GetSettings() : Application::GetSettings();
+
+ if ( pImpl->bShowRadioButton )
+ {
+ aBmps[ SV_BMP_UNCHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DEFAULT );
+ aBmps[ SV_BMP_CHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_CHECKED );
+ aBmps[ SV_BMP_HICHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED );
+ aBmps[ SV_BMP_HIUNCHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DEFAULT | BUTTON_DRAW_PRESSED );
+ aBmps[ SV_BMP_TRISTATE ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DONTKNOW );
+ aBmps[ SV_BMP_HITRISTATE ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DONTKNOW | BUTTON_DRAW_PRESSED );
+ }
+ else
+ {
+ aBmps[ SV_BMP_UNCHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT );
+ aBmps[ SV_BMP_CHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED );
+ aBmps[ SV_BMP_HICHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED );
+ aBmps[ SV_BMP_HIUNCHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT | BUTTON_DRAW_PRESSED );
+ aBmps[ SV_BMP_TRISTATE ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DONTKNOW );
+ aBmps[ SV_BMP_HITRISTATE ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DONTKNOW | BUTTON_DRAW_PRESSED );
+ }
+}
+
+BOOL SvLBoxButtonData::HasDefaultImages( void ) const
+{
+ return pImpl->bDefaultImages;
+}
+
+BOOL SvLBoxButtonData::IsRadio() {
+ return pImpl->bShowRadioButton;
+}
+
+// ***************************************************************
+// class SvLBoxString
+// ***************************************************************
+
+DBG_NAME(SvLBoxString);
+
+SvLBoxString::SvLBoxString( SvLBoxEntry* pEntry,USHORT nFlags,const XubString& rStr) :
+ SvLBoxItem( pEntry, nFlags )
+{
+ DBG_CTOR(SvLBoxString,0);
+ SetText( pEntry, rStr );
+}
+
+SvLBoxString::SvLBoxString() : SvLBoxItem()
+{
+ DBG_CTOR(SvLBoxString,0);
+}
+
+SvLBoxString::~SvLBoxString()
+{
+ DBG_DTOR(SvLBoxString,0);
+}
+
+USHORT SvLBoxString::IsA()
+{
+ DBG_CHKTHIS(SvLBoxString,0);
+ return SV_ITEM_ID_LBOXSTRING;
+}
+
+void SvLBoxString::Paint( const Point& rPos, SvLBox& rDev, USHORT /* nFlags */,
+ SvLBoxEntry* _pEntry)
+{
+ DBG_CHKTHIS(SvLBoxString,0);
+ if ( _pEntry )
+ {
+ USHORT nStyle = rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE;
+ if ( rDev.IsEntryMnemonicsEnabled() )
+ nStyle |= TEXT_DRAW_MNEMONIC;
+ rDev.DrawText( Rectangle(rPos,GetSize(&rDev,_pEntry)),aStr,nStyle);
+ }
+ else
+ rDev.DrawText( rPos, aStr);
+
+}
+
+SvLBoxItem* SvLBoxString::Create() const
+{
+ DBG_CHKTHIS(SvLBoxString,0);
+ return new SvLBoxString;
+}
+
+void SvLBoxString::Clone( SvLBoxItem* pSource )
+{
+ DBG_CHKTHIS(SvLBoxString,0);
+ aStr = ((SvLBoxString*)pSource)->aStr;
+}
+
+void SvLBoxString::SetText( SvLBoxEntry*, const XubString& rStr )
+{
+ DBG_CHKTHIS(SvLBoxString,0);
+ aStr = rStr;
+}
+
+void SvLBoxString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
+ SvViewDataItem* pViewData)
+{
+ DBG_CHKTHIS(SvLBoxString,0);
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+ pViewData->aSize = Size(pView->GetTextWidth( aStr ), pView->GetTextHeight());
+}
+
+// ***************************************************************
+// class SvLBoxBmp
+// ***************************************************************
+
+DBG_NAME(SvLBoxBmp);
+
+SvLBoxBmp::SvLBoxBmp( SvLBoxEntry* pEntry, USHORT nFlags, Image aBitmap ) :
+ SvLBoxItem( pEntry, nFlags )
+{
+ DBG_CTOR(SvLBoxBmp,0);
+ SetBitmap( pEntry, aBitmap);
+}
+
+SvLBoxBmp::SvLBoxBmp() : SvLBoxItem()
+{
+ DBG_CTOR(SvLBoxBmp,0);
+}
+
+SvLBoxBmp::~SvLBoxBmp()
+{
+ DBG_DTOR(SvLBoxBmp,0);
+}
+
+USHORT SvLBoxBmp::IsA()
+{
+ DBG_CHKTHIS(SvLBoxBmp,0);
+ return SV_ITEM_ID_LBOXBMP;
+}
+
+void SvLBoxBmp::SetBitmap( SvLBoxEntry*, Image aBitmap)
+{
+ DBG_CHKTHIS(SvLBoxBmp,0);
+ aBmp = aBitmap;
+}
+
+void SvLBoxBmp::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
+ SvViewDataItem* pViewData)
+{
+ DBG_CHKTHIS(SvLBoxBmp,0);
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+ pViewData->aSize = aBmp.GetSizePixel();
+}
+
+void SvLBoxBmp::Paint( const Point& rPos, SvLBox& rDev, USHORT /* nFlags */,
+ SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBoxBmp,0);
+ USHORT nStyle = rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE;
+ rDev.DrawImage( rPos, aBmp ,nStyle);
+}
+
+SvLBoxItem* SvLBoxBmp::Create() const
+{
+ DBG_CHKTHIS(SvLBoxBmp,0);
+ return new SvLBoxBmp;
+}
+
+void SvLBoxBmp::Clone( SvLBoxItem* pSource )
+{
+ DBG_CHKTHIS(SvLBoxBmp,0);
+ aBmp = ((SvLBoxBmp*)pSource)->aBmp;
+}
+
+// ***************************************************************
+// class SvLBoxButton
+// ***************************************************************
+
+DBG_NAME(SvLBoxButton);
+
+SvLBoxButton::SvLBoxButton( SvLBoxEntry* pEntry, SvLBoxButtonKind eTheKind,
+ USHORT nFlags, SvLBoxButtonData* pBData )
+ : SvLBoxItem( pEntry, nFlags )
+{
+ DBG_CTOR(SvLBoxButton,0);
+ eKind = eTheKind;
+ nBaseOffs = 0;
+ nItemFlags = 0;
+ SetStateUnchecked();
+ pData = pBData;
+}
+
+SvLBoxButton::SvLBoxButton() : SvLBoxItem()
+{
+ DBG_CTOR(SvLBoxButton,0);
+ eKind = SvLBoxButtonKind_enabledCheckbox;
+ nItemFlags = 0;
+ SetStateUnchecked();
+}
+
+SvLBoxButton::~SvLBoxButton()
+{
+ DBG_DTOR(SvLBoxButton,0);
+}
+
+USHORT SvLBoxButton::IsA()
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ return SV_ITEM_ID_LBOXBUTTON;
+}
+
+void SvLBoxButton::Check(SvLBox*, SvLBoxEntry*, BOOL bOn)
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ if ( bOn != IsStateChecked() )
+ {
+ if ( bOn )
+ SetStateChecked();
+ else
+ SetStateUnchecked();
+ }
+}
+
+BOOL SvLBoxButton::ClickHdl( SvLBox*, SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ if ( CheckModification() )
+ {
+ if ( IsStateChecked() )
+ SetStateUnchecked();
+ else
+ SetStateChecked();
+ pData->StoreButtonState( pEntry, nItemFlags );
+ pData->CallLink();
+ }
+ return FALSE;
+}
+
+void SvLBoxButton::Paint( const Point& rPos, SvLBox& rDev, USHORT /* nFlags */,
+ SvLBoxEntry* /*pEntry*/ )
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ USHORT nIndex = eKind == SvLBoxButtonKind_staticImage
+ ? SV_BMP_STATICIMAGE : pData->GetIndex( nItemFlags );
+ USHORT nStyle = eKind != SvLBoxButtonKind_disabledCheckbox &&
+ rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE;
+
+///
+//Native drawing
+///
+ BOOL bNativeOK = FALSE;
+ ControlType eCtrlType = (pData->IsRadio())? CTRL_RADIOBUTTON : CTRL_CHECKBOX;
+ if ( nIndex != SV_BMP_STATICIMAGE && rDev.IsNativeControlSupported( eCtrlType, PART_ENTIRE_CONTROL) )
+ {
+ Size aSize(pData->Width(), pData->Height());
+ ImplAdjustBoxSize( aSize, eCtrlType, &rDev );
+ ImplControlValue aControlValue;
+ Rectangle aCtrlRegion( rPos, aSize );
+ ControlState nState = 0;
+
+ //states CTRL_STATE_DEFAULT, CTRL_STATE_PRESSED and CTRL_STATE_ROLLOVER are not implemented
+ if ( IsStateHilighted() ) nState |= CTRL_STATE_FOCUSED;
+ if ( nStyle != IMAGE_DRAW_DISABLE ) nState |= CTRL_STATE_ENABLED;
+
+ if ( IsStateChecked() )
+ aControlValue.setTristateVal( BUTTONVALUE_ON );
+ else if ( IsStateUnchecked() )
+ aControlValue.setTristateVal( BUTTONVALUE_OFF );
+ else if ( IsStateTristate() )
+ aControlValue.setTristateVal( BUTTONVALUE_MIXED );
+
+ bNativeOK = rDev.DrawNativeControl( eCtrlType, PART_ENTIRE_CONTROL,
+ aCtrlRegion, nState, aControlValue, rtl::OUString() );
+ }
+
+ if( !bNativeOK)
+ rDev.DrawImage( rPos, pData->aBmps[nIndex + nBaseOffs] ,nStyle);
+}
+
+SvLBoxItem* SvLBoxButton::Create() const
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ return new SvLBoxButton;
+}
+
+void SvLBoxButton::Clone( SvLBoxItem* pSource )
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ pData = ((SvLBoxButton*)pSource)->pData;
+}
+
+void SvLBoxButton::ImplAdjustBoxSize( Size& io_rSize, ControlType i_eType, Window* i_pParent )
+{
+ if ( i_pParent->IsNativeControlSupported( i_eType, PART_ENTIRE_CONTROL) )
+ {
+ ImplControlValue aControlValue;
+ Rectangle aCtrlRegion( Point( 0, 0 ), io_rSize );
+ ControlState nState = CTRL_STATE_ENABLED;
+
+ aControlValue.setTristateVal( BUTTONVALUE_ON );
+
+ Rectangle aNativeBounds, aNativeContent;
+ bool bNativeOK = i_pParent->GetNativeControlRegion( i_eType,
+ PART_ENTIRE_CONTROL,
+ aCtrlRegion,
+ nState,
+ aControlValue,
+ rtl::OUString(),
+ aNativeBounds,
+ aNativeContent );
+ if( bNativeOK )
+ {
+ Size aContentSize( aNativeContent.GetSize() );
+ // leave a little space around the box image (looks better
+ if( aContentSize.Height() + 2 > io_rSize.Height() )
+ io_rSize.Height() = aContentSize.Height() + 2;
+ }
+ }
+}
+
+void SvLBoxButton::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
+ SvViewDataItem* pViewData )
+{
+ DBG_CHKTHIS(SvLBoxButton,0);
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+ Size aSize( pData->Width(), pData->Height() );
+
+ ControlType eCtrlType = (pData->IsRadio())? CTRL_RADIOBUTTON : CTRL_CHECKBOX;
+ if ( eKind != SvLBoxButtonKind_staticImage && pView )
+ ImplAdjustBoxSize( aSize, eCtrlType, pView );
+ pViewData->aSize = aSize;
+}
+
+bool SvLBoxButton::CheckModification() const
+{
+ if( eKind == SvLBoxButtonKind_disabledCheckbox )
+ Sound::Beep();
+ return eKind == SvLBoxButtonKind_enabledCheckbox;
+}
+
+// ***************************************************************
+// class SvLBoxContextBmp
+// ***************************************************************
+
+struct SvLBoxContextBmp_Impl
+{
+ Image m_aImage1;
+ Image m_aImage2;
+
+ Image m_aImage1_hc;
+ Image m_aImage2_hc;
+
+ USHORT m_nB2IndicatorFlags;
+};
+
+// ***************************************************************
+DBG_NAME(SvLBoxContextBmp)
+
+SvLBoxContextBmp::SvLBoxContextBmp( SvLBoxEntry* pEntry, USHORT nItemFlags,
+ Image aBmp1, Image aBmp2, USHORT nEntryFlags )
+ :SvLBoxItem( pEntry, nItemFlags )
+ ,m_pImpl( new SvLBoxContextBmp_Impl )
+{
+ DBG_CTOR(SvLBoxContextBmp,0);
+
+ m_pImpl->m_nB2IndicatorFlags = nEntryFlags;
+ SetModeImages( aBmp1, aBmp2 );
+}
+
+SvLBoxContextBmp::SvLBoxContextBmp()
+ :SvLBoxItem( )
+ ,m_pImpl( new SvLBoxContextBmp_Impl )
+{
+ m_pImpl->m_nB2IndicatorFlags = 0;
+ DBG_CTOR(SvLBoxContextBmp,0);
+}
+
+SvLBoxContextBmp::~SvLBoxContextBmp()
+{
+ delete m_pImpl;
+ DBG_DTOR(SvLBoxContextBmp,0);
+}
+
+USHORT SvLBoxContextBmp::IsA()
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+ return SV_ITEM_ID_LBOXCONTEXTBMP;
+}
+
+BOOL SvLBoxContextBmp::SetModeImages( const Image& _rBitmap1, const Image& _rBitmap2, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+
+ sal_Bool bSuccess = sal_True;
+ switch ( _eMode )
+ {
+ case BMP_COLOR_NORMAL:
+ m_pImpl->m_aImage1 = _rBitmap1;
+ m_pImpl->m_aImage2 = _rBitmap2;
+ break;
+
+ case BMP_COLOR_HIGHCONTRAST:
+ m_pImpl->m_aImage1_hc = _rBitmap1;
+ m_pImpl->m_aImage2_hc = _rBitmap2;
+ break;
+
+ default:
+ DBG_ERROR( "SvLBoxContextBmp::SetModeImages: unexpected mode!");
+ bSuccess = sal_False;
+ break;
+ }
+ return bSuccess;
+}
+
+Image& SvLBoxContextBmp::implGetImageStore( sal_Bool _bFirst, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+
+ switch ( _eMode )
+ {
+ case BMP_COLOR_NORMAL:
+ return _bFirst ? m_pImpl->m_aImage1 : m_pImpl->m_aImage2;
+
+ case BMP_COLOR_HIGHCONTRAST:
+ return _bFirst ? m_pImpl->m_aImage1_hc : m_pImpl->m_aImage2_hc;
+
+ default:
+ DBG_ERROR( "SvLBoxContextBmp::implGetImageStore: unexpected mode!");
+ }
+
+ // OJ: #i27071# wrong mode so we just return the normal images
+ return _bFirst ? m_pImpl->m_aImage1 : m_pImpl->m_aImage2;
+}
+
+void SvLBoxContextBmp::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
+ SvViewDataItem* pViewData)
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+ pViewData->aSize = m_pImpl->m_aImage1.GetSizePixel();
+}
+
+void SvLBoxContextBmp::Paint( const Point& _rPos, SvLBox& _rDev,
+ USHORT _nViewDataEntryFlags, SvLBoxEntry* _pEntry )
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+
+ // determine the image set
+ BmpColorMode eMode( BMP_COLOR_NORMAL );
+ if ( !!m_pImpl->m_aImage1_hc )
+ { // we really have HC images
+ if ( _rDev.GetSettings().GetStyleSettings().GetHighContrastMode() )
+ eMode = BMP_COLOR_HIGHCONTRAST;
+ }
+
+ // get the image
+ const Image& rImage = implGetImageStore( 0 == ( _nViewDataEntryFlags & m_pImpl->m_nB2IndicatorFlags ), eMode );
+
+ sal_Bool _bSemiTransparent = _pEntry && ( 0 != ( SV_ENTRYFLAG_SEMITRANSPARENT & _pEntry->GetFlags( ) ) );
+ // draw
+ USHORT nStyle = _rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE;
+ if ( _bSemiTransparent )
+ nStyle |= IMAGE_DRAW_SEMITRANSPARENT;
+ _rDev.DrawImage( _rPos, rImage, nStyle);
+}
+
+SvLBoxItem* SvLBoxContextBmp::Create() const
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+ return new SvLBoxContextBmp;
+}
+
+void SvLBoxContextBmp::Clone( SvLBoxItem* pSource )
+{
+ DBG_CHKTHIS(SvLBoxContextBmp,0);
+ m_pImpl->m_aImage1 = static_cast< SvLBoxContextBmp* >( pSource )->m_pImpl->m_aImage1;
+ m_pImpl->m_aImage2 = static_cast< SvLBoxContextBmp* >( pSource )->m_pImpl->m_aImage2;
+ m_pImpl->m_nB2IndicatorFlags = static_cast< SvLBoxContextBmp* >( pSource )->m_pImpl->m_nB2IndicatorFlags;
+}
+
diff --git a/svtools/source/contnr/svlbox.cxx b/svtools/source/contnr/svlbox.cxx
new file mode 100644
index 000000000000..fb71f64772ad
--- /dev/null
+++ b/svtools/source/contnr/svlbox.cxx
@@ -0,0 +1,1923 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+/*
+ Todo:
+ - Anker loeschen in SelectionEngine bei manuellem Selektieren
+ - SelectAll( FALSE ), nur die deselektierten Entries repainten
+*/
+
+#include <string.h>
+#include <svtools/svlbox.hxx>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/accel.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <sot/formats.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <rtl/instance.hxx>
+
+#define _SVSTDARR_ULONGSSORT
+#include <svl/svstdarr.hxx>
+
+#ifndef _SVEDI_HXX
+#include <svtools/svmedit.hxx>
+#endif
+#include <svtools/svlbitm.hxx>
+
+using namespace ::com::sun::star::accessibility;
+
+// Drag&Drop
+static SvLBox* pDDSource = NULL;
+static SvLBox* pDDTarget = NULL;
+
+DBG_NAME(SvInplaceEdit)
+DBG_NAME(SvInplaceEdit2)
+
+#define SVLBOX_ACC_RETURN 1
+#define SVLBOX_ACC_ESCAPE 2
+
+SvInplaceEdit::SvInplaceEdit
+(
+ Window* pParent,
+ const Point& rPos,
+ const Size& rSize,
+ const String& rData,
+ const Link& rNotifyEditEnd,
+ const Selection& rSelection
+) :
+
+ Edit( pParent, WB_LEFT ),
+
+ aCallBackHdl ( rNotifyEditEnd ),
+ bCanceled ( FALSE ),
+ bAlreadyInCallBack ( FALSE )
+
+{
+ DBG_CTOR(SvInplaceEdit,0);
+
+ Font aFont( pParent->GetFont() );
+ aFont.SetTransparent( FALSE );
+ Color aColor( pParent->GetBackground().GetColor() );
+ aFont.SetFillColor(aColor );
+ SetFont( aFont );
+ SetBackground( pParent->GetBackground() );
+ SetPosPixel( rPos );
+ SetSizePixel( rSize );
+ SetText( rData );
+ SetSelection( rSelection );
+ SaveValue();
+
+ aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) );
+ aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) );
+
+ aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit, ReturnHdl_Impl) );
+ aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit, EscapeHdl_Impl) );
+ GetpApp()->InsertAccel( &aAccReturn );
+ GetpApp()->InsertAccel( &aAccEscape );
+
+ Show();
+ GrabFocus();
+}
+
+SvInplaceEdit::~SvInplaceEdit()
+{
+ DBG_DTOR(SvInplaceEdit,0);
+ if( !bAlreadyInCallBack )
+ {
+ GetpApp()->RemoveAccel( &aAccReturn );
+ GetpApp()->RemoveAccel( &aAccEscape );
+ }
+}
+
+IMPL_LINK_INLINE_START( SvInplaceEdit, ReturnHdl_Impl, Accelerator *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ bCanceled = FALSE;
+ CallCallBackHdl_Impl();
+ return 1;
+}
+IMPL_LINK_INLINE_END( SvInplaceEdit, ReturnHdl_Impl, Accelerator *, EMPTYARG )
+
+IMPL_LINK_INLINE_START( SvInplaceEdit, EscapeHdl_Impl, Accelerator *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ bCanceled = TRUE;
+ CallCallBackHdl_Impl();
+ return 1;
+}
+IMPL_LINK_INLINE_END( SvInplaceEdit, EscapeHdl_Impl, Accelerator *, EMPTYARG )
+
+void SvInplaceEdit::KeyInput( const KeyEvent& rKEvt )
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+ switch ( nCode )
+ {
+ case KEY_ESCAPE:
+ bCanceled = TRUE;
+ CallCallBackHdl_Impl();
+ break;
+
+ case KEY_RETURN:
+ bCanceled = FALSE;
+ CallCallBackHdl_Impl();
+ break;
+
+ default:
+ Edit::KeyInput( rKEvt );
+ }
+}
+
+void SvInplaceEdit::StopEditing( BOOL bCancel )
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ if ( !bAlreadyInCallBack )
+ {
+ bCanceled = bCancel;
+ CallCallBackHdl_Impl();
+ }
+}
+
+void SvInplaceEdit::LoseFocus()
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ if ( !bAlreadyInCallBack )
+ {
+ bCanceled = FALSE;
+ aTimer.SetTimeout(10);
+ aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit,Timeout_Impl));
+ aTimer.Start();
+ }
+}
+
+IMPL_LINK_INLINE_START( SvInplaceEdit, Timeout_Impl, Timer *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ CallCallBackHdl_Impl();
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvInplaceEdit, Timeout_Impl, Timer *, EMPTYARG )
+
+void SvInplaceEdit::CallCallBackHdl_Impl()
+{
+ DBG_CHKTHIS(SvInplaceEdit,0);
+ aTimer.Stop();
+ if ( !bAlreadyInCallBack )
+ {
+ bAlreadyInCallBack = TRUE;
+ GetpApp()->RemoveAccel( &aAccReturn );
+ GetpApp()->RemoveAccel( &aAccEscape );
+ Hide();
+ aCallBackHdl.Call( this );
+ // bAlreadyInCallBack = FALSE;
+ }
+}
+
+
+// ***************************************************************
+
+class MyEdit_Impl : public Edit
+{
+ SvInplaceEdit2* pOwner;
+public:
+ MyEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual void LoseFocus();
+};
+
+class MyMultiEdit_Impl : public MultiLineEdit
+{
+ SvInplaceEdit2* pOwner;
+public:
+ MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual void LoseFocus();
+};
+
+MyEdit_Impl::MyEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner ) :
+
+ Edit( pParent, WB_LEFT ),
+
+ pOwner( _pOwner )
+
+{
+}
+
+void MyEdit_Impl::KeyInput( const KeyEvent& rKEvt )
+{
+ if( !pOwner->KeyInput( rKEvt ))
+ Edit::KeyInput( rKEvt );
+}
+
+void MyEdit_Impl::LoseFocus()
+{
+ pOwner->LoseFocus();
+}
+
+MyMultiEdit_Impl::MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner )
+ : MultiLineEdit( pParent,
+ WB_CENTER
+ ), pOwner(_pOwner)
+{
+}
+
+void MyMultiEdit_Impl::KeyInput( const KeyEvent& rKEvt )
+{
+ if( !pOwner->KeyInput( rKEvt ))
+ MultiLineEdit::KeyInput( rKEvt );
+}
+
+void MyMultiEdit_Impl::LoseFocus()
+{
+ pOwner->LoseFocus();
+}
+
+
+SvInplaceEdit2::SvInplaceEdit2
+(
+ Window* pParent, const Point& rPos,
+ const Size& rSize,
+ const String& rData,
+ const Link& rNotifyEditEnd,
+ const Selection& rSelection,
+ BOOL bMulti
+) :
+
+ aCallBackHdl ( rNotifyEditEnd ),
+ bCanceled ( FALSE ),
+ bAlreadyInCallBack ( FALSE ),
+ bMultiLine ( bMulti )
+
+{
+ DBG_CTOR(SvInplaceEdit2,0);
+
+ if( bMulti )
+ pEdit = new MyMultiEdit_Impl( pParent, this );
+ else
+ pEdit = new MyEdit_Impl( pParent, this );
+
+ Font aFont( pParent->GetFont() );
+ aFont.SetTransparent( FALSE );
+ Color aColor( pParent->GetBackground().GetColor() );
+ aFont.SetFillColor(aColor );
+ pEdit->SetFont( aFont );
+ pEdit->SetBackground( pParent->GetBackground() );
+ pEdit->SetPosPixel( rPos );
+ pEdit->SetSizePixel( rSize );
+ pEdit->SetText( rData );
+ pEdit->SetSelection( rSelection );
+ pEdit->SaveValue();
+
+ aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) );
+ aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) );
+
+ aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit2, ReturnHdl_Impl) );
+ aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit2, EscapeHdl_Impl) );
+ GetpApp()->InsertAccel( &aAccReturn );
+ GetpApp()->InsertAccel( &aAccEscape );
+
+ pEdit->Show();
+ pEdit->GrabFocus();
+}
+
+SvInplaceEdit2::~SvInplaceEdit2()
+{
+ DBG_DTOR(SvInplaceEdit2,0);
+ if( !bAlreadyInCallBack )
+ {
+ GetpApp()->RemoveAccel( &aAccReturn );
+ GetpApp()->RemoveAccel( &aAccEscape );
+ }
+ delete pEdit;
+}
+
+String SvInplaceEdit2::GetSavedValue() const
+{
+ return pEdit->GetSavedValue();
+}
+
+void SvInplaceEdit2::Hide()
+{
+ pEdit->Hide();
+}
+
+
+IMPL_LINK_INLINE_START( SvInplaceEdit2, ReturnHdl_Impl, Accelerator *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ bCanceled = FALSE;
+ CallCallBackHdl_Impl();
+ return 1;
+}
+IMPL_LINK_INLINE_END( SvInplaceEdit2, ReturnHdl_Impl, Accelerator *, EMPTYARG )
+
+IMPL_LINK_INLINE_START( SvInplaceEdit2, EscapeHdl_Impl, Accelerator *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ bCanceled = TRUE;
+ CallCallBackHdl_Impl();
+ return 1;
+}
+IMPL_LINK_INLINE_END( SvInplaceEdit2, EscapeHdl_Impl, Accelerator *, EMPTYARG )
+
+
+BOOL SvInplaceEdit2::KeyInput( const KeyEvent& rKEvt )
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ KeyCode aCode = rKEvt.GetKeyCode();
+ USHORT nCode = aCode.GetCode();
+
+ switch ( nCode )
+ {
+ case KEY_ESCAPE:
+ bCanceled = TRUE;
+ CallCallBackHdl_Impl();
+ return TRUE;
+
+ case KEY_RETURN:
+ bCanceled = FALSE;
+ CallCallBackHdl_Impl();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SvInplaceEdit2::StopEditing( BOOL bCancel )
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ if ( !bAlreadyInCallBack )
+ {
+ bCanceled = bCancel;
+ CallCallBackHdl_Impl();
+ }
+}
+
+void SvInplaceEdit2::LoseFocus()
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ if ( !bAlreadyInCallBack
+ && ((!Application::GetFocusWindow()) || !pEdit->IsChild( Application::GetFocusWindow()) )
+ )
+ {
+ bCanceled = FALSE;
+ aTimer.SetTimeout(10);
+ aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit2,Timeout_Impl));
+ aTimer.Start();
+ }
+}
+
+IMPL_LINK_INLINE_START( SvInplaceEdit2, Timeout_Impl, Timer *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ CallCallBackHdl_Impl();
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvInplaceEdit2, Timeout_Impl, Timer *, EMPTYARG )
+
+void SvInplaceEdit2::CallCallBackHdl_Impl()
+{
+ DBG_CHKTHIS(SvInplaceEdit2,0);
+ aTimer.Stop();
+ if ( !bAlreadyInCallBack )
+ {
+ bAlreadyInCallBack = TRUE;
+ GetpApp()->RemoveAccel( &aAccReturn );
+ GetpApp()->RemoveAccel( &aAccEscape );
+ pEdit->Hide();
+ aCallBackHdl.Call( this );
+ }
+}
+
+String SvInplaceEdit2::GetText() const
+{
+ return pEdit->GetText();
+}
+
+// ***************************************************************
+// class SvLBoxTab
+// ***************************************************************
+
+DBG_NAME(SvLBoxTab);
+
+SvLBoxTab::SvLBoxTab()
+{
+ DBG_CTOR(SvLBoxTab,0);
+ nPos = 0;
+ pUserData = 0;
+ nFlags = 0;
+}
+
+SvLBoxTab::SvLBoxTab( long nPosition, USHORT nTabFlags )
+{
+ DBG_CTOR(SvLBoxTab,0);
+ nPos = nPosition;
+ pUserData = 0;
+ nFlags = nTabFlags;
+}
+
+SvLBoxTab::SvLBoxTab( const SvLBoxTab& rTab )
+{
+ DBG_CTOR(SvLBoxTab,0);
+ nPos = rTab.nPos;
+ pUserData = rTab.pUserData;
+ nFlags = rTab.nFlags;
+}
+
+SvLBoxTab::~SvLBoxTab()
+{
+ DBG_DTOR(SvLBoxTab,0);
+}
+
+
+long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth )
+{
+ DBG_CHKTHIS(SvLBoxTab,0);
+ long nOffset = 0;
+ if ( nFlags & SV_LBOXTAB_ADJUST_RIGHT )
+ {
+ nOffset = nTabWidth - nItemWidth;
+ if( nOffset < 0 )
+ nOffset = 0;
+ }
+ else if ( nFlags & SV_LBOXTAB_ADJUST_CENTER )
+ {
+ if( nFlags & SV_LBOXTAB_FORCE )
+ {
+ //richtige Implementierung der Zentrierung
+ nOffset = ( nTabWidth - nItemWidth ) / 2;
+ if( nOffset < 0 )
+ nOffset = 0;
+ }
+ else
+ {
+ // historisch gewachsene falsche Berechnung des Tabs, auf die sich
+ // Abo-Tabbox, Extras/Optionen/Anpassen etc. verlassen
+ nItemWidth++;
+ nOffset = -( nItemWidth / 2 );
+ }
+ }
+ return nOffset;
+}
+
+/*
+long SvLBoxTab::CalcOffset( const String& rStr, const OutputDevice& rOutDev )
+{
+ DBG_CHKTHIS(SvLBoxTab,0);
+ long nWidth;
+ if ( nFlags & SV_LBOXTAB_ADJUST_NUMERIC )
+ {
+ USHORT nPos = rStr.Search( '.' );
+ if ( nPos == STRING_NOTFOUND )
+ nPos = rStr.Search( ',' );
+ if ( nPos == STRING_NOTFOUND )
+ nPos = STRING_LEN;
+
+ nWidth = rOutDev.GetTextSize( rStr, 0, nPos ).Width();
+ nWidth *= -1;
+ }
+ else
+ {
+ nWidth = rOutDev.GetTextSize( rStr ).Width();
+ nWidth = CalcOffset( nWidth );
+ }
+ return nWidth;
+}
+*/
+
+// ***************************************************************
+// class SvLBoxItem
+// ***************************************************************
+
+DBG_NAME(SvLBoxItem);
+
+SvLBoxItem::SvLBoxItem( SvLBoxEntry*, USHORT )
+{
+ DBG_CTOR(SvLBoxItem,0);
+}
+
+SvLBoxItem::SvLBoxItem()
+{
+ DBG_CTOR(SvLBoxItem,0);
+}
+
+SvLBoxItem::~SvLBoxItem()
+{
+ DBG_DTOR(SvLBoxItem,0);
+}
+
+const Size& SvLBoxItem::GetSize( SvLBox* pView,SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvLBoxItem,0);
+ SvViewDataItem* pViewData = pView->GetViewDataItem( pEntry, this );
+ return pViewData->aSize;
+}
+
+const Size& SvLBoxItem::GetSize( SvLBoxEntry* pEntry, SvViewDataEntry* pViewData)
+{
+ DBG_CHKTHIS(SvLBoxItem,0);
+ USHORT nItemPos = pEntry->GetPos( this );
+ SvViewDataItem* pItemData = pViewData->pItemData+nItemPos;
+ return pItemData->aSize;
+}
+
+DBG_NAME(SvViewDataItem);
+
+SvViewDataItem::SvViewDataItem()
+{
+ DBG_CTOR(SvViewDataItem,0);
+}
+
+SvViewDataItem::~SvViewDataItem()
+{
+ DBG_DTOR(SvViewDataItem,0);
+}
+
+
+
+// ***************************************************************
+// class SvLBoxEntry
+// ***************************************************************
+
+DBG_NAME(SvLBoxEntry);
+
+SvLBoxEntry::SvLBoxEntry() : aItems()
+{
+ DBG_CTOR(SvLBoxEntry,0);
+ nEntryFlags = 0;
+ pUserData = 0;
+}
+
+SvLBoxEntry::~SvLBoxEntry()
+{
+ DBG_DTOR(SvLBoxEntry,0);
+ DeleteItems_Impl();
+}
+
+void SvLBoxEntry::DeleteItems_Impl()
+{
+ DBG_CHKTHIS(SvLBoxEntry,0);
+ USHORT nCount = aItems.Count();
+ while( nCount )
+ {
+ nCount--;
+ SvLBoxItem* pItem = (SvLBoxItem*)aItems.GetObject( nCount );
+ delete pItem;
+ }
+ aItems.Remove(0, aItems.Count() );
+}
+
+
+void SvLBoxEntry::AddItem( SvLBoxItem* pItem )
+{
+ DBG_CHKTHIS(SvLBoxEntry,0);
+ aItems.Insert( pItem, aItems.Count() );
+}
+
+void SvLBoxEntry::Clone( SvListEntry* pSource )
+{
+ DBG_CHKTHIS(SvLBoxEntry,0);
+ SvListEntry::Clone( pSource );
+ SvLBoxItem* pNewItem;
+ DeleteItems_Impl();
+ USHORT nCount = ((SvLBoxEntry*)pSource)->ItemCount();
+ USHORT nCurPos = 0;
+ while( nCurPos < nCount )
+ {
+ SvLBoxItem* pItem = ((SvLBoxEntry*)pSource)->GetItem( nCurPos );
+ pNewItem = pItem->Create();
+ pNewItem->Clone( pItem );
+ AddItem( pNewItem );
+ nCurPos++;
+ }
+ pUserData = ((SvLBoxEntry*)pSource)->GetUserData();
+ nEntryFlags = ((SvLBoxEntry*)pSource)->nEntryFlags;
+}
+
+void SvLBoxEntry::EnableChildsOnDemand( BOOL bEnable )
+{
+ DBG_CHKTHIS(SvLBoxEntry,0);
+ if ( bEnable )
+ nEntryFlags |= SV_ENTRYFLAG_CHILDS_ON_DEMAND;
+ else
+ nEntryFlags &= (~SV_ENTRYFLAG_CHILDS_ON_DEMAND);
+}
+
+void SvLBoxEntry::ReplaceItem( SvLBoxItem* pNewItem, USHORT nPos )
+{
+ DBG_CHKTHIS(SvLBoxEntry,0);
+ DBG_ASSERT(pNewItem,"ReplaceItem:No Item");
+ SvLBoxItem* pOld = GetItem( nPos );
+ if ( pOld )
+ {
+ aItems.Remove( nPos );
+ aItems.Insert( pNewItem, nPos );
+ delete pOld;
+ }
+}
+
+SvLBoxItem* SvLBoxEntry::GetFirstItem( USHORT nId )
+{
+ USHORT nCount = aItems.Count();
+ USHORT nCur = 0;
+ SvLBoxItem* pItem;
+ while( nCur < nCount )
+ {
+ pItem = GetItem( nCur );
+ if( pItem->IsA() == nId )
+ return pItem;
+ nCur++;
+ }
+ return 0;
+}
+
+// ***************************************************************
+// class SvLBoxViewData
+// ***************************************************************
+
+DBG_NAME(SvViewDataEntry);
+
+SvViewDataEntry::SvViewDataEntry()
+ : SvViewData()
+{
+ DBG_CTOR(SvViewDataEntry,0);
+ pItemData = 0;
+}
+
+SvViewDataEntry::~SvViewDataEntry()
+{
+ DBG_DTOR(SvViewDataEntry,0);
+ delete [] pItemData;
+}
+
+// ***************************************************************
+// struct SvLBox_Impl
+// ***************************************************************
+SvLBox_Impl::SvLBox_Impl( SvLBox& _rBox )
+ :m_bIsEmptyTextAllowed( true )
+ ,m_bEntryMnemonicsEnabled( false )
+ ,m_pLink( NULL )
+ ,m_aMnemonicEngine( _rBox )
+{
+}
+
+// ***************************************************************
+// class SvLBox
+// ***************************************************************
+
+DBG_NAME(SvLBox);
+
+SvLBox::SvLBox( Window* pParent, WinBits nWinStyle ) :
+ Control( pParent, nWinStyle | WB_CLIPCHILDREN ),
+ DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION )
+{
+ DBG_CTOR(SvLBox,0);
+ nWindowStyle = nWinStyle;
+ nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
+ nImpFlags = 0;
+ pTargetEntry = 0;
+ nDragDropMode = 0;
+ pLBoxImpl = new SvLBox_Impl( *this );
+ SvLBoxTreeList* pTempModel = new SvLBoxTreeList;
+ pTempModel->SetRefCount( 0 );
+ SetModel( pTempModel );
+ pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
+ pModel->InsertView( this );
+ pHdlEntry = 0;
+ pEdCtrl = 0;
+ SetSelectionMode( SINGLE_SELECTION ); // pruefen ob TreeListBox gecallt wird
+ SetDragDropMode( SV_DRAGDROP_NONE );
+ SetType(WINDOW_TREELISTBOX);
+}
+
+SvLBox::SvLBox( Window* pParent, const ResId& rResId ) :
+ Control( pParent, rResId ),
+ DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION )
+{
+ DBG_CTOR(SvLBox,0);
+ pTargetEntry = 0;
+ nImpFlags = 0;
+ nWindowStyle = 0;
+ pLBoxImpl = new SvLBox_Impl( *this );
+ nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
+ nDragDropMode = 0;
+ SvLBoxTreeList* pTempModel = new SvLBoxTreeList;
+ pTempModel->SetRefCount( 0 );
+ SetModel( pTempModel );
+ pModel->InsertView( this );
+ pHdlEntry = 0;
+ pEdCtrl = 0;
+ pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
+ SetType(WINDOW_TREELISTBOX);
+}
+
+__EXPORT SvLBox::~SvLBox()
+{
+ DBG_DTOR(SvLBox,0);
+ delete pEdCtrl;
+ pEdCtrl = 0;
+ pModel->RemoveView( this );
+ if ( pModel->GetRefCount() == 0 )
+ {
+ pModel->Clear();
+ delete pModel;
+ pModel = NULL;
+ }
+
+ SvLBox::RemoveBoxFromDDList_Impl( *this );
+
+ if( this == pDDSource )
+ pDDSource = 0;
+ if( this == pDDTarget )
+ pDDTarget = 0;
+ delete pLBoxImpl;
+}
+
+void SvLBox::SetModel( SvLBoxTreeList* pNewModel )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ // erledigt das ganz CleanUp
+ SvListView::SetModel( pNewModel );
+ pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
+ SvLBoxEntry* pEntry = First();
+ while( pEntry )
+ {
+ ModelHasInserted( pEntry );
+ pEntry = Next( pEntry );
+ }
+}
+
+void SvLBox::DisconnectFromModel()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ SvLBoxTreeList* pNewModel = new SvLBoxTreeList;
+ pNewModel->SetRefCount( 0 ); // else this will never be deleted
+ SvListView::SetModel( pNewModel );
+}
+
+void SvLBox::Clear()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ pModel->Clear(); // Model ruft SvLBox::ModelHasCleared() auf
+}
+
+void SvLBox::EnableEntryMnemonics( bool _bEnable )
+{
+ if ( _bEnable == IsEntryMnemonicsEnabled() )
+ return;
+
+ pLBoxImpl->m_bEntryMnemonicsEnabled = _bEnable;
+ Invalidate();
+}
+
+bool SvLBox::IsEntryMnemonicsEnabled() const
+{
+ return pLBoxImpl->m_bEntryMnemonicsEnabled;
+}
+
+USHORT SvLBox::IsA()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return SVLISTBOX_ID_LBOX;
+}
+
+IMPL_LINK_INLINE_START( SvLBox, CloneHdl_Impl, SvListEntry*, pEntry )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return (long)(CloneEntry((SvLBoxEntry*)pEntry));
+}
+IMPL_LINK_INLINE_END( SvLBox, CloneHdl_Impl, SvListEntry*, pEntry )
+
+ULONG SvLBox::Insert( SvLBoxEntry* pEntry, SvLBoxEntry* pParent, ULONG nPos )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ ULONG nInsPos = pModel->Insert( pEntry, pParent, nPos );
+ return nInsPos;
+}
+
+ULONG SvLBox::Insert( SvLBoxEntry* pEntry,ULONG nRootPos )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ ULONG nInsPos = pModel->Insert( pEntry, nRootPos );
+ return nInsPos;
+}
+
+long SvLBox::ExpandingHdl()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return aExpandingHdl.IsSet() ? aExpandingHdl.Call( this ) : 1;
+}
+
+void SvLBox::ExpandedHdl()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ aExpandedHdl.Call( this );
+}
+
+void SvLBox::SelectHdl()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ aSelectHdl.Call( this );
+}
+
+void SvLBox::DeselectHdl()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ aDeselectHdl.Call( this );
+}
+
+BOOL SvLBox::DoubleClickHdl()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ aDoubleClickHdl.Call( this );
+ return TRUE;
+}
+
+
+BOOL SvLBox::CheckDragAndDropMode( SvLBox* pSource, sal_Int8 nAction )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ if ( pSource == this )
+ {
+ if ( !(nDragDropMode & (SV_DRAGDROP_CTRL_MOVE | SV_DRAGDROP_CTRL_COPY) ) )
+ return FALSE; // D&D innerhalb der Liste gesperrt
+ if( DND_ACTION_MOVE == nAction )
+ {
+ if ( !(nDragDropMode & SV_DRAGDROP_CTRL_MOVE) )
+ return FALSE; // kein lokales Move
+ }
+ else
+ {
+ if ( !(nDragDropMode & SV_DRAGDROP_CTRL_COPY))
+ return FALSE; // kein lokales Copy
+ }
+ }
+ else
+ {
+ if ( !(nDragDropMode & SV_DRAGDROP_APP_DROP ) )
+ return FALSE; // kein Drop
+ if ( DND_ACTION_MOVE == nAction )
+ {
+ if ( !(nDragDropMode & SV_DRAGDROP_APP_MOVE) )
+ return FALSE; // kein globales Move
+ }
+ else
+ {
+ if ( !(nDragDropMode & SV_DRAGDROP_APP_COPY))
+ return FALSE; // kein globales Copy
+ }
+ }
+ return TRUE;
+}
+
+
+
+
+void SvLBox::NotifyRemoving( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+/*
+ NotifyMoving/Copying
+ ====================
+
+ Standard-Verhalten:
+
+ 1. Target hat keine Childs
+ - Entry wird Sibling des Targets. Entry steht hinter dem
+ Target (->Fenster: Unter dem Target)
+ 2. Target ist ein aufgeklappter Parent
+ - Entry wird an den Anfang der Target-Childlist gehaengt
+ 3. Target ist ein zugeklappter Parent
+ - Entry wird an das Ende der Target-Childlist gehaengt
+*/
+#ifdef DBG_UTIL
+BOOL SvLBox::NotifyMoving(
+ SvLBoxEntry* pTarget, // D&D-Drop-Position in this->GetModel()
+ SvLBoxEntry* pEntry, // Zu verschiebender Entry aus
+ // GetSourceListBox()->GetModel()
+ SvLBoxEntry*& rpNewParent, // Neuer Target-Parent
+ ULONG& rNewChildPos) // Position in Childlist des Target-Parents
+#else
+BOOL SvLBox::NotifyMoving(
+ SvLBoxEntry* pTarget, // D&D-Drop-Position in this->GetModel()
+ SvLBoxEntry*, // Zu verschiebender Entry aus
+ // GetSourceListBox()->GetModel()
+ SvLBoxEntry*& rpNewParent, // Neuer Target-Parent
+ ULONG& rNewChildPos) // Position in Childlist des Target-Parents
+#endif
+{
+ DBG_CHKTHIS(SvLBox,0);
+ DBG_ASSERT(pEntry,"NotifyMoving:SoureEntry?");
+ if( !pTarget )
+ {
+ rpNewParent = 0;
+ rNewChildPos = 0;
+ return TRUE;
+ }
+ if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() )
+ {
+ // Fall 1
+ rpNewParent = GetParent( pTarget );
+ rNewChildPos = pModel->GetRelPos( pTarget ) + 1;
+ rNewChildPos += nCurEntrySelPos;
+ nCurEntrySelPos++;
+ }
+ else
+ {
+ // Faelle 2 & 3
+ rpNewParent = pTarget;
+ if( IsExpanded(pTarget))
+ rNewChildPos = 0;
+ else
+ rNewChildPos = LIST_APPEND;
+ }
+ return TRUE;
+}
+
+BOOL SvLBox::NotifyCopying(
+ SvLBoxEntry* pTarget, // D&D-Drop-Position in this->GetModel()
+ SvLBoxEntry* pEntry, // Zu kopierender Entry aus
+ // GetSourceListBox()->GetModel()
+ SvLBoxEntry*& rpNewParent, // Neuer Target-Parent
+ ULONG& rNewChildPos) // Position in Childlist des Target-Parents
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos);
+ /*
+ DBG_ASSERT(pEntry,"NotifyCopying:SourceEntry?");
+ if( !pTarget )
+ {
+ rpNewParent = 0;
+ rNewChildPos = 0;
+ return TRUE;
+ }
+ if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() )
+ {
+ // Fall 1
+ rpNewParent = GetParent( pTarget );
+ rNewChildPos = GetRelPos( pTarget ) + 1;
+ }
+ else
+ {
+ // Faelle 2 & 3
+ rpNewParent = pTarget;
+ if( IsExpanded(pTarget))
+ rNewChildPos = 0;
+ else
+ rNewChildPos = LIST_APPEND;
+ }
+ return TRUE;
+ */
+}
+
+SvLBoxEntry* SvLBox::CloneEntry( SvLBoxEntry* pSource )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)CreateEntry(); // new SvLBoxEntry;
+ pEntry->Clone( (SvListEntry*)pSource );
+ return pEntry;
+}
+
+
+// Rueckgabe: Alle Entries wurden kopiert
+BOOL SvLBox::CopySelection( SvLBox* pSource, SvLBoxEntry* pTarget )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ nCurEntrySelPos = 0; // Selektionszaehler fuer NotifyMoving/Copying
+ BOOL bSuccess = TRUE;
+ SvTreeEntryList aList;
+ BOOL bClone = (BOOL)( (ULONG)(pSource->GetModel()) != (ULONG)GetModel() );
+ Link aCloneLink( pModel->GetCloneLink() );
+ pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
+
+ // Selektion zwischenspeichern, um bei D&D-Austausch
+ // innerhalb der gleichen Listbox das Iterieren ueber
+ // die Selektion zu vereinfachen
+ SvLBoxEntry* pSourceEntry = pSource->FirstSelected();
+ while ( pSourceEntry )
+ {
+ // Childs werden automatisch mitkopiert
+ pSource->SelectChilds( pSourceEntry, FALSE );
+ aList.Insert( pSourceEntry, LIST_APPEND );
+ pSourceEntry = pSource->NextSelected( pSourceEntry );
+ }
+
+ pSourceEntry = (SvLBoxEntry*)aList.First();
+ while ( pSourceEntry )
+ {
+ SvLBoxEntry* pNewParent = 0;
+ ULONG nInsertionPos = LIST_APPEND;
+ BOOL bOk=NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
+ if ( bOk )
+ {
+ if ( bClone )
+ {
+ ULONG nCloneCount = 0;
+ pSourceEntry = (SvLBoxEntry*)
+ pModel->Clone( (SvListEntry*)pSourceEntry, nCloneCount );
+ pModel->InsertTree( (SvListEntry*)pSourceEntry,
+ (SvListEntry*)pNewParent, nInsertionPos );
+ }
+ else
+ {
+ ULONG nListPos = pModel->Copy( (SvListEntry*)pSourceEntry,
+ (SvListEntry*)pNewParent, nInsertionPos );
+ pSourceEntry = GetEntry( pNewParent, nListPos );
+ }
+ }
+ else
+ bSuccess = FALSE;
+
+ if( bOk == (BOOL)2 ) // !!!HACK verschobenen Entry sichtbar machen?
+ MakeVisible( pSourceEntry );
+
+ pSourceEntry = (SvLBoxEntry*)aList.Next();
+ }
+ pModel->SetCloneLink( aCloneLink );
+ return bSuccess;
+}
+
+// Rueckgabe: Alle Entries wurden verschoben
+BOOL SvLBox::MoveSelection( SvLBox* pSource, SvLBoxEntry* pTarget )
+{
+ return MoveSelectionCopyFallbackPossible( pSource, pTarget, sal_False );
+}
+
+BOOL SvLBox::MoveSelectionCopyFallbackPossible( SvLBox* pSource, SvLBoxEntry* pTarget, sal_Bool bAllowCopyFallback )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ nCurEntrySelPos = 0; // Selektionszaehler fuer NotifyMoving/Copying
+ BOOL bSuccess = TRUE;
+ SvTreeEntryList aList;
+ BOOL bClone = (BOOL)( (ULONG)(pSource->GetModel()) != (ULONG)GetModel() );
+ Link aCloneLink( pModel->GetCloneLink() );
+ if ( bClone )
+ pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
+
+ SvLBoxEntry* pSourceEntry = pSource->FirstSelected();
+ while ( pSourceEntry )
+ {
+ // Childs werden automatisch mitbewegt
+ pSource->SelectChilds( pSourceEntry, FALSE );
+ aList.Insert( pSourceEntry, LIST_APPEND );
+ pSourceEntry = pSource->NextSelected( pSourceEntry );
+ }
+
+ pSourceEntry = (SvLBoxEntry*)aList.First();
+ while ( pSourceEntry )
+ {
+ SvLBoxEntry* pNewParent = 0;
+ ULONG nInsertionPos = LIST_APPEND;
+ sal_Bool bOk = NotifyMoving(pTarget,pSourceEntry,pNewParent,nInsertionPos);
+ sal_Bool bCopyOk = bOk;
+ if ( !bOk && bAllowCopyFallback )
+ {
+ nInsertionPos = LIST_APPEND;
+ bCopyOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
+ }
+
+ if ( bOk || bCopyOk )
+ {
+ if ( bClone )
+ {
+ ULONG nCloneCount = 0;
+ pSourceEntry = (SvLBoxEntry*)
+ pModel->Clone( (SvListEntry*)pSourceEntry, nCloneCount );
+ pModel->InsertTree( (SvListEntry*)pSourceEntry,
+ (SvListEntry*)pNewParent, nInsertionPos );
+ }
+ else
+ {
+ if ( bOk )
+ pModel->Move( (SvListEntry*)pSourceEntry,
+ (SvListEntry*)pNewParent, nInsertionPos );
+ else
+ pModel->Copy( (SvListEntry*)pSourceEntry,
+ (SvListEntry*)pNewParent, nInsertionPos );
+ }
+ }
+ else
+ bSuccess = FALSE;
+
+ if( bOk == (BOOL)2 ) // !!!HACK verschobenen Entry sichtbar machen?
+ MakeVisible( pSourceEntry );
+
+ pSourceEntry = (SvLBoxEntry*)aList.Next();
+ }
+ pModel->SetCloneLink( aCloneLink );
+ return bSuccess;
+}
+
+void SvLBox::RemoveSelection()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ SvTreeEntryList aList;
+ // Selektion zwischenspeichern, da die Impl bei
+ // dem ersten Remove alles deselektiert!
+ SvLBoxEntry* pEntry = FirstSelected();
+ while ( pEntry )
+ {
+ aList.Insert( pEntry );
+ if ( pEntry->HasChilds() )
+ // Remove loescht Childs automatisch
+ SelectChilds( pEntry, FALSE );
+ pEntry = NextSelected( pEntry );
+ }
+ pEntry = (SvLBoxEntry*)aList.First();
+ while ( pEntry )
+ {
+ pModel->Remove( pEntry );
+ pEntry = (SvLBoxEntry*)aList.Next();
+ }
+}
+
+SvLBox* SvLBox::GetSourceView() const
+{
+ return pDDSource;
+}
+
+SvLBox* SvLBox::GetTargetView() const
+{
+ return pDDTarget;
+}
+
+void SvLBox::RequestingChilds( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ DBG_ERROR("Child-Request-Hdl not implemented!");
+}
+
+void SvLBox::RecalcViewData()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ SvLBoxEntry* pEntry = First();
+ while( pEntry )
+ {
+ USHORT nCount = pEntry->ItemCount();
+ USHORT nCurPos = 0;
+ while ( nCurPos < nCount )
+ {
+ SvLBoxItem* pItem = pEntry->GetItem( nCurPos );
+ pItem->InitViewData( this, pEntry );
+ nCurPos++;
+ }
+ ViewDataInitialized( pEntry );
+ pEntry = Next( pEntry );
+ }
+}
+
+void SvLBox::ViewDataInitialized( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+void SvLBox::StateChanged( StateChangedType eType )
+{
+ if( eType == STATE_CHANGE_ENABLE )
+ Invalidate( INVALIDATE_CHILDREN );
+ Control::StateChanged( eType );
+}
+
+void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL bShow)
+{
+ DBG_CHKTHIS(SvLBox,0);
+ if ( bShow && (nImpFlags & SVLBOX_TARGEMPH_VIS) )
+ return;
+ if ( !bShow && !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
+ return;
+ ShowTargetEmphasis( pEntry, bShow );
+ if( bShow )
+ nImpFlags |= SVLBOX_TARGEMPH_VIS;
+ else
+ nImpFlags &= ~SVLBOX_TARGEMPH_VIS;
+}
+
+void SvLBox::ShowTargetEmphasis( SvLBoxEntry*, BOOL /* bShow */ )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+
+BOOL SvLBox::Expand( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return TRUE;
+}
+
+BOOL SvLBox::Collapse( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return TRUE;
+}
+
+BOOL SvLBox::Select( SvLBoxEntry*, BOOL )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return FALSE;
+}
+
+ULONG SvLBox::SelectChilds( SvLBoxEntry* , BOOL )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return 0;
+}
+
+void SvLBox::SelectAll( BOOL /* bSelect */ , BOOL /* bPaint */ )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+SvLBoxEntry* SvLBox::GetEntryFromPath( const ::std::deque< sal_Int32 >& _rPath ) const
+{
+ DBG_CHKTHIS(SvLBox,0);
+
+ SvLBoxEntry* pEntry = NULL;
+ SvLBoxEntry* pParent = NULL;
+ for( ::std::deque< sal_Int32 >::const_iterator pItem = _rPath.begin(); pItem != _rPath.end(); ++pItem )
+ {
+ pEntry = GetEntry( pParent, *pItem );
+ if ( !pEntry )
+ break;
+ pParent = pEntry;
+ }
+
+ return pEntry;
+}
+
+void SvLBox::FillEntryPath( SvLBoxEntry* pEntry, ::std::deque< sal_Int32 >& _rPath ) const
+{
+ DBG_CHKTHIS(SvLBox,0);
+
+ if ( pEntry )
+ {
+ SvLBoxEntry* pParentEntry = GetParent( pEntry );
+ while ( TRUE )
+ {
+ ULONG i, nCount = GetLevelChildCount( pParentEntry );
+ for ( i = 0; i < nCount; ++i )
+ {
+ SvLBoxEntry* pTemp = GetEntry( pParentEntry, i );
+ DBG_ASSERT( pEntry, "invalid entry" );
+ if ( pEntry == pTemp )
+ {
+ _rPath.push_front( (sal_Int32)i );
+ break;
+ }
+ }
+
+ if ( pParentEntry )
+ {
+ pEntry = pParentEntry;
+ pParentEntry = GetParent( pParentEntry );
+ }
+ else
+ break;
+ }
+ }
+}
+
+String SvLBox::GetEntryText( SvLBoxEntry* ) const
+{
+ DBG_CHKTHIS(SvLBox,0);
+
+ return String();
+}
+
+ULONG SvLBox::GetLevelChildCount( SvLBoxEntry* _pParent ) const
+{
+ DBG_CHKTHIS(SvLBox,0);
+
+ ULONG nCount = 0;
+ SvLBoxEntry* pEntry = FirstChild( _pParent );
+ while ( pEntry )
+ {
+ ++nCount;
+ pEntry = NextSibling( pEntry );
+ }
+
+ return nCount;
+}
+
+void SvLBox::SetSelectionMode( SelectionMode eSelectMode )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ eSelMode = eSelectMode;
+}
+
+void SvLBox::SetDragDropMode( DragDropMode nDDMode )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ nDragDropMode = nDDMode;
+}
+
+SvViewData* SvLBox::CreateViewData( SvListEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ SvViewDataEntry* pEntryData = new SvViewDataEntry;
+ return (SvViewData*)pEntryData;
+}
+
+void SvLBox::InitViewData( SvViewData* pData, SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ SvLBoxEntry* pInhEntry = (SvLBoxEntry*)pEntry;
+ SvViewDataEntry* pEntryData = (SvViewDataEntry*)pData;
+
+ pEntryData->pItemData = new SvViewDataItem[ pInhEntry->ItemCount() ];
+ SvViewDataItem* pItemData = pEntryData->pItemData;
+ pEntryData->nItmCnt = pInhEntry->ItemCount(); // Anzahl Items fuer delete
+ USHORT nCount = pInhEntry->ItemCount();
+ USHORT nCurPos = 0;
+ while( nCurPos < nCount )
+ {
+ SvLBoxItem* pItem = pInhEntry->GetItem( nCurPos );
+ pItem->InitViewData( this, pInhEntry, pItemData );
+ pItemData++;
+ nCurPos++;
+ }
+}
+
+
+
+void SvLBox::EnableSelectionAsDropTarget( BOOL bEnable, BOOL bWithChilds )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ USHORT nRefDepth;
+ SvLBoxEntry* pTemp;
+
+ SvLBoxEntry* pSelEntry = FirstSelected();
+ while( pSelEntry )
+ {
+ if ( !bEnable )
+ {
+ pSelEntry->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
+ if ( bWithChilds )
+ {
+ nRefDepth = pModel->GetDepth( pSelEntry );
+ pTemp = Next( pSelEntry );
+ while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
+ {
+ pTemp->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
+ pTemp = Next( pTemp );
+ }
+ }
+ }
+ else
+ {
+ pSelEntry->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
+ if ( bWithChilds )
+ {
+ nRefDepth = pModel->GetDepth( pSelEntry );
+ pTemp = Next( pSelEntry );
+ while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
+ {
+ pTemp->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
+ pTemp = Next( pTemp );
+ }
+ }
+ }
+ pSelEntry = NextSelected( pSelEntry );
+ }
+}
+
+SvLBoxEntry* SvLBox::GetDropTarget( const Point& )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return 0;
+}
+
+// ******************************************************************
+// InplaceEditing
+// ******************************************************************
+
+void SvLBox::EditText( const String& rStr, const Rectangle& rRect,
+ const Selection& rSel )
+{
+ EditText( rStr, rRect, rSel, FALSE );
+}
+
+void SvLBox::EditText( const String& rStr, const Rectangle& rRect,
+ const Selection& rSel, BOOL bMulti )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ if( pEdCtrl )
+ delete pEdCtrl;
+ nImpFlags |= SVLBOX_IN_EDT;
+ nImpFlags &= ~SVLBOX_EDTEND_CALLED;
+ HideFocus();
+ pEdCtrl = new SvInplaceEdit2(
+ this, rRect.TopLeft(), rRect.GetSize(), rStr,
+ LINK( this, SvLBox, TextEditEndedHdl_Impl ),
+ rSel, bMulti );
+}
+
+IMPL_LINK( SvLBox, TextEditEndedHdl_Impl, SvInplaceEdit2 *, EMPTYARG )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ if ( nImpFlags & SVLBOX_EDTEND_CALLED ) // Nesting verhindern
+ return 0;
+ nImpFlags |= SVLBOX_EDTEND_CALLED;
+ String aStr;
+ if ( !pEdCtrl->EditingCanceled() )
+ aStr = pEdCtrl->GetText();
+ else
+ aStr = pEdCtrl->GetSavedValue();
+ if ( IsEmptyTextAllowed() || aStr.Len() > 0 )
+ EditedText( aStr );
+ // Hide darf erst gerufen werden, nachdem der neue Text in den
+ // Entry gesetzt wurde, damit im GetFocus der ListBox nicht
+ // der Selecthandler mit dem alten EntryText gerufen wird.
+ pEdCtrl->Hide();
+ // delete pEdCtrl;
+ // pEdCtrl = 0;
+ nImpFlags &= (~SVLBOX_IN_EDT);
+ GrabFocus();
+ return 0;
+}
+
+void SvLBox::CancelTextEditing()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ if ( pEdCtrl )
+ pEdCtrl->StopEditing( TRUE );
+ nImpFlags &= (~SVLBOX_IN_EDT);
+}
+
+void SvLBox::EndEditing( BOOL bCancel )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ if( pEdCtrl )
+ pEdCtrl->StopEditing( bCancel );
+ nImpFlags &= (~SVLBOX_IN_EDT);
+}
+
+
+bool SvLBox::IsEmptyTextAllowed() const
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return pLBoxImpl->m_bIsEmptyTextAllowed;
+}
+
+void SvLBox::ForbidEmptyText()
+{
+ DBG_CHKTHIS(SvLBox,0);
+ pLBoxImpl->m_bIsEmptyTextAllowed = false;
+}
+
+void SvLBox::EditedText( const String& )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+void SvLBox::EditingRequest( SvLBoxEntry*, SvLBoxItem*,const Point& )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+
+SvLBoxEntry* SvLBox::CreateEntry() const
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return new SvLBoxEntry;
+}
+
+void SvLBox::MakeVisible( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+void SvLBox::Command( const CommandEvent& i_rCommandEvent )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ Control::Command( i_rCommandEvent );
+}
+
+void SvLBox::KeyInput( const KeyEvent& rKEvt )
+{
+ bool bHandled = HandleKeyInput( rKEvt );
+ if ( !bHandled )
+ Control::KeyInput( rKEvt );
+}
+
+const void* SvLBox::FirstSearchEntry( String& _rEntryText )
+{
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if ( pEntry )
+ pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( NextSearchEntry( pEntry, _rEntryText ) ) );
+ else
+ {
+ if ( !pEntry )
+ pEntry = FirstSelected();
+ if ( !pEntry )
+ pEntry = First();
+ }
+
+ if ( pEntry )
+ _rEntryText = GetEntryText( pEntry );
+
+ return pEntry;
+}
+
+const void* SvLBox::NextSearchEntry( const void* _pCurrentSearchEntry, String& _rEntryText )
+{
+ SvLBoxEntry* pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( _pCurrentSearchEntry ) );
+
+ pEntry = Next( pEntry );
+ if ( !pEntry )
+ pEntry = First();
+
+ if ( pEntry )
+ _rEntryText = GetEntryText( pEntry );
+
+ return pEntry;
+}
+
+void SvLBox::SelectSearchEntry( const void* _pEntry )
+{
+ SvLBoxEntry* pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( _pEntry ) );
+ DBG_ASSERT( pEntry, "SvLBox::SelectSearchEntry: invalid entry!" );
+ if ( pEntry )
+ return;
+
+ SelectAll( FALSE );
+ SetCurEntry( pEntry );
+ Select( pEntry );
+}
+
+void SvLBox::ExecuteSearchEntry( const void* /*_pEntry*/ )
+{
+ // nothing to do here, we have no "execution"
+}
+
+bool SvLBox::HandleKeyInput( const KeyEvent& _rKEvt )
+{
+ if ( !IsEntryMnemonicsEnabled() )
+ return false;
+
+ return pLBoxImpl->m_aMnemonicEngine.HandleKeyEvent( _rKEvt );
+}
+
+SvLBoxEntry* SvLBox::GetEntry( const Point&, BOOL ) const
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return 0;
+}
+
+void SvLBox::ModelHasEntryInvalidated( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ USHORT nCount = ((SvLBoxEntry*)pEntry)->ItemCount();
+ for( USHORT nIdx = 0; nIdx < nCount; nIdx++ )
+ {
+ SvLBoxItem* pItem = ((SvLBoxEntry*)pEntry)->GetItem( nIdx );
+ pItem->InitViewData( this, (SvLBoxEntry*)pEntry, 0 );
+ }
+}
+
+void SvLBox::SetInUseEmphasis( SvLBoxEntry* pEntry, BOOL bInUse )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry");
+ if( bInUse )
+ {
+ if( !pEntry->HasInUseEmphasis() )
+ {
+ pEntry->nEntryFlags |= SV_ENTRYFLAG_IN_USE;
+ pModel->InvalidateEntry( pEntry );
+ }
+ }
+ else
+ {
+ if( pEntry->HasInUseEmphasis() )
+ {
+ pEntry->nEntryFlags &= (~SV_ENTRYFLAG_IN_USE);
+ pModel->InvalidateEntry( pEntry );
+ }
+ }
+}
+
+void SvLBox::SetCursorEmphasis( SvLBoxEntry* pEntry, BOOL bCursored )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry");
+ SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
+ if( pViewData && (bCursored != pViewData->IsCursored()) )
+ {
+ pViewData->SetCursored( bCursored );
+ // paintet in allen Views
+ // pModel->InvalidateEntry( pEntry );
+ // invalidiert nur in dieser View
+ ModelHasEntryInvalidated( pEntry );
+ }
+}
+
+BOOL SvLBox::HasCursorEmphasis( SvLBoxEntry* pEntry ) const
+{
+ DBG_CHKTHIS(SvLBox,0);
+ DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry");
+ SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
+ DBG_ASSERT(pViewData,"Entry not in View");
+ return pViewData->IsCursored();
+}
+
+void SvLBox::WriteDragServerInfo( const Point&, SvLBoxDDInfo* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+void SvLBox::ReadDragServerInfo(const Point&, SvLBoxDDInfo* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+}
+
+BOOL SvLBox::EditingCanceled() const
+{
+ if( pEdCtrl && pEdCtrl->EditingCanceled() )
+ return TRUE;
+ return FALSE;
+}
+
+
+//JP 28.3.2001: new Drag & Drop API
+sal_Int8 SvLBox::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ if( rEvt.mbLeaving || !CheckDragAndDropMode( pDDSource, rEvt.mnAction ) )
+ {
+ ImplShowTargetEmphasis( pTargetEntry, FALSE );
+ }
+ else if( !nDragDropMode )
+ {
+ DBG_ERRORFILE( "SvLBox::QueryDrop(): no target" );
+ }
+ else
+ {
+ SvLBoxEntry* pEntry = GetDropTarget( rEvt.maPosPixel );
+ if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX ) )
+ {
+ DBG_ERRORFILE( "SvLBox::QueryDrop(): no format" );
+ }
+ else
+ {
+ DBG_ASSERT( pDDSource, "SvLBox::QueryDrop(): SourceBox == 0 (__EXPORT?)" );
+ if( !( pEntry && pDDSource->GetModel() == this->GetModel()
+ && DND_ACTION_MOVE == rEvt.mnAction
+ && ( pEntry->nEntryFlags & SV_ENTRYFLAG_DISABLE_DROP ) ))
+ {
+ if( NotifyAcceptDrop( pEntry ))
+ nRet = rEvt.mnAction;
+ }
+ }
+
+ // **** Emphasis zeichnen ****
+ if( DND_ACTION_NONE == nRet )
+ ImplShowTargetEmphasis( pTargetEntry, FALSE );
+ else if( pEntry != pTargetEntry || !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
+ {
+ ImplShowTargetEmphasis( pTargetEntry, FALSE );
+ pTargetEntry = pEntry;
+ ImplShowTargetEmphasis( pTargetEntry, TRUE );
+ }
+ }
+ return nRet;
+}
+
+sal_Int8 SvLBox::ExecuteDrop( const ExecuteDropEvent& rEvt, SvLBox* pSourceView )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ DBG_ASSERT( pSourceView, "SvLBox::ExecuteDrop(): no source view" );
+ pSourceView->EnableSelectionAsDropTarget( TRUE, TRUE );
+
+ ImplShowTargetEmphasis( pTargetEntry, FALSE );
+ pDDTarget = this;
+
+ SvLBoxDDInfo aDDInfo;
+
+ TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
+ if( aData.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX ))
+ {
+ ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
+ if( aData.GetSequence( SOT_FORMATSTR_ID_TREELISTBOX, aSeq ) &&
+ sizeof(SvLBoxDDInfo) == aSeq.getLength() )
+ {
+ memcpy( &aDDInfo, aSeq.getConstArray(), sizeof(SvLBoxDDInfo) );
+ nRet = rEvt.mnAction;
+ }
+ }
+
+ if( DND_ACTION_NONE != nRet )
+ {
+ nRet = DND_ACTION_NONE;
+
+ ReadDragServerInfo( rEvt.maPosPixel, &aDDInfo );
+
+ SvLBoxEntry* pTarget = pTargetEntry; // !!! kann 0 sein !!!
+
+ if( DND_ACTION_COPY == rEvt.mnAction )
+ {
+ if ( CopySelection( aDDInfo.pSource, pTarget ) )
+ nRet = rEvt.mnAction;
+ }
+ else if( DND_ACTION_MOVE == rEvt.mnAction )
+ {
+ if ( MoveSelection( aDDInfo.pSource, pTarget ) )
+ nRet = rEvt.mnAction;
+ }
+ else if( DND_ACTION_COPYMOVE == rEvt.mnAction )
+ {
+ if ( MoveSelectionCopyFallbackPossible( aDDInfo.pSource, pTarget, sal_True ) )
+ nRet = rEvt.mnAction;
+ }
+ }
+ return nRet;
+}
+
+sal_Int8 SvLBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return ExecuteDrop( rEvt, GetSourceView() );
+}
+
+void SvLBox::StartDrag( sal_Int8, const Point& rPosPixel )
+{
+ DBG_CHKTHIS(SvLBox,0);
+
+ nOldDragMode = GetDragDropMode();
+ if ( !nOldDragMode )
+ return;
+
+ ReleaseMouse();
+
+ SvLBoxEntry* pEntry = GetEntry( rPosPixel ); // GetDropTarget( rPos );
+ if( !pEntry )
+ {
+ DragFinished( DND_ACTION_NONE );
+ return;
+ }
+
+ TransferDataContainer* pContainer = new TransferDataContainer;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable > xRef( pContainer );
+
+ nDragDropMode = NotifyStartDrag( *pContainer, pEntry );
+ if( !nDragDropMode || 0 == GetSelectionCount() )
+ {
+ nDragDropMode = nOldDragMode;
+ DragFinished( DND_ACTION_NONE );
+ return;
+ }
+
+ SvLBoxDDInfo aDDInfo;
+ memset(&aDDInfo,0,sizeof(SvLBoxDDInfo));
+ aDDInfo.pApp = GetpApp();
+ aDDInfo.pSource = this;
+ aDDInfo.pDDStartEntry = pEntry;
+ // abgeleitete Views zum Zuge kommen lassen
+ WriteDragServerInfo( rPosPixel, &aDDInfo );
+
+ pContainer->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX,
+ (sal_Char*)&aDDInfo, sizeof(SvLBoxDDInfo) );
+ pDDSource = this;
+ pDDTarget = 0;
+
+ BOOL bOldUpdateMode = Control::IsUpdateMode();
+ Control::SetUpdateMode( TRUE );
+ Update();
+ Control::SetUpdateMode( bOldUpdateMode );
+
+ // Selektion & deren Childs im Model als DropTargets sperren
+ // Wichtig: Wenn im DropHandler die Selektion der
+ // SourceListBox veraendert wird, muessen vorher die Eintraege
+ // als DropTargets wieder freigeschaltet werden:
+ // (GetSourceListBox()->EnableSelectionAsDropTarget( TRUE, TRUE );)
+ EnableSelectionAsDropTarget( FALSE, TRUE /* with Childs */ );
+
+ pContainer->StartDrag( this, nDragOptions, GetDragFinishedHdl() );
+}
+
+void SvLBox::DragFinished( sal_Int8
+#ifndef UNX
+nAction
+#endif
+)
+{
+ EnableSelectionAsDropTarget( TRUE, TRUE );
+
+#ifndef UNX
+ if( (nAction == DND_ACTION_MOVE) && ( (pDDTarget &&
+ ((ULONG)(pDDTarget->GetModel())!=(ULONG)(this->GetModel()))) ||
+ !pDDTarget ))
+ {
+ RemoveSelection();
+ }
+#endif
+
+ ImplShowTargetEmphasis( pTargetEntry, FALSE );
+ pDDSource = 0;
+ pDDTarget = 0;
+ pTargetEntry = 0;
+ nDragDropMode = nOldDragMode;
+}
+
+DragDropMode SvLBox::NotifyStartDrag( TransferDataContainer&, SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return (DragDropMode)0xffff;
+}
+
+BOOL SvLBox::NotifyAcceptDrop( SvLBoxEntry* )
+{
+ DBG_CHKTHIS(SvLBox,0);
+ return TRUE;
+}
+
+// handler and methods for Drag - finished handler.
+// The with get GetDragFinishedHdl() get link can set on the
+// TransferDataContainer. This link is a callback for the DragFinished
+// call. AddBox method is called from the GetDragFinishedHdl() and the
+// remove is called in link callback and in the destructor. So it can't
+// called to a deleted object.
+
+namespace
+{
+ struct SortLBoxes : public rtl::Static<SvULongsSort, SortLBoxes> {};
+}
+
+void SvLBox::AddBoxToDDList_Impl( const SvLBox& rB )
+{
+ ULONG nVal = (ULONG)&rB;
+ SortLBoxes::get().Insert( nVal );
+}
+
+void SvLBox::RemoveBoxFromDDList_Impl( const SvLBox& rB )
+{
+ ULONG nVal = (ULONG)&rB;
+ SortLBoxes::get().Remove( nVal );
+}
+
+IMPL_STATIC_LINK( SvLBox, DragFinishHdl_Impl, sal_Int8*, pAction )
+{
+ ULONG nVal = (ULONG)pThis;
+ USHORT nFnd;
+ SvULongsSort &rSortLBoxes = SortLBoxes::get();
+ if( rSortLBoxes.Seek_Entry( nVal, &nFnd ) )
+ {
+ pThis->DragFinished( *pAction );
+ rSortLBoxes.Remove( nFnd, 1 );
+ }
+ return 0;
+}
+
+Link SvLBox::GetDragFinishedHdl() const
+{
+ AddBoxToDDList_Impl( *this );
+ return STATIC_LINK( this, SvLBox, DragFinishHdl_Impl );
+}
+
+void SvLBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& ) const
+{
+}
+
+::com::sun::star::uno::Reference< XAccessible > SvLBox::CreateAccessible()
+{
+ return ::com::sun::star::uno::Reference< XAccessible >();
+}
+
+Rectangle SvLBox::GetBoundingRect( SvLBoxEntry* )
+{
+ return Rectangle();
+}
+
diff --git a/svtools/source/contnr/svtabbx.cxx b/svtools/source/contnr/svtabbx.cxx
new file mode 100644
index 000000000000..53fbded59f11
--- /dev/null
+++ b/svtools/source/contnr/svtabbx.cxx
@@ -0,0 +1,1304 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/svtabbx.hxx>
+#include <svtools/headbar.hxx>
+#include <svtools/svtdata.hxx>
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#ifndef SVTOOLS_ACCESSIBLE_FACTORY_HXX
+#include "svtaccessiblefactory.hxx"
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::accessibility;
+
+#define MYTABMASK \
+ ( SV_LBOXTAB_ADJUST_RIGHT | SV_LBOXTAB_ADJUST_LEFT | SV_LBOXTAB_ADJUST_CENTER | SV_LBOXTAB_ADJUST_NUMERIC )
+
+// SvTreeListBox-Callback
+
+void SvTabListBox::SetTabs()
+{
+ SvTreeListBox::SetTabs();
+ if( nTabCount )
+ {
+ DBG_ASSERT(pTabList,"TabList ?");
+
+ // die TreeListBox hat jetzt ihre Tabulatoren in die Liste eingefuegt.
+ // jetzt plustern wir die Liste mit zusaetzlichen Tabulatoren auf,
+ // und passen den ganz rechten Tab der Treelistbox an.
+
+ // den ganz rechten Tab nehmen
+ // HACK fuer den Explorer! Wenn der ViewParent != 0 ist, dann wird
+ // der erste Tab der TreeListBox von der TreelistBox berechnet!
+ // Dies wird fuer ButtonsOnRoot benoetigt, da der Explorer nicht
+ // weiss, welchen zusaetzlichen Offset er in diesem Modus auf
+ // den Tabulator addieren muss. Die TreeListBox weiss es!
+ /*
+ if( !pViewParent )
+ {
+ SvLBoxTab* pFirstTab = (SvLBoxTab*)aTabs.GetObject( aTabs.Count()-1 );
+ pFirstTab->SetPos( pTabList[0].GetPos() );
+ pFirstTab->nFlags &= ~MYTABMASK;
+ pFirstTab->nFlags |= pTabList[0].nFlags;
+ }
+ */
+
+ // alle anderen Tabs an Liste haengen
+ for( USHORT nCurTab = 1; nCurTab < nTabCount; nCurTab++ )
+ {
+ SvLBoxTab* pTab = pTabList+nCurTab;
+ AddTab( pTab->GetPos(), pTab->nFlags );
+ }
+ }
+}
+
+void SvTabListBox::InitEntry( SvLBoxEntry* pEntry, const XubString& rStr,
+ const Image& rColl, const Image& rExp, SvLBoxButtonKind eButtonKind )
+{
+ SvTreeListBox::InitEntry( pEntry, rStr, rColl, rExp, eButtonKind );
+ XubString aToken;
+
+ const xub_Unicode* pCurToken = aCurEntry.GetBuffer();
+ USHORT nCurTokenLen;
+ const xub_Unicode* pNextToken = GetToken( pCurToken, nCurTokenLen );
+ USHORT nCount = nTabCount; nCount--;
+ for( USHORT nToken = 0; nToken < nCount; nToken++ )
+ {
+ if( pCurToken && nCurTokenLen )
+ // aToken.Assign( pCurToken, nCurTokenLen );
+ aToken = XubString( pCurToken, nCurTokenLen );
+ else
+ aToken.Erase();
+ SvLBoxString* pStr = new SvLBoxString( pEntry, 0, aToken );
+ pEntry->AddItem( pStr );
+ pCurToken = pNextToken;
+ if( pCurToken )
+ pNextToken = GetToken( pCurToken, nCurTokenLen );
+ else
+ nCurTokenLen = 0;
+ }
+}
+
+
+SvTabListBox::SvTabListBox( Window* pParent, WinBits nBits )
+ : SvTreeListBox( pParent, nBits )
+{
+ pTabList = 0;
+ nTabCount = 0;
+ pViewParent = 0;
+ SetHighlightRange(); // ueber volle Breite selektieren
+}
+
+SvTabListBox::SvTabListBox( Window* pParent, const ResId& rResId )
+ : SvTreeListBox( pParent, rResId )
+{
+ pTabList = 0;
+ nTabCount = 0;
+ pViewParent = 0;
+ SvTabListBox::Resize();
+ SetHighlightRange();
+}
+
+SvTabListBox::~SvTabListBox()
+{
+ // array-delete
+ delete [] pTabList;
+#ifdef DBG_UTIL
+ pTabList = 0;
+ nTabCount = 0;
+#endif
+}
+
+void SvTabListBox::SetTabs( long* pTabs, MapUnit eMapUnit )
+{
+ DBG_ASSERT(pTabs,"SetTabs:NULL-Ptr");
+ if( !pTabs )
+ return;
+
+ delete [] pTabList;
+ USHORT nCount = (USHORT)(*pTabs);
+ pTabList = new SvLBoxTab[ nCount ];
+ nTabCount = nCount;
+
+ MapMode aMMSource( eMapUnit );
+ MapMode aMMDest( MAP_PIXEL );
+
+ pTabs++;
+ for( USHORT nIdx = 0; nIdx < nCount; nIdx++, pTabs++ )
+ {
+ Size aSize( *pTabs, 0 );
+ aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
+ long nNewTab = aSize.Width();
+ pTabList[nIdx].SetPos( nNewTab );
+ pTabList[nIdx].nFlags=(SV_LBOXTAB_ADJUST_LEFT| SV_LBOXTAB_INV_ALWAYS);
+ }
+ SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
+ if( IsUpdateMode() )
+ Invalidate();
+}
+
+void SvTabListBox::SetTab( USHORT nTab,long nValue,MapUnit eMapUnit )
+{
+ DBG_ASSERT(nTab<nTabCount,"Invalid Tab-Pos");
+ if( nTab < nTabCount )
+ {
+ DBG_ASSERT(pTabList,"TabList?");
+ MapMode aMMSource( eMapUnit );
+ MapMode aMMDest( MAP_PIXEL );
+ Size aSize( nValue, 0 );
+ aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
+ nValue = aSize.Width();
+ pTabList[ nTab ].SetPos( nValue );
+ SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
+ if( IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+SvLBoxEntry* SvTabListBox::InsertEntry( const XubString& rText, SvLBoxEntry* pParent,
+ BOOL /*bChildsOnDemand*/,
+ ULONG nPos, void* pUserData,
+ SvLBoxButtonKind )
+{
+ return InsertEntryToColumn( rText, pParent, nPos, 0xffff, pUserData );
+}
+
+SvLBoxEntry* SvTabListBox::InsertEntry( const XubString& rText,
+ const Image& rExpandedEntryBmp,
+ const Image& rCollapsedEntryBmp,
+ SvLBoxEntry* pParent,
+ BOOL /*bChildsOnDemand*/,
+ ULONG nPos, void* pUserData,
+ SvLBoxButtonKind )
+{
+ return InsertEntryToColumn( rText, rExpandedEntryBmp, rCollapsedEntryBmp,
+ pParent, nPos, 0xffff, pUserData );
+}
+
+SvLBoxEntry* SvTabListBox::InsertEntryToColumn(const XubString& rStr,SvLBoxEntry* pParent,ULONG nPos,USHORT nCol,
+ void* pUser )
+{
+ XubString aStr;
+ if( nCol != 0xffff )
+ {
+ while( nCol )
+ {
+ aStr += '\t';
+ nCol--;
+ }
+ }
+ aStr += rStr;
+ XubString aFirstStr( aStr );
+ USHORT nEnd = aFirstStr.Search( '\t' );
+ if( nEnd != STRING_NOTFOUND )
+ {
+ aFirstStr.Erase( nEnd );
+ aCurEntry = aStr;
+ aCurEntry.Erase( 0, ++nEnd );
+ }
+ else
+ aCurEntry.Erase();
+ return SvTreeListBox::InsertEntry( aFirstStr, pParent, FALSE, nPos, pUser );
+}
+
+SvLBoxEntry* SvTabListBox::InsertEntryToColumn( const XubString& rStr,
+ const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
+ SvLBoxEntry* pParent,ULONG nPos,USHORT nCol, void* pUser )
+{
+ XubString aStr;
+ if( nCol != 0xffff )
+ {
+ while( nCol )
+ {
+ aStr += '\t';
+ nCol--;
+ }
+ }
+ aStr += rStr;
+ XubString aFirstStr( aStr );
+ USHORT nEnd = aFirstStr.Search( '\t' );
+ if( nEnd != STRING_NOTFOUND )
+ {
+ aFirstStr.Erase( nEnd );
+ aCurEntry = aStr;
+ aCurEntry.Erase( 0, ++nEnd );
+ }
+ else
+ aCurEntry.Erase();
+
+ return SvTreeListBox::InsertEntry(
+ aFirstStr,
+ rExpandedEntryBmp, rCollapsedEntryBmp,
+ pParent, FALSE, nPos, pUser );
+}
+
+SvLBoxEntry* SvTabListBox::InsertEntryToColumn( const XubString& rStr, ULONG nPos,
+ USHORT nCol, void* pUser )
+{
+ return InsertEntryToColumn( rStr,0,nPos, nCol, pUser );
+}
+
+String SvTabListBox::GetEntryText( SvLBoxEntry* pEntry ) const
+{
+ return GetEntryText( pEntry, 0xffff );
+}
+
+String SvTabListBox::GetEntryText( SvLBoxEntry* pEntry, USHORT nCol ) const
+{
+ DBG_ASSERT(pEntry,"GetEntryText:Invalid Entry");
+ XubString aResult;
+ if( pEntry )
+ {
+ USHORT nCount = pEntry->ItemCount();
+ USHORT nCur = 0;
+ while( nCur < nCount )
+ {
+ SvLBoxItem* pStr = pEntry->GetItem( nCur );
+ if( pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ if( nCol == 0xffff )
+ {
+ if( aResult.Len() )
+ aResult += '\t';
+ aResult += static_cast<SvLBoxString*>( pStr )->GetText();
+ }
+ else
+ {
+ if( nCol == 0 )
+ return static_cast<SvLBoxString*>( pStr )->GetText();
+ nCol--;
+ }
+ }
+ nCur++;
+ }
+ }
+ return aResult;
+}
+
+String SvTabListBox::GetEntryText( ULONG nPos, USHORT nCol ) const
+{
+ SvLBoxEntry* pEntry = GetEntryOnPos( nPos );
+ return GetEntryText( pEntry, nCol );
+}
+
+void SvTabListBox::SetEntryText( const XubString& rStr, ULONG nPos, USHORT nCol )
+{
+ SvLBoxEntry* pEntry = SvTreeListBox::GetEntry( nPos );
+ SetEntryText( rStr, pEntry, nCol );
+}
+
+void SvTabListBox::SetEntryText( const XubString& rStr, SvLBoxEntry* pEntry, USHORT nCol )
+{
+ DBG_ASSERT(pEntry,"SetEntryText:Invalid Entry");
+ if( !pEntry )
+ return;
+
+ String sOldText = GetEntryText( pEntry, nCol );
+ if ( sOldText == rStr )
+ return;
+
+ USHORT nTextColumn = nCol;
+ const xub_Unicode* pCurToken = rStr.GetBuffer();
+ USHORT nCurTokenLen;
+ const xub_Unicode* pNextToken = GetToken( pCurToken, nCurTokenLen );
+
+ XubString aTemp;
+ USHORT nCount = pEntry->ItemCount();
+ USHORT nCur = 0;
+ while( nCur < nCount )
+ {
+ SvLBoxItem* pStr = pEntry->GetItem( nCur );
+ if( pStr && pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ if( nCol == 0xffff )
+ {
+ if( pCurToken )
+ aTemp = XubString( pCurToken, nCurTokenLen );
+ else
+ aTemp.Erase(); // alle Spalten ohne Token loeschen
+ ((SvLBoxString*)pStr)->SetText( pEntry, aTemp );
+ pCurToken = pNextToken;
+ pNextToken = GetToken( pCurToken, nCurTokenLen );
+ }
+ else
+ {
+ if( !nCol )
+ {
+ aTemp = XubString( pCurToken, nCurTokenLen );
+ ((SvLBoxString*)pStr)->SetText( pEntry, aTemp );
+ if( !pNextToken )
+ break;
+ pCurToken = pNextToken;
+ pNextToken = GetToken( pCurToken, nCurTokenLen );
+ }
+ else
+ nCol--;
+ }
+ }
+ nCur++;
+ }
+ GetModel()->InvalidateEntry( pEntry );
+
+ TabListBoxEventData* pData = new TabListBoxEventData( pEntry, nTextColumn, sOldText );
+ ImplCallEventListeners( VCLEVENT_TABLECELL_NAMECHANGED, pData );
+ delete pData;
+}
+
+String SvTabListBox::GetCellText( ULONG nPos, USHORT nCol ) const
+{
+ SvLBoxEntry* pEntry = GetEntryOnPos( nPos );
+ DBG_ASSERT( pEntry, "SvTabListBox::GetCellText(): Invalid Entry" );
+ XubString aResult;
+ if ( pEntry && pEntry->ItemCount() > ( nCol + 1 ) )
+ {
+ SvLBoxItem* pStr = pEntry->GetItem( nCol + 1 );
+ if ( pStr && pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
+ aResult = static_cast< SvLBoxString* >( pStr )->GetText();
+ }
+ return aResult;
+}
+
+ULONG SvTabListBox::GetEntryPos( const XubString& rStr, USHORT nCol )
+{
+ ULONG nPos = 0;
+ SvLBoxEntry* pEntry = First();
+ while( pEntry )
+ {
+ XubString aStr( GetEntryText( pEntry, nCol ));
+ if( aStr == rStr )
+ return nPos;
+ pEntry = Next( pEntry );
+ nPos++;
+ }
+ return 0xffffffff;
+}
+
+ULONG SvTabListBox::GetEntryPos( const SvLBoxEntry* pEntry ) const
+{
+ ULONG nPos = 0;
+ SvLBoxEntry* pTmpEntry = First();
+ while( pTmpEntry )
+ {
+ if ( pTmpEntry == pEntry )
+ return nPos;
+ pTmpEntry = Next( pTmpEntry );
+ ++nPos;
+ }
+ return 0xffffffff;
+}
+
+void __EXPORT SvTabListBox::Resize()
+{
+ SvTreeListBox::Resize();
+}
+
+// static
+const xub_Unicode* SvTabListBox::GetToken( const xub_Unicode* pPtr, USHORT& rLen )
+{
+ if( !pPtr || *pPtr == 0 )
+ {
+ rLen = 0;
+ return 0;
+ }
+ xub_Unicode c = *pPtr;
+ USHORT nLen = 0;
+ while( c != '\t' && c != 0 )
+ {
+ pPtr++;
+ nLen++;
+ c = *pPtr;
+ }
+ if( c )
+ pPtr++; // Tab ueberspringen
+ else
+ pPtr = 0;
+ rLen = nLen;
+ return pPtr;
+}
+
+String SvTabListBox::GetTabEntryText( ULONG nPos, USHORT nCol ) const
+{
+ SvLBoxEntry* pEntry = SvTreeListBox::GetEntry( nPos );
+ DBG_ASSERT( pEntry, "GetTabEntryText(): Invalid entry " );
+ XubString aResult;
+ if ( pEntry )
+ {
+ USHORT nCount = pEntry->ItemCount();
+ USHORT nCur = ( 0 == nCol && IsCellFocusEnabled() ) ? GetCurrentTabPos() : 0;
+ while( nCur < nCount )
+ {
+ SvLBoxItem* pStr = pEntry->GetItem( nCur );
+ if ( pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ if ( nCol == 0xffff )
+ {
+ if ( aResult.Len() )
+ aResult += '\t';
+ aResult += static_cast<SvLBoxString*>( pStr )->GetText();
+ }
+ else
+ {
+ if ( nCol == 0 )
+ {
+ String sRet = static_cast<SvLBoxString*>( pStr )->GetText();
+ if ( sRet.Len() == 0 )
+ sRet = String( SvtResId( STR_SVT_ACC_EMPTY_FIELD ) );
+ return sRet;
+ }
+ --nCol;
+ }
+ }
+ ++nCur;
+ }
+ }
+ return aResult;
+}
+
+SvLBoxEntry* SvTabListBox::GetEntryOnPos( ULONG _nEntryPos ) const
+{
+ SvLBoxEntry* pEntry = NULL;
+ ULONG i, nPos = 0, nCount = GetLevelChildCount( NULL );
+ for ( i = 0; i < nCount; ++i )
+ {
+ SvLBoxEntry* pParent = GetEntry(i);
+ if ( nPos == _nEntryPos )
+ {
+ pEntry = pParent;
+ break;
+ }
+ else
+ {
+ nPos++;
+ pEntry = GetChildOnPos( pParent, _nEntryPos, nPos );
+ if ( pEntry )
+ break;
+ }
+ }
+
+ return pEntry;
+}
+
+SvLBoxEntry* SvTabListBox::GetChildOnPos( SvLBoxEntry* _pParent, ULONG _nEntryPos, ULONG& _rPos ) const
+{
+ ULONG i, nCount = GetLevelChildCount( _pParent );
+ for ( i = 0; i < nCount; ++i )
+ {
+ SvLBoxEntry* pParent = GetEntry( _pParent, i );
+ if ( _rPos == _nEntryPos )
+ return pParent;
+ else
+ {
+ _rPos++;
+ SvLBoxEntry* pEntry = GetChildOnPos( pParent, _nEntryPos, _rPos );
+ if ( pEntry )
+ return pEntry;
+ }
+ }
+
+ return NULL;
+}
+
+void SvTabListBox::SetTabJustify( USHORT nTab, SvTabJustify eJustify)
+{
+ if( nTab >= nTabCount )
+ return;
+ SvLBoxTab* pTab = &(pTabList[ nTab ]);
+ USHORT nFlags = pTab->nFlags;
+ nFlags &= (~MYTABMASK);
+ nFlags |= (USHORT)eJustify;
+ pTab->nFlags = nFlags;
+ SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
+ if( IsUpdateMode() )
+ Invalidate();
+}
+
+SvTabJustify SvTabListBox::GetTabJustify( USHORT nTab ) const
+{
+ SvTabJustify eResult = AdjustLeft;
+ if( nTab >= nTabCount )
+ return eResult;
+ SvLBoxTab* pTab = &(pTabList[ nTab ]);
+ USHORT nFlags = pTab->nFlags;
+ nFlags &= MYTABMASK;
+ eResult = (SvTabJustify)nFlags;
+ return eResult;
+}
+
+long SvTabListBox::GetLogicTab( USHORT nTab )
+{
+ if( SvTreeListBox::nTreeFlags & TREEFLAG_RECALCTABS )
+ ((SvTabListBox*)this)->SetTabs();
+
+ DBG_ASSERT(nTab<nTabCount,"GetTabPos:Invalid Tab");
+ return ((SvLBoxTab*)aTabs.GetObject( nTab ))->GetPos();
+}
+
+// class SvHeaderTabListBoxImpl ------------------------------------------
+
+namespace svt
+{
+ struct SvHeaderTabListBoxImpl
+ {
+ HeaderBar* m_pHeaderBar;
+ AccessibleFactoryAccess m_aFactoryAccess;
+
+ SvHeaderTabListBoxImpl() : m_pHeaderBar( NULL ) { }
+ };
+}
+
+// class SvHeaderTabListBox ----------------------------------------------
+
+SvHeaderTabListBox::SvHeaderTabListBox( Window* pParent, WinBits nWinStyle ) :
+
+ SvTabListBox( pParent, nWinStyle ),
+
+ m_bFirstPaint ( TRUE ),
+ m_pImpl ( new ::svt::SvHeaderTabListBoxImpl ),
+ m_pAccessible ( NULL )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvHeaderTabListBox::SvHeaderTabListBox( Window* pParent, const ResId& rResId ) :
+
+ SvTabListBox( pParent, rResId ),
+
+ m_bFirstPaint ( TRUE ),
+ m_pImpl ( new ::svt::SvHeaderTabListBoxImpl ),
+ m_pAccessible ( NULL )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvHeaderTabListBox::~SvHeaderTabListBox()
+{
+ delete m_pImpl;
+}
+
+// -----------------------------------------------------------------------
+
+void SvHeaderTabListBox::Paint( const Rectangle& rRect )
+{
+ if ( m_bFirstPaint )
+ {
+ m_bFirstPaint = FALSE;
+ RepaintScrollBars();
+ }
+ SvTabListBox::Paint( rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void SvHeaderTabListBox::InitHeaderBar( HeaderBar* pHeaderBar )
+{
+ DBG_ASSERT( !m_pImpl->m_pHeaderBar, "header bar already initialized" );
+ DBG_ASSERT( pHeaderBar, "invalid header bar initialization" );
+ m_pImpl->m_pHeaderBar = pHeaderBar;
+ SetScrolledHdl( LINK( this, SvHeaderTabListBox, ScrollHdl_Impl ) );
+ m_pImpl->m_pHeaderBar->SetCreateAccessibleHdl( LINK( this, SvHeaderTabListBox, CreateAccessibleHdl_Impl ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvHeaderTabListBox::IsItemChecked( SvLBoxEntry* pEntry, USHORT nCol ) const
+{
+ SvButtonState eState = SV_BUTTON_UNCHECKED;
+ SvLBoxButton* pItem = (SvLBoxButton*)( pEntry->GetItem( nCol + 1 ) );
+
+ if ( pItem && ( (SvLBoxItem*)pItem )->IsA() == SV_ITEM_ID_LBOXBUTTON )
+ {
+ USHORT nButtonFlags = pItem->GetButtonFlags();
+ eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
+ }
+
+ return ( eState == SV_BUTTON_CHECKED );
+}
+
+// -----------------------------------------------------------------------
+
+SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
+ const XubString& rStr, ULONG nPos, USHORT nCol, void* pUserData )
+{
+ SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, nPos, nCol, pUserData );
+ RecalculateAccessibleChildren();
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------
+
+SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
+ const XubString& rStr, SvLBoxEntry* pParent, ULONG nPos, USHORT nCol, void* pUserData )
+{
+ SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, pParent, nPos, nCol, pUserData );
+ RecalculateAccessibleChildren();
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------
+
+SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
+ const XubString& rStr, const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
+ SvLBoxEntry* pParent, ULONG nPos, USHORT nCol, void* pUserData )
+{
+ SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn(
+ rStr, rExpandedEntryBmp, rCollapsedEntryBmp, pParent, nPos, nCol, pUserData );
+ RecalculateAccessibleChildren();
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SvHeaderTabListBox::Insert(
+ SvLBoxEntry* pEnt, SvLBoxEntry* pPar, ULONG nPos )
+{
+ ULONG n = SvTabListBox::Insert( pEnt, pPar, nPos );
+ RecalculateAccessibleChildren();
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SvHeaderTabListBox::Insert( SvLBoxEntry* pEntry, ULONG nRootPos )
+{
+ ULONG nPos = SvTabListBox::Insert( pEntry, nRootPos );
+ RecalculateAccessibleChildren();
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void SvHeaderTabListBox::RemoveEntry( SvLBoxEntry* _pEntry )
+{
+ GetModel()->Remove( _pEntry );
+ m_aAccessibleChildren.clear();
+}
+
+// -----------------------------------------------------------------------
+
+void SvHeaderTabListBox::Clear()
+{
+ SvTabListBox::Clear();
+ m_aAccessibleChildren.clear();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( SvHeaderTabListBox, ScrollHdl_Impl, SvTabListBox*, EMPTYARG )
+{
+ m_pImpl->m_pHeaderBar->SetOffset( -GetXOffset() );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( SvHeaderTabListBox, CreateAccessibleHdl_Impl, HeaderBar*, EMPTYARG )
+{
+ Window* pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
+ DBG_ASSERT( pParent, "SvHeaderTabListBox..CreateAccessibleHdl_Impl - accessible parent not found" );
+ if ( pParent )
+ {
+ ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
+ if ( xAccParent.is() )
+ {
+ Reference< XAccessible > xAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderBar(
+ xAccParent, *this, ::svt::BBTYPE_COLUMNHEADERBAR );
+ m_pImpl->m_pHeaderBar->SetAccessible( xAccessible );
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SvHeaderTabListBox::RecalculateAccessibleChildren()
+{
+ if ( !m_aAccessibleChildren.empty() )
+ {
+ sal_uInt32 nCount = ( GetRowCount() + 1 ) * GetColumnCount();
+ if ( m_aAccessibleChildren.size() < nCount )
+ m_aAccessibleChildren.resize( nCount );
+ else
+ {
+ DBG_ASSERT( m_aAccessibleChildren.size() == nCount, "wrong children count" );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvHeaderTabListBox::IsCellCheckBox( long _nRow, sal_uInt16 _nColumn, TriState& _rState )
+{
+ sal_Bool bRet = sal_False;
+ SvLBoxEntry* pEntry = GetEntry( _nRow );
+ if ( pEntry )
+ {
+ USHORT nItemCount = pEntry->ItemCount();
+ if ( nItemCount > ( _nColumn + 1 ) )
+ {
+ SvLBoxButton* pItem = (SvLBoxButton*)( pEntry->GetItem( _nColumn + 1 ) );
+ if ( pItem && ( (SvLBoxItem*)pItem )->IsA() == SV_ITEM_ID_LBOXBUTTON )
+ {
+ bRet = sal_True;
+ _rState = ( ( pItem->GetButtonFlags() & SV_ITEMSTATE_UNCHECKED ) == 0 )
+ ? STATE_CHECK : STATE_NOCHECK;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "SvHeaderTabListBox::IsCellCheckBox(): column out of range" );
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+long SvHeaderTabListBox::GetRowCount() const
+{
+ return GetEntryCount();
+}
+// -----------------------------------------------------------------------
+sal_uInt16 SvHeaderTabListBox::GetColumnCount() const
+{
+ return m_pImpl->m_pHeaderBar->GetItemCount();
+}
+// -----------------------------------------------------------------------
+sal_Int32 SvHeaderTabListBox::GetCurrRow() const
+{
+ sal_Int32 nRet = -1;
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if ( pEntry )
+ {
+ ULONG nCount = GetEntryCount();
+ for ( ULONG i = 0; i < nCount; ++i )
+ {
+ if ( pEntry == GetEntry(i) )
+ {
+ nRet = i;
+ break;
+ }
+ }
+ }
+
+ return nRet;
+}
+// -----------------------------------------------------------------------
+sal_uInt16 SvHeaderTabListBox::GetCurrColumn() const
+{
+ sal_uInt16 nPos = GetCurrentTabPos() - 1;
+ return nPos;
+}
+// -----------------------------------------------------------------------
+::rtl::OUString SvHeaderTabListBox::GetRowDescription( sal_Int32 _nRow ) const
+{
+ return ::rtl::OUString( GetEntryText( _nRow ) );
+}
+// -----------------------------------------------------------------------
+::rtl::OUString SvHeaderTabListBox::GetColumnDescription( sal_uInt16 _nColumn ) const
+{
+ return ::rtl::OUString( m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) ) );
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::HasRowHeader() const
+{
+ return sal_False;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::IsCellFocusable() const
+{
+ return IsCellFocusEnabled();
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::GoToCell( sal_Int32 _nRow, sal_uInt16 _nColumn )
+{
+ sal_Bool bRet = ( IsCellFocusEnabled() == TRUE );
+ if ( bRet )
+ {
+ // first set cursor to _nRow
+ SetCursor( GetEntry( _nRow ), TRUE );
+ // then set the focus into _nColumn
+ bRet = ( SetCurrentTabPos( _nColumn ) == true );
+ }
+ return bRet;
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::SetNoSelection()
+{
+ SvLBox::SelectAll( FALSE );
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::SelectAll()
+{
+ SvLBox::SelectAll( TRUE );
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::SelectAll( BOOL bSelect, BOOL bPaint )
+{
+ // overwritten just to disambiguate the SelectAll() from the base' class SelectAll( BOOl, BOOL )
+ SvTabListBox::SelectAll( bSelect, bPaint );
+}
+
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::SelectRow( long _nRow, BOOL _bSelect, BOOL )
+{
+ Select( GetEntry( _nRow ), _bSelect );
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::SelectColumn( sal_uInt16, sal_Bool )
+{
+}
+// -----------------------------------------------------------------------
+sal_Int32 SvHeaderTabListBox::GetSelectedRowCount() const
+{
+ return GetSelectionCount();
+}
+// -----------------------------------------------------------------------
+sal_Int32 SvHeaderTabListBox::GetSelectedColumnCount() const
+{
+ return 0;
+}
+// -----------------------------------------------------------------------
+bool SvHeaderTabListBox::IsRowSelected( long _nRow ) const
+{
+ SvLBoxEntry* pEntry = GetEntry( _nRow );
+ return ( pEntry && IsSelected( pEntry ) );
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::IsColumnSelected( long ) const
+{
+ return FALSE;
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::GetAllSelectedRows( ::com::sun::star::uno::Sequence< sal_Int32 >& ) const
+{
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::GetAllSelectedColumns( ::com::sun::star::uno::Sequence< sal_Int32 >& ) const
+{
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::IsCellVisible( sal_Int32, sal_uInt16 ) const
+{
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+String SvHeaderTabListBox::GetAccessibleCellText( long _nRow, USHORT _nColumnPos ) const
+{
+ return ::rtl::OUString( GetTabEntryText( _nRow, _nColumnPos ) );
+}
+// -----------------------------------------------------------------------
+Rectangle SvHeaderTabListBox::calcHeaderRect( sal_Bool _bIsColumnBar, BOOL _bOnScreen )
+{
+ Rectangle aRect;
+ if ( _bIsColumnBar )
+ {
+ Window* pParent = NULL;
+ if ( !_bOnScreen )
+ pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
+
+ aRect = m_pImpl->m_pHeaderBar->GetWindowExtentsRelative( pParent );
+ }
+ return aRect;
+}
+// -----------------------------------------------------------------------
+Rectangle SvHeaderTabListBox::calcTableRect( BOOL _bOnScreen )
+{
+ Window* pParent = NULL;
+ if ( !_bOnScreen )
+ pParent = GetAccessibleParentWindow();
+
+ Rectangle aRect( GetWindowExtentsRelative( pParent ) );
+ return aRect;
+}
+// -----------------------------------------------------------------------
+Rectangle SvHeaderTabListBox::GetFieldRectPixelAbs( sal_Int32 _nRow, sal_uInt16 _nColumn, BOOL _bIsHeader, BOOL _bOnScreen )
+{
+ DBG_ASSERT( !_bIsHeader || 0 == _nRow, "invalid parameters" );
+ Rectangle aRect;
+ SvLBoxEntry* pEntry = GetEntry( _nRow );
+ if ( pEntry )
+ {
+ aRect = _bIsHeader ? calcHeaderRect( sal_True, FALSE ) : GetBoundingRect( pEntry );
+ Point aTopLeft = aRect.TopLeft();
+ DBG_ASSERT( m_pImpl->m_pHeaderBar->GetItemCount() > _nColumn, "invalid column" );
+ Rectangle aItemRect = m_pImpl->m_pHeaderBar->GetItemRect( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) );
+ aTopLeft.X() = aItemRect.Left();
+ Size aSize = aItemRect.GetSize();
+ aRect = Rectangle( aTopLeft, aSize );
+ Window* pParent = NULL;
+ if ( !_bOnScreen )
+ pParent = GetAccessibleParentWindow();
+ aTopLeft = aRect.TopLeft();
+ aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
+ aRect = Rectangle( aTopLeft, aRect.GetSize() );
+ }
+
+ return aRect;
+}
+// -----------------------------------------------------------------------
+Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
+{
+ OSL_ENSURE( m_pAccessible, "Invalid call: Accessible is null" );
+
+ Reference< XAccessible > xChild;
+ sal_Int32 nIndex = -1;
+
+ if ( !AreChildrenTransient() )
+ {
+ const sal_uInt16 nColumnCount = GetColumnCount();
+
+ // first call? -> initial list
+ if ( m_aAccessibleChildren.empty() )
+ {
+ sal_Int32 nCount = ( GetRowCount() + 1 ) * nColumnCount;
+ m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() );
+ }
+
+ nIndex = ( _nRow * nColumnCount ) + _nColumnPos + nColumnCount;
+ xChild = m_aAccessibleChildren[ nIndex ];
+ }
+
+ if ( !xChild.is() )
+ {
+ TriState eState = STATE_DONTKNOW;
+ sal_Bool bIsCheckBox = IsCellCheckBox( _nRow, _nColumnPos, eState );
+ if ( bIsCheckBox )
+ xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleCheckBoxCell(
+ m_pAccessible->getAccessibleChild( 0 ), *this, NULL, _nRow, _nColumnPos, eState, sal_True, sal_False );
+ else
+ xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxTableCell(
+ m_pAccessible->getAccessibleChild( 0 ), *this, NULL, _nRow, _nColumnPos, OFFSET_NONE );
+
+ // insert into list
+ if ( !AreChildrenTransient() )
+ m_aAccessibleChildren[ nIndex ] = xChild;
+ }
+
+ return xChild;
+}
+// -----------------------------------------------------------------------
+Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleRowHeader( sal_Int32 )
+{
+ Reference< XAccessible > xHeader;
+ return xHeader;
+}
+// -----------------------------------------------------------------------
+Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleColumnHeader( sal_uInt16 _nColumn )
+{
+ // first call? -> initial list
+ if ( m_aAccessibleChildren.empty() )
+ {
+ const sal_uInt16 nColumnCount = GetColumnCount();
+ sal_Int32 nCount = AreChildrenTransient() ?
+ nColumnCount : ( GetRowCount() + 1 ) * nColumnCount;
+ m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() );
+ }
+
+ // get header
+ Reference< XAccessible > xChild = m_aAccessibleChildren[ _nColumn ];
+ // already exists?
+ if ( !xChild.is() && m_pAccessible )
+ {
+ // no -> create new header cell
+ xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderCell(
+ _nColumn, m_pAccessible->getHeaderBar( ::svt::BBTYPE_COLUMNHEADERBAR ),
+ *this, NULL, ::svt::BBTYPE_COLUMNHEADERCELL
+ );
+
+ // insert into list
+ m_aAccessibleChildren[ _nColumn ] = xChild;
+ }
+
+ return xChild;
+}
+// -----------------------------------------------------------------------
+sal_Int32 SvHeaderTabListBox::GetAccessibleControlCount() const
+{
+ return -1;
+}
+// -----------------------------------------------------------------------
+Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleControl( sal_Int32 )
+{
+ Reference< XAccessible > xControl;
+ return xControl;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::ConvertPointToControlIndex( sal_Int32&, const Point& )
+{
+ return sal_False;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::ConvertPointToCellAddress( sal_Int32&, sal_uInt16&, const Point& )
+{
+ return sal_False;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::ConvertPointToRowHeader( sal_Int32&, const Point& )
+{
+ return sal_False;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Point& )
+{
+ return sal_False;
+}
+// -----------------------------------------------------------------------
+::rtl::OUString SvHeaderTabListBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
+{
+ ::rtl::OUString aRetText;
+ switch( _eType )
+ {
+ case ::svt::BBTYPE_BROWSEBOX:
+ case ::svt::BBTYPE_TABLE:
+ case ::svt::BBTYPE_COLUMNHEADERBAR:
+ // should be empty now (see #i63983)
+ aRetText = ::rtl::OUString();
+ break;
+
+ case ::svt::BBTYPE_TABLECELL:
+ {
+ // here we need a valid pos, we can not handle -1
+ if ( _nPos >= 0 )
+ {
+ sal_uInt16 nColumnCount = GetColumnCount();
+ if (nColumnCount > 0)
+ {
+ sal_Int32 nRow = _nPos / nColumnCount;
+ sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount );
+ aRetText = GetCellText( nRow, nColumn );
+ }
+ }
+ break;
+ }
+ case ::svt::BBTYPE_CHECKBOXCELL:
+ {
+ break; // checkbox cells have no name
+ }
+ case ::svt::BBTYPE_COLUMNHEADERCELL:
+ {
+ aRetText = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( (USHORT)_nPos ) );
+ break;
+ }
+
+ case ::svt::BBTYPE_ROWHEADERBAR:
+ case ::svt::BBTYPE_ROWHEADERCELL:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "error" ) );
+ break;
+
+ default:
+ OSL_ENSURE(0,"BrowseBox::GetAccessibleName: invalid enum!");
+ }
+ return aRetText;
+}
+// -----------------------------------------------------------------------
+::rtl::OUString SvHeaderTabListBox::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
+{
+ ::rtl::OUString aRetText;
+
+ if( _eType == ::svt::BBTYPE_TABLECELL && _nPos != -1 )
+ {
+ static const String sVar1( RTL_CONSTASCII_USTRINGPARAM( "%1" ) );
+ static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) );
+
+ sal_uInt16 nColumnCount = GetColumnCount();
+ if (nColumnCount > 0)
+ {
+ sal_Int32 nRow = _nPos / nColumnCount;
+ sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount );
+
+ String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) );
+ aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) );
+ String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) );
+ if ( sColHeader.Len() == 0 )
+ sColHeader = String::CreateFromInt32( nColumn );
+ aText.SearchAndReplace( sVar2, sColHeader );
+ aRetText = aText;
+ }
+ }
+
+ return aRetText;
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& _rStateSet, ::svt::AccessibleBrowseBoxObjType _eType ) const
+{
+ switch( _eType )
+ {
+ case ::svt::BBTYPE_BROWSEBOX:
+ case ::svt::BBTYPE_TABLE:
+ {
+ _rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ if ( HasFocus() )
+ _rStateSet.AddState( AccessibleStateType::FOCUSED );
+ if ( IsActive() )
+ _rStateSet.AddState( AccessibleStateType::ACTIVE );
+ if ( IsEnabled() )
+ {
+ _rStateSet.AddState( AccessibleStateType::ENABLED );
+ _rStateSet.AddState( AccessibleStateType::SENSITIVE );
+ }
+ if ( IsReallyVisible() )
+ _rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( _eType == ::svt::BBTYPE_TABLE )
+ {
+
+ if ( AreChildrenTransient() )
+ _rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ _rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
+ }
+ break;
+ }
+
+ case ::svt::BBTYPE_COLUMNHEADERBAR:
+ {
+ sal_Int32 nCurRow = GetCurrRow();
+ sal_uInt16 nCurColumn = GetCurrColumn();
+ if ( IsCellVisible( nCurRow, nCurColumn ) )
+ _rStateSet.AddState( AccessibleStateType::VISIBLE );
+ _rStateSet.AddState( AccessibleStateType::TRANSIENT );
+ break;
+ }
+
+ case ::svt::BBTYPE_ROWHEADERCELL:
+ case ::svt::BBTYPE_COLUMNHEADERCELL:
+ {
+ _rStateSet.AddState( AccessibleStateType::VISIBLE );
+ _rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ _rStateSet.AddState( AccessibleStateType::TRANSIENT );
+ break;
+ }
+ default:
+ break;
+ }
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumn ) const
+{
+ _rStateSet.AddState( AccessibleStateType::SELECTABLE );
+ if ( AreChildrenTransient() )
+ _rStateSet.AddState( AccessibleStateType::TRANSIENT );
+
+ if ( IsCellVisible( _nRow, _nColumn ) )
+ {
+ _rStateSet.AddState( AccessibleStateType::VISIBLE );
+ _rStateSet.AddState( AccessibleStateType::ENABLED );
+ }
+
+ if ( IsRowSelected( _nRow ) )
+ {
+ _rStateSet.AddState( AccessibleStateType::ACTIVE );
+ _rStateSet.AddState( AccessibleStateType::SELECTED );
+ }
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::GrabTableFocus()
+{
+ GrabFocus();
+}
+// -----------------------------------------------------------------------
+BOOL SvHeaderTabListBox::GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector )
+{
+ return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, nBase, rVector );
+}
+// -----------------------------------------------------------------------
+Rectangle SvHeaderTabListBox::GetWindowExtentsRelative( Window *pRelativeWindow ) const
+{
+ return Control::GetWindowExtentsRelative( pRelativeWindow );
+}
+// -----------------------------------------------------------------------
+void SvHeaderTabListBox::GrabFocus()
+{
+ Control::GrabFocus();
+}
+// -----------------------------------------------------------------------
+Reference< XAccessible > SvHeaderTabListBox::GetAccessible( BOOL bCreate )
+{
+ return Control::GetAccessible( bCreate );
+}
+// -----------------------------------------------------------------------
+Window* SvHeaderTabListBox::GetAccessibleParentWindow() const
+{
+ return Control::GetAccessibleParentWindow();
+}
+// -----------------------------------------------------------------------
+Window* SvHeaderTabListBox::GetWindowInstance()
+{
+ return this;
+}
+// -----------------------------------------------------------------------
+Reference< XAccessible > SvHeaderTabListBox::CreateAccessible()
+{
+ Window* pParent = GetAccessibleParentWindow();
+ DBG_ASSERT( pParent, "SvHeaderTabListBox::::CreateAccessible - accessible parent not found" );
+
+ Reference< XAccessible > xAccessible;
+ if ( m_pAccessible ) xAccessible = m_pAccessible->getMyself();
+
+ if( pParent && !m_pAccessible )
+ {
+ Reference< XAccessible > xAccParent = pParent->GetAccessible();
+ if ( xAccParent.is() )
+ {
+ m_pAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleTabListBox( xAccParent, *this );
+ if ( m_pAccessible )
+ xAccessible = m_pAccessible->getMyself();
+ }
+ }
+ return xAccessible;
+}
+// -----------------------------------------------------------------------------
+Rectangle SvHeaderTabListBox::GetFieldCharacterBounds(sal_Int32,sal_Int32,sal_Int32)
+{
+ Rectangle aRect;
+ return aRect;
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SvHeaderTabListBox::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
+{
+ String sText = GetAccessibleCellText( _nRow, static_cast< USHORT >( _nColumnPos ) );
+ MetricVector aRects;
+ if ( GetGlyphBoundRects(Point(0,0),sText,0,STRING_LEN,0,aRects) )
+ {
+ for (MetricVector::iterator aIter = aRects.begin(); aIter != aRects.end(); ++aIter)
+ {
+ if( aIter->IsInside(_rPoint) )
+ return aIter - aRects.begin();
+ }
+ }
+
+ return -1;
+}
+// -----------------------------------------------------------------------------
+
+
diff --git a/svtools/source/contnr/svtreebx.cxx b/svtools/source/contnr/svtreebx.cxx
new file mode 100644
index 000000000000..b11a3f12ddf3
--- /dev/null
+++ b/svtools/source/contnr/svtreebx.cxx
@@ -0,0 +1,2670 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SVTREEBX_CXX
+#include <vcl/svapp.hxx>
+#ifndef GCC
+#endif
+
+class TabBar;
+
+// #102891# -----------------------
+
+#include <svtools/svlbox.hxx>
+#include <svtools/svlbitm.hxx>
+#include <svtools/svtreebx.hxx>
+#include <tools/diagnose_ex.h>
+#include <svimpbox.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+
+
+using namespace ::com::sun::star::accessibility;
+
+/*
+ Bugs/ToDo
+
+ - Berechnung Rectangle beim Inplace-Editing (Bug bei manchen Fonts)
+ - SetSpaceBetweenEntries: Offset wird in SetEntryHeight nicht
+ beruecksichtigt
+*/
+
+#define TREEFLAG_FIXEDHEIGHT 0x0010
+
+
+DBG_NAME(SvTreeListBox)
+
+#define SV_LBOX_DEFAULT_INDENT_PIXEL 20
+
+SvTreeListBox::SvTreeListBox( Window* pParent, WinBits nWinStyle )
+ : SvLBox(pParent,nWinStyle )
+{
+ DBG_CTOR(SvTreeListBox,0);
+ InitTreeView( nWinStyle );
+
+ SetSublistOpenWithLeftRight();
+}
+
+SvTreeListBox::SvTreeListBox( Window* pParent , const ResId& rResId )
+ : SvLBox( pParent,rResId )
+{
+ DBG_CTOR(SvTreeListBox,0);
+
+ InitTreeView( 0 );
+ Resize();
+
+ SetSublistOpenWithLeftRight();
+}
+
+void SvTreeListBox::InitTreeView( WinBits nWinStyle )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pCheckButtonData = NULL;
+ pEdEntry = NULL;
+ pEdItem = NULL;
+ nEntryHeight = 0;
+ pEdCtrl = NULL;
+ nFirstSelTab = 0;
+ nLastSelTab = 0;
+ nFocusWidth = -1;
+
+ Link* pLink = new Link( LINK(this,SvTreeListBox, DefaultCompare) );
+ pLBoxImpl->m_pLink = pLink;
+
+ nTreeFlags = TREEFLAG_RECALCTABS;
+ nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL;
+ nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL;
+ pImp = new SvImpLBox( this, GetModel(), nWinStyle );
+
+ aContextBmpMode = SVLISTENTRYFLAG_EXPANDED;
+ nContextBmpWidthMax = 0;
+ SetFont( GetFont() );
+ SetSpaceBetweenEntries( 0 );
+ SetLineColor();
+ InitSettings( TRUE, TRUE, TRUE );
+ SetWindowBits( nWinStyle );
+ SetTabs();
+}
+
+
+SvTreeListBox::~SvTreeListBox()
+{
+ DBG_DTOR(SvTreeListBox,0);
+ pImp->CallEventListeners( VCLEVENT_OBJECT_DYING );
+ delete pImp;
+ delete pLBoxImpl->m_pLink;
+ ClearTabList();
+}
+
+void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits )
+{
+ pImp->SetExtendedWindowBits( _nBits );
+}
+
+ExtendedWinBits SvTreeListBox::GetExtendedWinBits() const
+{
+ return pImp->GetExtendedWindowBits();
+}
+
+void SvTreeListBox::SetModel( SvLBoxTreeList* pNewModel )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->SetModel( pNewModel );
+ SvLBox::SetModel( pNewModel );
+}
+
+void SvTreeListBox::DisconnectFromModel()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBox::DisconnectFromModel();
+ pImp->SetModel( GetModel() );
+}
+
+
+USHORT SvTreeListBox::IsA()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ return SV_LISTBOX_ID_TREEBOX;
+}
+
+void SvTreeListBox::SetSublistOpenWithReturn( BOOL b )
+{
+ pImp->bSubLstOpRet = b;
+}
+
+BOOL SvTreeListBox::IsSublistOpenWithReturn() const
+{
+ return pImp->bSubLstOpRet;
+}
+
+void SvTreeListBox::SetSublistOpenWithLeftRight( BOOL b )
+{
+ pImp->bSubLstOpLR = b;
+}
+
+BOOL SvTreeListBox::IsSublistOpenWithLeftRight() const
+{
+ return pImp->bSubLstOpLR;
+}
+
+void SvTreeListBox::Resize()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( IsEditingActive() )
+ EndEditing( TRUE );
+ SvLBox::Resize();
+ pImp->Resize();
+ nFocusWidth = -1;
+ pImp->ShowCursor( FALSE );
+ pImp->ShowCursor( TRUE );
+}
+
+/* Faelle:
+
+ A) Entries haben Bitmaps
+ 0. Keine Buttons
+ 1. Node-Buttons (optional auch an Root-Items)
+ 2. Node-Buttons (optional auch an Root-Items) + CheckButton
+ 3. CheckButton
+ B) Entries haben keine Bitmaps (->ueber WindowBits wg. D&D !!!!!!)
+ 0. Keine Buttons
+ 1. Node-Buttons (optional auch an Root-Items)
+ 2. Node-Buttons (optional auch an Root-Items) + CheckButton
+ 3. CheckButton
+*/
+
+#define NO_BUTTONS 0
+#define NODE_BUTTONS 1
+#define NODE_AND_CHECK_BUTTONS 2
+#define CHECK_BUTTONS 3
+
+#define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC | \
+ SV_LBOXTAB_ADJUST_LEFT | \
+ SV_LBOXTAB_EDITABLE | \
+ SV_LBOXTAB_SHOW_SELECTION)
+
+#define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER)
+
+#define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC | \
+ SV_LBOXTAB_ADJUST_CENTER | \
+ SV_LBOXTAB_PUSHABLE)
+
+#define TAB_STARTPOS 2
+
+// bei Aenderungen GetTextOffset beruecksichtigen
+void SvTreeListBox::SetTabs()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( IsEditingActive() )
+ EndEditing( TRUE );
+ nTreeFlags &= (~TREEFLAG_RECALCTABS);
+ nFocusWidth = -1;
+ BOOL bHasButtons = (nWindowStyle & WB_HASBUTTONS)!=0;
+ BOOL bHasButtonsAtRoot = (nWindowStyle & (WB_HASLINESATROOT |
+ WB_HASBUTTONSATROOT))!=0;
+ long nStartPos = TAB_STARTPOS;
+ long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();
+
+ long nCheckWidth = 0;
+ if( nTreeFlags & TREEFLAG_CHKBTN )
+ nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width();
+ long nCheckWidthDIV2 = nCheckWidth / 2;
+
+ long nContextWidth = nContextBmpWidthMax;
+ long nContextWidthDIV2 = nContextWidth / 2;
+
+ ClearTabList();
+
+ int nCase = NO_BUTTONS;
+ if( !(nTreeFlags & TREEFLAG_CHKBTN) )
+ {
+ if( bHasButtons )
+ nCase = NODE_BUTTONS;
+ }
+ else
+ {
+ if( bHasButtons )
+ nCase = NODE_AND_CHECK_BUTTONS;
+ else
+ nCase = CHECK_BUTTONS;
+ }
+
+ switch( nCase )
+ {
+ case NO_BUTTONS :
+ nStartPos += nContextWidthDIV2; // wg. Zentrierung
+ AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ // Abstand setzen nur wenn Bitmaps da
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ AddTab( nStartPos, TABFLAGS_TEXT );
+ break;
+
+ case NODE_BUTTONS :
+ if( bHasButtonsAtRoot )
+ nStartPos += ( nIndent + (nNodeWidthPixel/2) );
+ else
+ nStartPos += nContextWidthDIV2;
+ AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ // Abstand setzen nur wenn Bitmaps da
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ AddTab( nStartPos, TABFLAGS_TEXT );
+ break;
+
+ case NODE_AND_CHECK_BUTTONS :
+ if( bHasButtonsAtRoot )
+ nStartPos += ( nIndent + nNodeWidthPixel );
+ else
+ nStartPos += nCheckWidthDIV2;
+ AddTab( nStartPos, TABFLAGS_CHECKBTN );
+ nStartPos += nCheckWidthDIV2; // rechter Rand des CheckButtons
+ nStartPos += 3; // Abstand CheckButton Context-Bmp
+ nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp
+ AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ // Abstand setzen nur wenn Bitmaps da
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ AddTab( nStartPos, TABFLAGS_TEXT );
+ break;
+
+ case CHECK_BUTTONS :
+ nStartPos += nCheckWidthDIV2;
+ AddTab( nStartPos, TABFLAGS_CHECKBTN );
+ nStartPos += nCheckWidthDIV2; // rechter Rand CheckButton
+ nStartPos += 3; // Abstand CheckButton Context-Bmp
+ nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp
+ AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ // Abstand setzen nur wenn Bitmaps da
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ AddTab( nStartPos, TABFLAGS_TEXT );
+ break;
+ }
+ pImp->NotifyTabsChanged();
+}
+
+void SvTreeListBox::InitEntry( SvLBoxEntry* pEntry,
+ const XubString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp,
+ SvLBoxButtonKind eButtonKind)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxButton* pButton;
+ SvLBoxString* pString;
+ SvLBoxContextBmp* pContextBmp;
+
+ if( nTreeFlags & TREEFLAG_CHKBTN )
+ {
+ pButton= new SvLBoxButton( pEntry,eButtonKind,0,pCheckButtonData );
+ pEntry->AddItem( pButton );
+ }
+
+ pContextBmp= new SvLBoxContextBmp( pEntry,0, aCollEntryBmp,aExpEntryBmp,
+ aContextBmpMode );
+ pEntry->AddItem( pContextBmp );
+
+ pString = new SvLBoxString( pEntry, 0, aStr );
+ pEntry->AddItem( pString );
+}
+
+String SvTreeListBox::GetEntryText(SvLBoxEntry* pEntry) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): no entry" );
+ SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): item not found" );
+ return pItem->GetText();
+}
+
+String SvTreeListBox::SearchEntryText( SvLBoxEntry* pEntry ) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" );
+ String sRet;
+ USHORT nCount = pEntry->ItemCount();
+ USHORT nCur = 0;
+ SvLBoxItem* pItem;
+ while( nCur < nCount )
+ {
+ pItem = pEntry->GetItem( nCur );
+ if ( pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
+ static_cast<SvLBoxString*>( pItem )->GetText().Len() > 0 )
+ {
+ sRet = static_cast<SvLBoxString*>( pItem )->GetText();
+ break;
+ }
+ nCur++;
+ }
+ return sRet;
+}
+
+const Image& SvTreeListBox::GetExpandedEntryBmp(SvLBoxEntry* pEntry, BmpColorMode _eMode) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pEntry,"Entry?");
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ DBG_ASSERT(pItem,"GetContextBmp:Item not found");
+ return pItem->GetBitmap2( _eMode );
+}
+
+const Image& SvTreeListBox::GetCollapsedEntryBmp( SvLBoxEntry* pEntry, BmpColorMode _eMode ) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pEntry,"Entry?");
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ DBG_ASSERT(pItem,"GetContextBmp:Item not found");
+ return pItem->GetBitmap1( _eMode );
+}
+
+IMPL_LINK_INLINE_START( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pHdlEntry = pData->GetActEntry();
+ CheckButtonHdl();
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
+
+SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,SvLBoxEntry* pParent,
+ BOOL bChildsOnDemand, ULONG nPos, void* pUser,
+ SvLBoxButtonKind eButtonKind )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nTreeFlags |= TREEFLAG_MANINS;
+
+ const Image& rDefExpBmp = pImp->GetDefaultEntryExpBmp( );
+ const Image& rDefColBmp = pImp->GetDefaultEntryColBmp( );
+
+ aCurInsertedExpBmp = rDefExpBmp;
+ aCurInsertedColBmp = rDefColBmp;
+
+ SvLBoxEntry* pEntry = CreateEntry();
+ pEntry->SetUserData( pUser );
+ InitEntry( pEntry, aText, rDefColBmp, rDefExpBmp, eButtonKind );
+ pEntry->EnableChildsOnDemand( bChildsOnDemand );
+
+ // Add the HC versions of the default images
+ SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
+ if( pBmpItem )
+ {
+ pBmpItem->SetBitmap1( pImp->GetDefaultEntryColBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
+ pBmpItem->SetBitmap2( pImp->GetDefaultEntryExpBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
+ }
+
+ if( !pParent )
+ SvLBox::Insert( pEntry, nPos );
+ else
+ SvLBox::Insert( pEntry, pParent, nPos );
+
+ aPrevInsertedExpBmp = rDefExpBmp;
+ aPrevInsertedColBmp = rDefColBmp;
+
+ nTreeFlags &= (~TREEFLAG_MANINS);
+
+ return pEntry;
+}
+
+SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,
+ const Image& aExpEntryBmp, const Image& aCollEntryBmp,
+ SvLBoxEntry* pParent, BOOL bChildsOnDemand, ULONG nPos, void* pUser,
+ SvLBoxButtonKind eButtonKind )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nTreeFlags |= TREEFLAG_MANINS;
+
+ aCurInsertedExpBmp = aExpEntryBmp;
+ aCurInsertedColBmp = aCollEntryBmp;
+
+ SvLBoxEntry* pEntry = CreateEntry();
+ pEntry->SetUserData( pUser );
+ InitEntry( pEntry, aText, aCollEntryBmp, aExpEntryBmp, eButtonKind );
+
+ pEntry->EnableChildsOnDemand( bChildsOnDemand );
+
+ if( !pParent )
+ SvLBox::Insert( pEntry, nPos );
+ else
+ SvLBox::Insert( pEntry, pParent, nPos );
+
+ aPrevInsertedExpBmp = aExpEntryBmp;
+ aPrevInsertedColBmp = aCollEntryBmp;
+
+ nTreeFlags &= (~TREEFLAG_MANINS);
+
+ return pEntry;
+}
+
+void SvTreeListBox::SetEntryText( SvLBoxEntry* pEntry, const XubString& aStr)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ DBG_ASSERT(pItem,"SetText:Item not found");
+ pItem->SetText( pEntry, aStr );
+ pItem->InitViewData( this, pEntry, 0 );
+ GetModel()->InvalidateEntry( pEntry );
+}
+
+void SvTreeListBox::SetExpandedEntryBmp( SvLBoxEntry* pEntry, const Image& aBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+
+ DBG_ASSERT(pItem,"SetExpBmp:Item not found");
+ pItem->SetBitmap2( aBmp, _eMode );
+
+ GetModel()->InvalidateEntry( pEntry );
+ SetEntryHeight( pEntry );
+ Size aSize = aBmp.GetSizePixel();
+ // #97680# ---------------
+ short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
+ if( nWidth > nContextBmpWidthMax )
+ {
+ nContextBmpWidthMax = nWidth;
+ SetTabs();
+ }
+}
+
+void SvTreeListBox::SetCollapsedEntryBmp(SvLBoxEntry* pEntry,const Image& aBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+
+ DBG_ASSERT(pItem,"SetExpBmp:Item not found");
+ pItem->SetBitmap1( aBmp, _eMode );
+
+ GetModel()->InvalidateEntry( pEntry );
+ SetEntryHeight( pEntry );
+ Size aSize = aBmp.GetSizePixel();
+ // #97680# -----------
+ short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
+ if( nWidth > nContextBmpWidthMax )
+ {
+ nContextBmpWidthMax = nWidth;
+ SetTabs();
+ }
+}
+
+void SvTreeListBox::ImpEntryInserted( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+
+ SvLBoxEntry* pParent = (SvLBoxEntry*)pModel->GetParent( pEntry );
+ if( pParent )
+ {
+ USHORT nFlags = pParent->GetFlags();
+ nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
+ pParent->SetFlags( nFlags );
+ }
+
+ if(!((nTreeFlags & TREEFLAG_MANINS) &&
+ (aPrevInsertedExpBmp == aCurInsertedExpBmp) &&
+ (aPrevInsertedColBmp == aCurInsertedColBmp) ))
+ {
+ Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel();
+ if( aSize.Width() > nContextBmpWidthMax )
+ {
+ nContextBmpWidthMax = (short)aSize.Width();
+ nTreeFlags |= TREEFLAG_RECALCTABS;
+ }
+ aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel();
+ if( aSize.Width() > nContextBmpWidthMax )
+ {
+ nContextBmpWidthMax = (short)aSize.Width();
+ nTreeFlags |= TREEFLAG_RECALCTABS;
+ }
+ }
+ SetEntryHeight( (SvLBoxEntry*)pEntry );
+}
+
+
+
+void SvTreeListBox::SetCheckButtonState( SvLBoxEntry* pEntry, SvButtonState eState)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( nTreeFlags & TREEFLAG_CHKBTN )
+ {
+ SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
+ if(!(pItem && pItem->CheckModification()))
+ return ;
+ switch( eState )
+ {
+ case SV_BUTTON_CHECKED:
+ pItem->SetStateChecked();
+ break;
+
+ case SV_BUTTON_UNCHECKED:
+ pItem->SetStateUnchecked();
+ break;
+
+ case SV_BUTTON_TRISTATE:
+ pItem->SetStateTristate();
+ break;
+ }
+ InvalidateEntry( pEntry );
+ }
+}
+
+SvButtonState SvTreeListBox::GetCheckButtonState( SvLBoxEntry* pEntry ) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvButtonState eState = SV_BUTTON_UNCHECKED;
+ if( nTreeFlags & TREEFLAG_CHKBTN )
+ {
+ SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
+ if(!pItem)
+ return SV_BUTTON_TRISTATE;
+ USHORT nButtonFlags = pItem->GetButtonFlags();
+ eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
+ }
+ return eState;
+}
+
+void SvTreeListBox::CheckButtonHdl()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ aCheckButtonHdl.Call( this );
+ if ( pCheckButtonData )
+ pImp->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)pCheckButtonData->GetActEntry() );
+}
+
+// *********************************************************************
+// *********************************************************************
+
+//
+// TODO: Momentan werden die Daten so geklont, dass sie dem
+// Standard-TreeView-Format entsprechen. Hier sollte eigentlich
+// das Model als Referenz dienen. Dies fuehrt dazu, dass
+// SvLBoxEntry::Clone _nicht_ gerufen wird, sondern nur dessen
+// Basisklasse SvListEntry
+//
+
+SvLBoxEntry* SvTreeListBox::CloneEntry( SvLBoxEntry* pSource )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ XubString aStr;
+ Image aCollEntryBmp;
+ Image aExpEntryBmp;
+ SvLBoxButtonKind eButtonKind = SvLBoxButtonKind_enabledCheckbox;
+
+ SvLBoxString* pStringItem = (SvLBoxString*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
+ if( pStringItem )
+ aStr = pStringItem->GetText();
+ SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
+ if( pBmpItem )
+ {
+ aCollEntryBmp = pBmpItem->GetBitmap1( BMP_COLOR_NORMAL );
+ aExpEntryBmp = pBmpItem->GetBitmap2( BMP_COLOR_NORMAL );
+ }
+ SvLBoxButton* pButtonItem = (SvLBoxButton*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
+ if( pButtonItem )
+ eButtonKind = pButtonItem->GetKind();
+ SvLBoxEntry* pClone = CreateEntry();
+ InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind );
+ pClone->SvListEntry::Clone( pSource );
+ pClone->EnableChildsOnDemand( pSource->HasChildsOnDemand() );
+ pClone->SetUserData( pSource->GetUserData() );
+
+ if ( pBmpItem )
+ {
+ SvLBoxContextBmp* pCloneBitmap = static_cast< SvLBoxContextBmp* >( pClone->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
+ if ( pCloneBitmap )
+ {
+ pCloneBitmap->SetBitmap1( pBmpItem->GetBitmap1( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
+ pCloneBitmap->SetBitmap2( pBmpItem->GetBitmap2( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
+ }
+ }
+
+ return pClone;
+}
+
+// *********************************************************************
+// *********************************************************************
+
+
+void SvTreeListBox::ShowExpandBitmapOnCursor( BOOL bYes )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( bYes )
+ aContextBmpMode = SVLISTENTRYFLAG_FOCUSED;
+ else
+ aContextBmpMode = SVLISTENTRYFLAG_EXPANDED;
+}
+
+void SvTreeListBox::SetIndent( short nNewIndent )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nIndent = nNewIndent;
+ SetTabs();
+ if( IsUpdateMode() )
+ Invalidate();
+}
+
+const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( BmpColorMode _eMode ) const
+{
+ return pImp->GetDefaultEntryExpBmp( _eMode );
+}
+
+const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( BmpColorMode _eMode ) const
+{
+ return pImp->GetDefaultEntryColBmp( _eMode );
+}
+
+void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Size aSize = aBmp.GetSizePixel();
+ if( aSize.Width() > nContextBmpWidthMax )
+ nContextBmpWidthMax = (short)aSize.Width();
+ SetTabs();
+
+ pImp->SetDefaultEntryExpBmp( aBmp, _eMode );
+}
+
+void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Size aSize = aBmp.GetSizePixel();
+ if( aSize.Width() > nContextBmpWidthMax )
+ nContextBmpWidthMax = (short)aSize.Width();
+ SetTabs();
+
+ pImp->SetDefaultEntryColBmp( aBmp, _eMode );
+}
+
+void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
+ if( !pData )
+ nTreeFlags &= (~TREEFLAG_CHKBTN);
+ else
+ {
+ SetCheckButtonData( pData );
+ nTreeFlags |= TREEFLAG_CHKBTN;
+ pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick));
+ }
+
+ SetTabs();
+ if( IsUpdateMode() )
+ Invalidate();
+}
+
+void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if ( pData )
+ pCheckButtonData = pData;
+}
+
+const Image& SvTreeListBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode )
+{
+ return SvImpLBox::GetDefaultExpandedNodeImage( _eMode );
+}
+
+const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode )
+{
+ return SvImpLBox::GetDefaultCollapsedNodeImage( _eMode );
+}
+
+void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SetExpandedNodeBmp( rExpandedNodeBmp, _eMode );
+ SetCollapsedNodeBmp( rCollapsedNodeBmp, _eMode );
+ SetTabs();
+}
+
+void SvTreeListBox::SetDontKnowNodeBitmap( const Image& rDontKnowBmp, BmpColorMode _eMode )
+{
+ pImp->SetDontKnowNodeBmp( rDontKnowBmp, _eMode );
+}
+
+BOOL SvTreeListBox::EditingEntry( SvLBoxEntry*, Selection& )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ return TRUE;
+}
+
+BOOL SvTreeListBox::EditedEntry( SvLBoxEntry* /*pEntry*/,const XubString& /*rNewText*/)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ return TRUE;
+}
+
+void SvTreeListBox::EnableInplaceEditing( BOOL bOn )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBox::EnableInplaceEditing( bOn );
+}
+
+void SvTreeListBox::KeyInput( const KeyEvent& rKEvt )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ // unter OS/2 bekommen wir auch beim Editieren Key-Up/Down
+ if( IsEditingActive() )
+ return;
+
+ nImpFlags |= SVLBOX_IS_TRAVELSELECT;
+
+#ifdef OVDEBUG
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+ switch ( nCode )
+ {
+ case KEY_F1:
+ {
+ SvLBoxEntry* pEntry = First();
+ pEntry = NextVisible( pEntry );
+ SetEntryText( pEntry, "SetEntryText" );
+ Sound::Beep();
+ }
+ break;
+ }
+#endif
+
+ if( !pImp->KeyInput( rKEvt ) )
+ SvLBox::KeyInput( rKEvt );
+
+ nImpFlags &= ~SVLBOX_IS_TRAVELSELECT;
+}
+
+void SvTreeListBox::RequestingChilds( SvLBoxEntry* pParent )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( !pParent->HasChilds() )
+ InsertEntry( String::CreateFromAscii("<dummy>"), pParent, FALSE, LIST_APPEND );
+}
+
+void SvTreeListBox::GetFocus()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->GetFocus();
+ SvLBox::GetFocus();
+
+ SvLBoxEntry* pEntry = FirstSelected();
+ if ( pEntry )
+ pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );
+
+}
+
+void SvTreeListBox::LoseFocus()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->LoseFocus();
+ SvLBox::LoseFocus();
+}
+
+void SvTreeListBox::ModelHasCleared()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->pCursor = 0; //sonst Absturz beim Inplace-Editieren im GetFocus
+ delete pEdCtrl;
+ pEdCtrl = NULL;
+ pImp->Clear();
+ nFocusWidth = -1;
+
+ nContextBmpWidthMax = 0;
+ SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
+ SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );
+
+ if( !(nTreeFlags & TREEFLAG_FIXEDHEIGHT ))
+ nEntryHeight = 0;
+ AdjustEntryHeight( GetFont() );
+ AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
+ AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );
+
+ SvLBox::ModelHasCleared();
+// if( IsUpdateMode() )
+// Invalidate();
+}
+
+void SvTreeListBox::ShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL /* bShow */ )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->PaintDDCursor( pEntry );
+}
+
+void SvTreeListBox::ScrollOutputArea( short nDeltaEntries )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( !nDeltaEntries || !pImp->aVerSBar.IsVisible() )
+ return;
+
+ long nThumb = pImp->aVerSBar.GetThumbPos();
+ long nMax = pImp->aVerSBar.GetRange().Max();
+
+ NotifyBeginScroll();
+ if( nDeltaEntries < 0 )
+ {
+ // das Fenster nach oben verschieben
+ nDeltaEntries *= -1;
+ long nVis = pImp->aVerSBar.GetVisibleSize();
+ long nTemp = nThumb + nVis;
+ if( nDeltaEntries > (nMax - nTemp) )
+ nDeltaEntries = (short)(nMax - nTemp);
+ pImp->PageDown( (USHORT)nDeltaEntries );
+ }
+ else
+ {
+ if( nDeltaEntries > nThumb )
+ nDeltaEntries = (short)nThumb;
+ pImp->PageUp( (USHORT)nDeltaEntries );
+ }
+ pImp->SyncVerThumb();
+ NotifyEndScroll();
+}
+
+void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBox::SetSelectionMode( eSelectMode );
+ pImp->SetSelectionMode( eSelectMode );
+}
+
+void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBox::SetDragDropMode( nDDMode );
+ pImp->SetDragDropMode( nDDMode );
+}
+
+short SvTreeListBox::GetHeightOffset(const Image& rBmp, Size& aSizeLogic )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ short nOffset = 0;
+ aSizeLogic = rBmp.GetSizePixel();
+ if( GetEntryHeight() > aSizeLogic.Height() )
+ nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
+ return nOffset;
+}
+
+short SvTreeListBox::GetHeightOffset(const Font& /* rFont */, Size& aSizeLogic )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ short nOffset = 0;
+ aSizeLogic = Size(GetTextWidth('X'), GetTextHeight());
+ if( GetEntryHeight() > aSizeLogic.Height() )
+ nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
+ return nOffset;
+}
+
+void SvTreeListBox::SetEntryHeight( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ short nHeight, nHeightMax=0;
+ USHORT nCount = pEntry->ItemCount();
+ USHORT nCur = 0;
+ SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
+ while( nCur < nCount )
+ {
+ SvLBoxItem* pItem = pEntry->GetItem( nCur );
+ nHeight = (short)(pItem->GetSize( pViewData, nCur ).Height());
+ if( nHeight > nHeightMax )
+ nHeightMax = nHeight;
+ nCur++;
+ }
+
+ if( nHeightMax > nEntryHeight )
+ {
+ nEntryHeight = nHeightMax;
+ SvLBox::SetFont( GetFont() );
+ pImp->SetEntryHeight( nHeightMax );
+ }
+}
+
+void SvTreeListBox::SetEntryHeight( short nHeight, BOOL bAlways )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+
+ if( bAlways || nHeight > nEntryHeight )
+ {
+ nEntryHeight = nHeight;
+ if( nEntryHeight )
+ nTreeFlags |= TREEFLAG_FIXEDHEIGHT;
+ else
+ nTreeFlags &= ~TREEFLAG_FIXEDHEIGHT;
+ SvLBox::SetFont( GetFont() );
+ pImp->SetEntryHeight( nHeight );
+ }
+}
+
+
+void SvTreeListBox::AdjustEntryHeight( const Image& rBmp )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Size aSize;
+ GetHeightOffset( rBmp, aSize );
+ if( aSize.Height() > nEntryHeight )
+ {
+ nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
+ pImp->SetEntryHeight( nEntryHeight );
+ }
+}
+
+void SvTreeListBox::AdjustEntryHeight( const Font& rFont )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Size aSize;
+ GetHeightOffset( rFont, aSize );
+ if( aSize.Height() > nEntryHeight )
+ {
+ nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
+ pImp->SetEntryHeight( nEntryHeight );
+ }
+}
+
+BOOL SvTreeListBox::Expand( SvLBoxEntry* pParent )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pHdlEntry = pParent;
+ BOOL bExpanded = FALSE;
+ USHORT nFlags;
+
+ if( pParent->HasChildsOnDemand() )
+ RequestingChilds( pParent );
+ if( pParent->HasChilds() )
+ {
+ nImpFlags |= SVLBOX_IS_EXPANDING;
+ if( ExpandingHdl() )
+ {
+ bExpanded = TRUE;
+ SvListView::Expand( pParent );
+ pImp->EntryExpanded( pParent );
+ pHdlEntry = pParent;
+ ExpandedHdl();
+ }
+ nFlags = pParent->GetFlags();
+ nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
+ nFlags |= SV_ENTRYFLAG_HAD_CHILDREN;
+ pParent->SetFlags( nFlags );
+ }
+ else
+ {
+ nFlags = pParent->GetFlags();
+ nFlags |= SV_ENTRYFLAG_NO_NODEBMP;
+ pParent->SetFlags( nFlags );
+ GetModel()->InvalidateEntry( pParent ); // neu zeichnen
+ }
+
+ // --> OD 2009-04-01 #i92103#
+ if ( bExpanded )
+ {
+ pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent );
+ }
+ // <--
+
+ return bExpanded;
+}
+
+BOOL SvTreeListBox::Collapse( SvLBoxEntry* pParent )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nImpFlags &= ~SVLBOX_IS_EXPANDING;
+ pHdlEntry = pParent;
+ BOOL bCollapsed = FALSE;
+
+ if( ExpandingHdl() )
+ {
+ bCollapsed = TRUE;
+ pImp->CollapsingEntry( pParent );
+ SvListView::Collapse( pParent );
+ pImp->EntryCollapsed( pParent );
+ pHdlEntry = pParent;
+ ExpandedHdl();
+ }
+
+ // --> OD 2009-04-01 #i92103#
+ if ( bCollapsed )
+ {
+ pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent );
+ }
+ // <--
+
+ return bCollapsed;
+}
+
+BOOL SvTreeListBox::Select( SvLBoxEntry* pEntry, BOOL bSelect )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pEntry,"Select: Null-Ptr");
+ BOOL bRetVal = SvListView::Select( pEntry, bSelect );
+ DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed");
+ if( bRetVal )
+ {
+ pImp->EntrySelected( pEntry, bSelect );
+ pHdlEntry = pEntry;
+ if( bSelect )
+ {
+ SelectHdl();
+ pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );
+ }
+ else
+ DeselectHdl();
+ }
+ return bRetVal;
+}
+
+ULONG SvTreeListBox::SelectChilds( SvLBoxEntry* pParent, BOOL bSelect )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->DestroyAnchor();
+ ULONG nRet = 0;
+ if( !pParent->HasChilds() )
+ return 0;
+ USHORT nRefDepth = pModel->GetDepth( pParent );
+ SvLBoxEntry* pChild = FirstChild( pParent );
+ do {
+ nRet++;
+ Select( pChild, bSelect );
+ pChild = Next( pChild );
+ } while( pChild && pModel->GetDepth( pChild ) > nRefDepth );
+ return nRet;
+}
+
+void SvTreeListBox::SelectAll( BOOL bSelect, BOOL )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->SelAllDestrAnch(
+ bSelect,
+ TRUE, // Anker loeschen,
+ TRUE ); // auch bei SINGLE_SELECTION den Cursor deselektieren
+}
+
+void SvTreeListBox::ModelHasInsertedTree( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ USHORT nRefDepth = pModel->GetDepth( (SvLBoxEntry*)pEntry );
+ SvLBoxEntry* pTmp = (SvLBoxEntry*)pEntry;
+ do
+ {
+ ImpEntryInserted( pTmp );
+ pTmp = Next( pTmp );
+ } while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) );
+ pImp->TreeInserted( (SvLBoxEntry*)pEntry );
+}
+
+void SvTreeListBox::ModelHasInserted( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ ImpEntryInserted( (SvLBoxEntry*)pEntry );
+ pImp->EntryInserted( (SvLBoxEntry*)pEntry );
+}
+
+void SvTreeListBox::ModelIsMoving(SvListEntry* pSource,
+ SvListEntry* /* pTargetParent */,
+ ULONG /* nChildPos */ )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->MovingEntry( (SvLBoxEntry*)pSource );
+}
+
+void SvTreeListBox::ModelHasMoved( SvListEntry* pSource )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->EntryMoved( (SvLBoxEntry*)pSource );
+}
+
+void SvTreeListBox::ModelIsRemoving( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if(pEdEntry == pEntry)
+ pEdEntry = NULL;
+
+ pImp->RemovingEntry( (SvLBoxEntry*)pEntry );
+ NotifyRemoving( (SvLBoxEntry*)pEntry );
+}
+
+void SvTreeListBox::ModelHasRemoved( SvListEntry* /* pEntry */ )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->EntryRemoved();
+}
+
+void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ AdjustEntryHeight( rBmp );
+ pImp->SetCollapsedNodeBmp( rBmp, _eMode );
+}
+
+void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp, BmpColorMode _eMode )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ AdjustEntryHeight( rBmp );
+ pImp->SetExpandedNodeBmp( rBmp, _eMode );
+}
+
+
+void SvTreeListBox::SetFont( const Font& rFont )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Font aTempFont( rFont );
+ aTempFont.SetTransparent( TRUE );
+ Control::SetFont( aTempFont );
+ AdjustEntryHeight( aTempFont );
+ // immer Invalidieren, sonst fallen wir
+ // bei SetEntryHeight auf die Nase
+ RecalcViewData();
+}
+
+
+void SvTreeListBox::Paint( const Rectangle& rRect )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBox::Paint( rRect );
+ if( nTreeFlags & TREEFLAG_RECALCTABS )
+ SetTabs();
+ pImp->Paint( rRect );
+}
+
+void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->MouseButtonDown( rMEvt );
+}
+
+void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->MouseButtonUp( rMEvt );
+}
+
+void SvTreeListBox::MouseMove( const MouseEvent& rMEvt )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->MouseMove( rMEvt );
+}
+
+
+void SvTreeListBox::SetUpdateMode( BOOL bUpdate )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->SetUpdateMode( bUpdate );
+}
+
+void SvTreeListBox::SetUpdateModeFast( BOOL bUpdate )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->SetUpdateModeFast( bUpdate );
+}
+
+void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( nOffsLogic != nEntryHeightOffs )
+ {
+ nEntryHeight = nEntryHeight - nEntryHeightOffs;
+ nEntryHeightOffs = (short)nOffsLogic;
+ nEntryHeight = nEntryHeight + nOffsLogic;
+ AdjustEntryHeight( GetFont() );
+ RecalcViewData();
+ pImp->SetEntryHeight( nEntryHeight );
+ }
+}
+
+void SvTreeListBox::SetCursor( SvLBoxEntry* pEntry, BOOL bForceNoSelect )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->SetCursor(pEntry, bForceNoSelect);
+}
+
+void SvTreeListBox::SetCurEntry( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ pImp->SetCurEntry( pEntry );
+}
+
+Image SvTreeListBox::GetCollapsedNodeBmp( BmpColorMode _eMode ) const
+{
+ return pImp->GetCollapsedNodeBmp( _eMode );
+}
+
+Image SvTreeListBox::GetExpandedNodeBmp( BmpColorMode _eMode ) const
+{
+ return pImp->GetExpandedNodeBmp( _eMode );
+}
+
+Point SvTreeListBox::GetEntryPosition( SvLBoxEntry* pEntry ) const
+{
+ return pImp->GetEntryPosition( pEntry );
+}
+
+void SvTreeListBox::ShowEntry( SvLBoxEntry* pEntry )
+{
+ MakeVisible( pEntry );
+}
+
+void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry )
+{
+ pImp->MakeVisible(pEntry);
+}
+
+void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry, BOOL bMoveToTop )
+{
+ pImp->MakeVisible( pEntry, bMoveToTop );
+}
+
+void SvTreeListBox::ModelHasEntryInvalidated( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ // die einzelnen Items des Entries reinitialisieren
+ SvLBox::ModelHasEntryInvalidated( pEntry );
+ // repainten
+ pImp->InvalidateEntry( (SvLBoxEntry*)pEntry );
+}
+
+void SvTreeListBox::EditItemText( SvLBoxEntry* pEntry, SvLBoxString* pItem,
+ const Selection& rSelection )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pEntry&&pItem,"EditItemText: Bad params");
+ if( IsSelected( pEntry ))
+ {
+ pImp->ShowCursor( FALSE );
+ SvListView::Select( pEntry, FALSE );
+ PaintEntry( pEntry );
+ SvListView::Select( pEntry, TRUE );
+ pImp->ShowCursor( TRUE );
+ }
+ pEdEntry = pEntry;
+ pEdItem = pItem;
+ SvLBoxTab* pTab = GetTab( pEntry, pItem );
+ DBG_ASSERT(pTab,"EditItemText:Tab not found");
+
+ Size aItemSize( pItem->GetSize(this, pEntry) );
+ Point aPos = GetEntryPosition( pEntry );
+ aPos.Y() += ( nEntryHeight - aItemSize.Height() ) / 2;
+ aPos.X() = GetTabPos( pEntry, pTab );
+ long nOutputWidth = pImp->GetOutputSize().Width();
+ Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() );
+ USHORT nPos = aTabs.GetPos( pTab );
+ if( nPos+1 < aTabs.Count() )
+ {
+ SvLBoxTab* pRightTab = (SvLBoxTab*)aTabs.GetObject( nPos + 1 );
+ long nRight = GetTabPos( pEntry, pRightTab );
+ if( nRight <= nOutputWidth )
+ aSize.Width() = nRight - aPos.X();
+ }
+ Point aOrigin( GetMapMode().GetOrigin() );
+ aPos += aOrigin; // in Win-Koord umrechnen
+ aSize.Width() -= aOrigin.X();
+ Rectangle aRect( aPos, aSize );
+#ifdef OS2
+ // Platz lassen fuer WB_BORDER
+ aRect.Left() -= 2;
+ aRect.Top() -= 3;
+ aRect.Bottom() += 3;
+#endif
+ EditText( pItem->GetText(), aRect, rSelection );
+}
+
+void SvTreeListBox::CancelEditing()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBox::CancelTextEditing();
+}
+
+void SvTreeListBox::EditEntry( SvLBoxEntry* pEntry )
+{
+ pImp->aEditClickPos = Point( -1, -1 );
+ ImplEditEntry( pEntry );
+}
+
+void SvTreeListBox::ImplEditEntry( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( IsEditingActive() )
+ EndEditing();
+ if( !pEntry )
+ pEntry = GetCurEntry();
+ if( pEntry )
+ {
+ long nClickX = pImp->aEditClickPos.X();
+ bool bIsMouseTriggered = nClickX >= 0;
+
+ SvLBoxString* pItem = NULL;
+ USHORT nCount = pEntry->ItemCount();
+ for( USHORT i = 0 ; i < nCount ; i++ )
+ {
+ SvLBoxItem* pTmpItem = pEntry->GetItem( i );
+ if( pTmpItem->IsA() != SV_ITEM_ID_LBOXSTRING )
+ continue;
+
+ SvLBoxTab* pTab = GetTab( pEntry, pTmpItem );
+ long nTabPos = pTab->GetPos();
+ long nNextTabPos = -1;
+ if( i < nCount - 1 )
+ {
+ SvLBoxItem* pNextItem = pEntry->GetItem( i + 1 );
+ SvLBoxTab* pNextTab = GetTab( pEntry, pNextItem );
+ nNextTabPos = pNextTab->GetPos();
+ }
+
+ if( pTab && pTab->IsEditable() )
+ {
+ if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) )
+ {
+ pItem = static_cast<SvLBoxString*>( pTmpItem );
+ break;
+ }
+ }
+ }
+
+ Selection aSel( SELECTION_MIN, SELECTION_MAX );
+ if( pItem && EditingEntry( pEntry, aSel ) )
+ {
+ SelectAll( FALSE );
+ MakeVisible( pEntry );
+ EditItemText( pEntry, pItem, aSel );
+ }
+ }
+}
+
+sal_Bool SvTreeListBox::AreChildrenTransient() const
+{
+ return pImp->AreChildrenTransient();
+}
+
+void SvTreeListBox::SetChildrenNotTransient()
+{
+ pImp->SetChildrenNotTransient();
+}
+
+void SvTreeListBox::EditedText( const XubString& rStr )
+
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing
+ {
+ Point aPos = GetEntryPosition( pEdEntry );
+ if( EditedEntry( pEdEntry, rStr ) )
+ {
+ ((SvLBoxString*)pEdItem)->SetText( pEdEntry, rStr );
+ pModel->InvalidateEntry( pEdEntry );
+ }
+ //if( GetSelectionMode() == SINGLE_SELECTION )
+ //{
+ if( GetSelectionCount() == 0 )
+ Select( pEdEntry );
+ if( GetSelectionMode() == MULTIPLE_SELECTION && !GetCurEntry() )
+ SetCurEntry( pEdEntry );
+ //}
+ }
+}
+
+void SvTreeListBox::EditingRequest( SvLBoxEntry* pEntry, SvLBoxItem* pItem,
+ const Point& )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( IsEditingActive() )
+ EndEditing();
+ if( pItem->IsA() == SV_ITEM_ID_LBOXSTRING )
+ {
+ Selection aSel( SELECTION_MIN, SELECTION_MAX );
+ if( EditingEntry( pEntry, aSel ) )
+ {
+ SelectAll( FALSE );
+ EditItemText( pEntry, (SvLBoxString*)pItem, aSel );
+ }
+ }
+}
+
+
+
+SvLBoxEntry* SvTreeListBox::GetDropTarget( const Point& rPos )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ // Scrollen
+ if( rPos.Y() < 12 )
+ {
+ SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, FALSE );
+ ScrollOutputArea( +1 );
+ }
+ else
+ {
+ Size aSize( pImp->GetOutputSize() );
+ if( rPos.Y() > aSize.Height() - 12 )
+ {
+ SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, FALSE );
+ ScrollOutputArea( -1 );
+ }
+ }
+
+ SvLBoxEntry* pTarget = pImp->GetEntry( rPos );
+ // bei Droppen in leere Flaeche -> den letzten Eintrag nehmen
+ if( !pTarget )
+ return (SvLBoxEntry*)LastVisible();
+ else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP) &&
+ pTarget == First() && rPos.Y() < 6 )
+ return 0;
+
+ return pTarget;
+}
+
+
+SvLBoxEntry* SvTreeListBox::GetEntry( const Point& rPos, BOOL bHit ) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxEntry* pEntry = pImp->GetEntry( rPos );
+ if( pEntry && bHit )
+ {
+ long nLine = pImp->GetEntryLine( pEntry );
+ if( !(pImp->EntryReallyHit( pEntry, rPos, nLine)) )
+ return 0;
+ }
+ return pEntry;
+}
+
+SvLBoxEntry* SvTreeListBox::GetCurEntry() const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ return pImp->GetCurEntry();
+}
+
+void SvTreeListBox::SetWindowBits( WinBits nWinStyle )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nWindowStyle = nWinStyle;
+ nTreeFlags |= TREEFLAG_RECALCTABS;
+ if( nWinStyle & WB_SORT )
+ {
+ GetModel()->SetSortMode( SortAscending );
+ GetModel()->SetCompareHdl( LINK(this,SvTreeListBox,DefaultCompare));
+ }
+ else
+ {
+ GetModel()->SetSortMode( SortNone );
+ GetModel()->SetCompareHdl( Link() );
+ }
+#ifdef OS2
+ nWinStyle |= WB_VSCROLL;
+#endif
+ pImp->SetWindowBits( nWinStyle );
+ pImp->Resize();
+ Invalidate();
+}
+
+void SvTreeListBox::PaintEntry( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pEntry,"PaintEntry:No Entry");
+ if( pEntry )
+ pImp->PaintEntry( pEntry );
+}
+
+void SvTreeListBox::InvalidateEntry( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pEntry,"InvalidateEntry:No Entry");
+ if( pEntry )
+ {
+ GetModel()->InvalidateEntry( pEntry );
+ // pImp->InvalidateEntry( pEntry );
+ }
+}
+
+
+long SvTreeListBox::PaintEntry(SvLBoxEntry* pEntry,long nLine,USHORT nTabFlags)
+{
+ return PaintEntry1(pEntry,nLine,nTabFlags);
+}
+
+#define SV_TAB_BORDER 8
+
+long SvTreeListBox::PaintEntry1(SvLBoxEntry* pEntry,long nLine,USHORT nTabFlags,
+ BOOL bHasClipRegion )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+
+ Rectangle aRect; // multi purpose
+
+ BOOL bHorSBar = pImp->HasHorScrollBar();
+ PreparePaint( pEntry );
+
+ // #97680# ------------------
+ pImp->UpdateContextBmpWidthMax( pEntry );
+
+ if( nTreeFlags & TREEFLAG_RECALCTABS )
+ SetTabs();
+
+ short nTempEntryHeight = GetEntryHeight();
+ long nWidth = pImp->GetOutputSize().Width();
+
+ // wurde innerhalb des PreparePaints die horizontale ScrollBar
+ // angeschaltet? Wenn ja, muss die ClipRegion neu gesetzt werden
+ if( !bHorSBar && pImp->HasHorScrollBar() )
+ SetClipRegion( Region(pImp->GetClipRegionRect()) );
+
+ Point aEntryPos( GetMapMode().GetOrigin() );
+ aEntryPos.X() *= -1; // Umrechnung Dokumentkoord.
+ long nMaxRight = nWidth + aEntryPos.X() - 1;
+
+ Color aBackupTextColor( GetTextColor() );
+ Font aBackupFont( GetFont() );
+ Color aBackupColor = GetFillColor();
+
+ bool bCurFontIsSel = false;
+ BOOL bInUse = pEntry->HasInUseEmphasis();
+ // wenn eine ClipRegion von aussen gesetzt wird, dann
+ // diese nicht zuruecksetzen
+ BOOL bResetClipRegion = !bHasClipRegion;
+ BOOL bHideSelection = ((nWindowStyle & WB_HIDESELECTION) && !HasFocus())!=0;
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+
+ Font aHighlightFont( GetFont() );
+ const Color aHighlightTextColor( rSettings.GetHighlightTextColor() );
+ aHighlightFont.SetColor( aHighlightTextColor );
+
+ Size aRectSize( 0, nTempEntryHeight );
+
+ if( !bHasClipRegion && nWindowStyle & WB_HSCROLL )
+ {
+ SetClipRegion( Region(pImp->GetClipRegionRect()) );
+ bHasClipRegion = TRUE;
+ }
+
+ SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry );
+
+ USHORT nTabCount = aTabs.Count();
+ USHORT nItemCount = pEntry->ItemCount();
+ USHORT nCurTab = 0;
+ USHORT nCurItem = 0;
+
+ while( nCurTab < nTabCount && nCurItem < nItemCount )
+ {
+ SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nCurTab );
+ USHORT nNextTab = nCurTab + 1;
+ SvLBoxTab* pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0;
+ SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0;
+
+ USHORT nFlags = pTab->nFlags;
+ Size aSize( pItem->GetSize( pViewDataEntry, nCurItem ));
+ long nTabPos = GetTabPos( pEntry, pTab );
+
+ long nNextTabPos;
+ if( pNextTab )
+ nNextTabPos = GetTabPos( pEntry, pNextTab );
+ else
+ {
+ nNextTabPos = nMaxRight;
+ if( nTabPos > nMaxRight )
+ nNextTabPos += 50;
+ }
+
+ long nX;
+ if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT )
+ //verhindern, das rechter Rand von der Tabtrennung abgeschnitten wird
+ nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos);
+ else
+ nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos);
+
+ if( nFlags & nTabFlags )
+ {
+ if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight )
+ {
+ SetClipRegion( Region(pImp->GetClipRegionRect()) );
+ bHasClipRegion = TRUE;
+ }
+ aEntryPos.X() = nX;
+ aEntryPos.Y() = nLine;
+
+ // Hintergrund-Muster & Farbe bestimmen
+
+ Wallpaper aWallpaper = GetBackground();
+
+ int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION;
+ USHORT nItemType = pItem->IsA();
+
+ if ( pViewDataEntry->IsSelected() && bSelTab && !pViewDataEntry->IsCursored() )
+ {
+ Color aNewWallColor = rSettings.GetHighlightColor();
+ if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP )
+ {
+ // if the face color is bright then the deactive color is also bright
+ // -> so you can't see any deactive selection
+ if ( bHideSelection && !rSettings.GetFaceColor().IsBright() &&
+ aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() )
+ aNewWallColor = rSettings.GetDeactiveColor();
+ // set font color to highlight
+ if ( !bCurFontIsSel )
+ {
+ SetTextColor( aHighlightTextColor );
+ SetFont( aHighlightFont );
+ bCurFontIsSel = true;
+ }
+ }
+ aWallpaper.SetColor( aNewWallColor );
+ }
+ else // keine Selektion
+ {
+ if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP )
+ aWallpaper.SetColor( rSettings.GetFieldColor() );
+ else if( bCurFontIsSel )
+ {
+ bCurFontIsSel = false;
+ SetTextColor( aBackupTextColor );
+ SetFont( aBackupFont );
+ }
+ }
+
+ // Hintergrund zeichnen
+ if( !(nTreeFlags & TREEFLAG_USESEL))
+ {
+ // nur den Bereich zeichnen, den das Item einnimmt
+ aRectSize.Width() = aSize.Width();
+ aRect.SetPos( aEntryPos );
+ aRect.SetSize( aRectSize );
+ }
+ else
+ {
+ // vom aktuellen bis zum naechsten Tab zeichnen
+ if( nCurTab != 0 )
+ aRect.Left() = nTabPos;
+ else
+ // beim nullten Tab immer ab Spalte 0 zeichnen
+ // (sonst Probleme bei Tabs mit Zentrierung)
+ aRect.Left() = 0;
+ aRect.Top() = nLine;
+ aRect.Bottom() = nLine + nTempEntryHeight - 1;
+ if( pNextTab )
+ {
+ long nRight;
+ nRight = GetTabPos(pEntry,pNextTab)-1;
+ if( nRight > nMaxRight )
+ nRight = nMaxRight;
+ aRect.Right() = nRight;
+ }
+ else
+ aRect.Right() = nMaxRight;
+ }
+ // bei anwenderdefinierter Selektion, die bei einer Tabposition
+ // groesser 0 beginnt den Hintergrund des 0.ten Items nicht
+ // fuellen, da sonst z.B. TablistBoxen mit Linien nicht
+ // realisiert werden koennen.
+ if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) )
+ {
+ SetFillColor( aWallpaper.GetColor() );
+ // Bei kleinen hor. Resizes tritt dieser Fall auf
+ if( aRect.Left() < aRect.Right() )
+ DrawRect( aRect );
+ }
+ // Item zeichnen
+ // vertikal zentrieren
+ aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2;
+ pItem->Paint( aEntryPos, *this, pViewDataEntry->GetFlags(), pEntry );
+
+ // Trennungslinie zwischen Tabs
+ if( pNextTab && pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
+ // nicht am rechten Fensterrand!
+ aRect.Right() < nMaxRight )
+ {
+ aRect.Left() = aRect.Right() - SV_TAB_BORDER;
+ DrawRect( aRect );
+ }
+
+ SetFillColor( aBackupColor );
+ }
+ nCurItem++;
+ nCurTab++;
+ }
+ if( pViewDataEntry->IsCursored() && !HasFocus() )
+ {
+ // Cursor-Emphasis
+ SetFillColor();
+ Color aOldLineColor = GetLineColor();
+ SetLineColor( Color( COL_BLACK ) );
+ aRect = GetFocusRect( pEntry, nLine );
+ aRect.Top()++;
+ aRect.Bottom()--;
+ DrawRect( aRect );
+ SetLineColor( aOldLineColor );
+ SetFillColor( aBackupColor );
+ }
+
+ if( bCurFontIsSel )
+ {
+ SetTextColor( aBackupTextColor );
+ SetFont( aBackupFont );
+ }
+
+ USHORT nFirstDynTabPos;
+ SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos );
+ long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab );
+ nDynTabPos += pImp->nNodeBmpTabDistance;
+ nDynTabPos += pImp->nNodeBmpWidth / 2;
+ nDynTabPos += 4; // 4 Pixel Reserve, damit die Node-Bitmap
+ // nicht zu nah am naechsten Tab steht
+
+ if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) &&
+ (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab &&
+ ( pEntry->HasChilds() || pEntry->HasChildsOnDemand() ) )
+ {
+ // ersten festen Tab suchen, und pruefen ob die Node-Bitmap
+ // in ihn hineinragt
+ USHORT nNextTab = nFirstDynTabPos;
+ SvLBoxTab* pNextTab;
+ do
+ {
+ nNextTab++;
+ pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0;
+ } while( pNextTab && pNextTab->IsDynamic() );
+
+ if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) )
+ {
+ if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0)
+ {
+ Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine );
+ aPos.X() += pImp->nNodeBmpTabDistance;
+
+ const Image* pImg = 0;
+ BmpColorMode eBitmapMode = BMP_COLOR_NORMAL;
+ if ( GetSettings().GetStyleSettings().GetHighContrastMode() )
+ eBitmapMode = BMP_COLOR_HIGHCONTRAST;
+
+ if( IsExpanded(pEntry) )
+ pImg = &pImp->GetExpandedNodeBmp( eBitmapMode );
+ else
+ {
+ if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() &&
+ (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
+ pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
+ pImg = &pImp->GetDontKnowNodeBmp( eBitmapMode );
+ else
+ pImg = &pImp->GetCollapsedNodeBmp( eBitmapMode );
+ }
+ aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2;
+
+ USHORT nStyle = 0;
+ if ( !IsEnabled() )
+ nStyle |= IMAGE_DRAW_DISABLE;
+
+ //native
+ BOOL bNativeOK = FALSE;
+ if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) )
+ {
+ ImplControlValue aControlValue;
+ Rectangle aCtrlRegion( aPos, pImg->GetSizePixel() );
+ ControlState nState = 0;
+
+ if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED;
+
+ if ( IsExpanded(pEntry) )
+ aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node
+ else
+ {
+ if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() &&
+ (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
+ pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
+ aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW );//dont know
+ else
+ aControlValue.setTristateVal( BUTTONVALUE_OFF );//collapsed node
+ }
+
+ bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL,
+ aCtrlRegion, nState, aControlValue, rtl::OUString() );
+ }
+
+ if( !bNativeOK) {
+ //non native
+ DrawImage( aPos, *pImg ,nStyle);
+ }
+ }
+ }
+ }
+
+
+ if( bHasClipRegion && bResetClipRegion )
+ SetClipRegion();
+ return 0; // nRowLen;
+}
+
+void SvTreeListBox::PreparePaint( SvLBoxEntry* )
+{
+}
+
+Rectangle SvTreeListBox::GetFocusRect( SvLBoxEntry* pEntry, long nLine )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Size aSize;
+ Rectangle aRect;
+ aRect.Top() = nLine;
+ aSize.Height() = GetEntryHeight();
+
+ long nRealWidth = pImp->GetOutputSize().Width();
+ nRealWidth -= GetMapMode().GetOrigin().X();
+
+ USHORT nCurTab;
+ SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab );
+ long nTabPos = 0;
+ if( pTab )
+ nTabPos = GetTabPos( pEntry, pTab );
+ long nNextTabPos;
+ if( pTab && nCurTab < aTabs.Count() - 1 )
+ {
+ SvLBoxTab* pNextTab = (SvLBoxTab*)aTabs.GetObject( nCurTab + 1 );
+ nNextTabPos = GetTabPos( pEntry, pNextTab );
+ }
+ else
+ {
+ nNextTabPos = nRealWidth;
+ if( nTabPos > nRealWidth )
+ nNextTabPos += 50;
+ }
+
+ BOOL bUserSelection = (BOOL)( nTreeFlags & TREEFLAG_USESEL ) != 0;
+ if( !bUserSelection )
+ {
+ if( pTab && nCurTab < pEntry->ItemCount() )
+ {
+ SvLBoxItem* pItem = pEntry->GetItem( nCurTab );
+ aSize.Width() = pItem->GetSize( this, pEntry ).Width();
+ if( !aSize.Width() )
+ aSize.Width() = 15;
+ long nX = nTabPos; //GetTabPos( pEntry, pTab );
+ // Ausrichtung
+ nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos );
+ aRect.Left() = nX;
+ // damit erster & letzter Buchstabe nicht angeknabbert werden
+ aRect.SetSize( aSize );
+ if( aRect.Left() > 0 )
+ aRect.Left()--;
+ aRect.Right()++;
+ }
+ }
+ else
+ {
+ // wenn erster SelTab != 0, dann muessen wir auch rechnen
+ if( nFocusWidth == -1 || nFirstSelTab )
+ {
+ USHORT nLastTab;
+ SvLBoxTab* pLastTab = GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab);
+ nLastTab++;
+ if( nLastTab < aTabs.Count() ) // gibts noch einen ?
+ pLastTab = (SvLBoxTab*)aTabs.GetObject( nLastTab );
+ else
+ pLastTab = 0; // ueber gesamte Breite selektieren
+ aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff;
+ nFocusWidth = (short)aSize.Width();
+ if( pTab )
+ nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos();
+ }
+ else
+ {
+ aSize.Width() = nFocusWidth;
+ if( pTab )
+ {
+ if( nCurTab )
+ aSize.Width() += nTabPos;
+ else
+ aSize.Width() += pTab->GetPos(); // Tab0 immer ab ganz links
+ }
+ }
+ // wenn Sel. beim nullten Tab anfaengt, dann ab Spalte 0 sel. zeichnen
+ if( nCurTab != 0 )
+ {
+ aRect.Left() = nTabPos;
+ aSize.Width() -= nTabPos;
+ }
+ aRect.SetSize( aSize );
+ }
+ // rechten Rand anpassen wg. Clipping
+ if( aRect.Right() >= nRealWidth )
+ {
+ aRect.Right() = nRealWidth-1;
+ nFocusWidth = (short)aRect.GetWidth();
+ }
+ return aRect;
+}
+
+
+long SvTreeListBox::GetTabPos( SvLBoxEntry* pEntry, SvLBoxTab* pTab)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pTab,"No Tab");
+ long nPos = pTab->GetPos();
+ if( pTab->IsDynamic() )
+ {
+ USHORT nDepth = pModel->GetDepth( pEntry );
+ nDepth = nDepth * (USHORT)nIndent;
+ nPos += (long)nDepth;
+ }
+ return nPos;
+}
+
+SvLBoxItem* SvTreeListBox::GetItem_Impl( SvLBoxEntry* pEntry, long nX,
+ SvLBoxTab** ppTab, USHORT nEmptyWidth )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxItem* pItemClicked = 0;
+ USHORT nTabCount = aTabs.Count();
+ USHORT nItemCount = pEntry->ItemCount();
+ SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0);
+ SvLBoxItem* pItem = pEntry->GetItem(0);
+ USHORT nNextItem = 1;
+ nX -= GetMapMode().GetOrigin().X();
+ long nRealWidth = pImp->GetOutputSize().Width();
+ nRealWidth -= GetMapMode().GetOrigin().X();
+
+ while( 1 )
+ {
+ SvLBoxTab* pNextTab=nNextItem<nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextItem) : 0;
+ long nStart = GetTabPos( pEntry, pTab );
+
+ long nNextTabPos;
+ if( pNextTab )
+ nNextTabPos = GetTabPos( pEntry, pNextTab );
+ else
+ {
+ nNextTabPos = nRealWidth;
+ if( nStart > nRealWidth )
+ nNextTabPos += 50;
+ }
+
+ Size aItemSize( pItem->GetSize(this, pEntry));
+ nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart );
+ long nLen = aItemSize.Width();
+ if( pNextTab )
+ {
+ long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart;
+ if( nTabWidth < nLen )
+ nLen = nTabWidth;
+ }
+
+ if( !nLen )
+ nLen = nEmptyWidth;
+
+ if( nX >= nStart && nX < (nStart+nLen ) )
+ {
+ pItemClicked = pItem;
+ if( ppTab )
+ {
+ *ppTab = pTab;
+ break;
+ }
+ }
+ if( nNextItem >= nItemCount || nNextItem >= nTabCount)
+ break;
+ pTab = (SvLBoxTab*)aTabs.GetObject( nNextItem );
+ pItem = pEntry->GetItem( nNextItem );
+ nNextItem++;
+ }
+ return pItemClicked;
+}
+
+SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX,SvLBoxTab** ppTab)
+{
+ return GetItem_Impl( pEntry, nX, ppTab, 0 );
+}
+
+SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ SvLBoxTab* pDummyTab;
+ return GetItem_Impl( pEntry, nX, &pDummyTab, 0 );
+}
+
+SvLBoxItem* SvTreeListBox::GetFirstDynamicItem( SvLBoxEntry* pEntry )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+
+ SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0);
+ SvLBoxItem* pItem = pEntry->GetItem(0);
+ USHORT nTabCount = aTabs.Count();
+
+ USHORT nNext = 1;
+ while ( !pTab->IsDynamic() && nNext < nTabCount )
+ {
+ pItem = pEntry->GetItem( nNext );
+ pTab = (SvLBoxTab*)aTabs.GetObject( nNext );
+ nNext++;
+ }
+ return pItem;
+}
+
+void SvTreeListBox::AddTab(long nTabPos,USHORT nFlags,void* pUserData )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nFocusWidth = -1;
+ SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags );
+ pTab->SetUserData( pUserData );
+ aTabs.Insert( pTab, aTabs.Count() );
+ if( nTreeFlags & TREEFLAG_USESEL )
+ {
+ USHORT nPos = aTabs.Count() - 1;
+ if( nPos >= nFirstSelTab && nPos <= nLastSelTab )
+ pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION;
+ else
+ // String-Items werden normalerweise immer selektiert
+ // deshalb explizit ausschalten
+ pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION;
+ }
+}
+
+
+
+SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( USHORT& rPos ) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ USHORT nCurTab = 0;
+ USHORT nTabCount = aTabs.Count();
+ while( nCurTab < nTabCount )
+ {
+ SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(nCurTab);
+ if( pTab->nFlags & SV_LBOXTAB_DYNAMIC )
+ {
+ rPos = nCurTab;
+ return pTab;
+ }
+ nCurTab++;
+ }
+ return 0;
+}
+
+SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const
+{
+ USHORT nDummy;
+ return GetFirstDynamicTab( nDummy );
+}
+
+SvLBoxTab* SvTreeListBox::GetTab( SvLBoxEntry* pEntry, SvLBoxItem* pItem) const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ USHORT nPos = pEntry->GetPos( pItem );
+ return (SvLBoxTab*)aTabs.GetObject( nPos );
+}
+
+void SvTreeListBox::ClearTabList()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ USHORT nTabCount = aTabs.Count();
+ while( nTabCount )
+ {
+ nTabCount--;
+ SvLBoxTab* pDelTab = (SvLBoxTab*)aTabs.GetObject( nTabCount );
+ delete pDelTab;
+ }
+ aTabs.Remove(0,aTabs.Count());
+}
+
+
+Size SvTreeListBox::GetOutputSizePixel() const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Size aSize = pImp->GetOutputSize();
+ return aSize;
+}
+
+void SvTreeListBox::NotifyBeginScroll()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+}
+
+void SvTreeListBox::NotifyEndScroll()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+}
+
+void SvTreeListBox::NotifyScrolling( long )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+}
+
+void SvTreeListBox::NotifyScrolled()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ aScrolledHdl.Call( this );
+}
+
+void SvTreeListBox::NotifyInvalidating()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+}
+
+void SvTreeListBox::Invalidate( USHORT nInvalidateFlags )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( nFocusWidth == -1 )
+ // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt
+ pImp->RecalcFocusRect();
+ NotifyInvalidating();
+ SvLBox::Invalidate( nInvalidateFlags );
+ pImp->Invalidate();
+}
+
+void SvTreeListBox::Invalidate( const Rectangle& rRect, USHORT nInvalidateFlags )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if( nFocusWidth == -1 )
+ // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt
+ pImp->RecalcFocusRect();
+ NotifyInvalidating();
+ SvLBox::Invalidate( rRect, nInvalidateFlags );
+}
+
+
+void SvTreeListBox::SetHighlightRange( USHORT nStart, USHORT nEnd)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+
+ USHORT nTemp;
+ nTreeFlags |= TREEFLAG_USESEL;
+ if( nStart > nEnd )
+ {
+ nTemp = nStart;
+ nStart = nEnd;
+ nEnd = nTemp;
+ }
+ // alle Tabs markieren, die im Bereich liegen
+ nTreeFlags |= TREEFLAG_RECALCTABS;
+ nFirstSelTab = nStart;
+ nLastSelTab = nEnd;
+ pImp->RecalcFocusRect();
+}
+
+void SvTreeListBox::RemoveHighlightRange()
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ nTreeFlags &= (~TREEFLAG_USESEL);
+ if( IsUpdateMode() )
+ Invalidate();
+}
+
+ULONG SvTreeListBox::GetAscInsertionPos(SvLBoxEntry*,SvLBoxEntry*)
+{
+ return LIST_APPEND;
+}
+
+ULONG SvTreeListBox::GetDescInsertionPos(SvLBoxEntry*,SvLBoxEntry*)
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ return LIST_APPEND;
+}
+
+Region SvTreeListBox::GetDragRegion() const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ Rectangle aRect;
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if( pEntry )
+ {
+ Point aPos = GetEntryPosition( pEntry );
+ aRect = ((SvTreeListBox*)this)->GetFocusRect( pEntry, aPos.Y() );
+ }
+ Region aRegion( aRect );
+ return aRegion;
+}
+
+
+void SvTreeListBox::Command( const CommandEvent& rCEvt )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ if ( !pImp->Command( rCEvt ) )
+ SvLBox::Command( rCEvt );
+}
+
+
+void SvTreeListBox::RemoveParentKeepChilds( SvLBoxEntry* pParent )
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ DBG_ASSERT(pParent,"RemoveParentKeepChilds:No Parent");
+ SvLBoxEntry* pNewParent = GetParent( pParent );
+ if( pParent->HasChilds())
+ {
+ SvLBoxEntry* pChild = FirstChild( pParent );
+ while( pChild )
+ {
+ pModel->Move( pChild, pNewParent, LIST_APPEND );
+ pChild = FirstChild( pParent );
+ }
+ }
+ pModel->Remove( pParent );
+}
+
+SvLBoxTab* SvTreeListBox::GetFirstTab( USHORT nFlagMask, USHORT& rPos )
+{
+ USHORT nTabCount = aTabs.Count();
+ for( USHORT nPos = 0; nPos < nTabCount; nPos++ )
+ {
+ SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nPos );
+ if( (pTab->nFlags & nFlagMask) )
+ {
+ rPos = nPos;
+ return pTab;
+ }
+ }
+ rPos = 0xffff;
+ return 0;
+}
+
+SvLBoxTab* SvTreeListBox::GetLastTab( USHORT nFlagMask, USHORT& rTabPos )
+{
+ short nTabCount = (short)aTabs.Count();
+ if( nTabCount )
+ {
+ for( short nPos = nTabCount-1; nPos >= 0; nPos-- )
+ {
+ SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( (USHORT)nPos );
+ if( (pTab->nFlags & nFlagMask) )
+ {
+ rTabPos = (USHORT)nPos;
+ return pTab;
+ }
+ }
+ }
+ rTabPos = 0xffff;
+ return 0;
+}
+
+void SvTreeListBox::SetAddMode( BOOL bAdd )
+{
+ pImp->SetAddMode( bAdd );
+}
+
+BOOL SvTreeListBox::IsAddMode() const
+{
+ return pImp->IsAddMode();
+}
+
+void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ if( !pImp->RequestHelp( rHEvt ) )
+ SvLBox::RequestHelp( rHEvt );
+}
+
+void SvTreeListBox::CursorMoved( SvLBoxEntry* )
+{
+}
+
+IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData )
+{
+ SvLBoxEntry* pLeft = (SvLBoxEntry*)(pData->pLeft );
+ SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight );
+ String aLeft( ((SvLBoxString*)(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
+ String aRight( ((SvLBoxString*)(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
+ // #102891# ----------------
+ pImp->UpdateIntlWrapper();
+ return pImp->pIntlWrapper->getCaseCollator()->compareString( aLeft, aRight );
+}
+
+void SvTreeListBox::ModelNotification( USHORT nActionId, SvListEntry* pEntry1,
+ SvListEntry* pEntry2, ULONG nPos )
+{
+ if( nActionId == LISTACTION_CLEARING )
+ CancelTextEditing();
+
+ SvLBox::ModelNotification( nActionId, pEntry1, pEntry2, nPos );
+ switch( nActionId )
+ {
+ case LISTACTION_INSERTED:
+ {
+ SvLBoxEntry* pEntry( dynamic_cast< SvLBoxEntry* >( pEntry1 ) );
+ ENSURE_OR_BREAK( pEntry, "SvTreeListBox::ModelNotification: invalid entry!" );
+ SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
+ if ( !pBmpItem )
+ break;
+ const Image& rBitmap1( pBmpItem->GetBitmap1() );
+ const Image& rBitmap2( pBmpItem->GetBitmap2() );
+ short nMaxWidth = short( Max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) );
+ nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth );
+ if( nMaxWidth > nContextBmpWidthMax )
+ {
+ nContextBmpWidthMax = nMaxWidth;
+ SetTabs();
+ }
+ }
+ break;
+
+ case LISTACTION_RESORTING:
+ SetUpdateMode( FALSE );
+ break;
+
+ case LISTACTION_RESORTED:
+ // nach Sortierung den ersten Eintrag anzeigen, dabei die
+ // Selektion erhalten.
+ MakeVisible( (SvLBoxEntry*)pModel->First(), TRUE );
+ SetUpdateMode( TRUE );
+ break;
+
+ case LISTACTION_CLEARED:
+ if( IsUpdateMode() )
+ Update();
+ break;
+ }
+}
+
+// bei Aenderungen SetTabs beruecksichtigen
+long SvTreeListBox::GetTextOffset() const
+{
+ DBG_CHKTHIS(SvTreeListBox,0);
+ BOOL bHasButtons = (nWindowStyle & WB_HASBUTTONS)!=0;
+ BOOL bHasButtonsAtRoot = (nWindowStyle & (WB_HASLINESATROOT |
+ WB_HASBUTTONSATROOT))!=0;
+ long nStartPos = TAB_STARTPOS;
+ long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();
+
+ long nCheckWidth = 0;
+ if( nTreeFlags & TREEFLAG_CHKBTN )
+ nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width();
+ long nCheckWidthDIV2 = nCheckWidth / 2;
+
+ long nContextWidth = nContextBmpWidthMax;
+ long nContextWidthDIV2 = nContextWidth / 2;
+
+ int nCase = NO_BUTTONS;
+ if( !(nTreeFlags & TREEFLAG_CHKBTN) )
+ {
+ if( bHasButtons )
+ nCase = NODE_BUTTONS;
+ }
+ else
+ {
+ if( bHasButtons )
+ nCase = NODE_AND_CHECK_BUTTONS;
+ else
+ nCase = CHECK_BUTTONS;
+ }
+
+ switch( nCase )
+ {
+ case NO_BUTTONS :
+ nStartPos += nContextWidthDIV2; // wg. Zentrierung
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ break;
+
+ case NODE_BUTTONS :
+ if( bHasButtonsAtRoot )
+ nStartPos += ( nIndent + (nNodeWidthPixel/2) );
+ else
+ nStartPos += nContextWidthDIV2;
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ break;
+
+ case NODE_AND_CHECK_BUTTONS :
+ if( bHasButtonsAtRoot )
+ nStartPos += ( nIndent + nNodeWidthPixel );
+ else
+ nStartPos += nCheckWidthDIV2;
+ nStartPos += nCheckWidthDIV2; // rechter Rand des CheckButtons
+ nStartPos += 3; // Abstand CheckButton Context-Bmp
+ nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ // Abstand setzen nur wenn Bitmaps da
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ break;
+
+ case CHECK_BUTTONS :
+ nStartPos += nCheckWidthDIV2;
+ nStartPos += nCheckWidthDIV2; // rechter Rand CheckButton
+ nStartPos += 3; // Abstand CheckButton Context-Bmp
+ nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp
+ nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp
+ if( nContextBmpWidthMax )
+ nStartPos += 5; // Abstand Context-Bmp - Text
+ break;
+ }
+ return nStartPos;
+}
+
+void SvTreeListBox::EndSelection()
+{
+ pImp->EndSelection();
+}
+
+BOOL SvTreeListBox::IsNodeButton( const Point& rPos ) const
+{
+ SvLBoxEntry* pEntry = GetEntry( rPos );
+ if( pEntry )
+ return pImp->IsNodeButton( rPos, pEntry );
+ return FALSE;
+}
+
+void SvTreeListBox::RepaintScrollBars() const
+{
+ ((SvTreeListBox*)this)->pImp->RepaintScrollBars();
+}
+
+ScrollBar *SvTreeListBox::GetVScroll()
+{
+ return &((SvTreeListBox*)this)->pImp->aVerSBar;
+}
+
+ScrollBar *SvTreeListBox::GetHScroll()
+{
+ return &((SvTreeListBox*)this)->pImp->aHorSBar;
+}
+
+void SvTreeListBox::EnableAsyncDrag( BOOL b )
+{
+ pImp->EnableAsyncDrag( b );
+}
+
+SvLBoxEntry* SvTreeListBox::GetFirstEntryInView() const
+{
+ Point aPos;
+ return GetEntry( aPos );
+}
+
+SvLBoxEntry* SvTreeListBox::GetNextEntryInView(SvLBoxEntry* pEntry ) const
+{
+ SvLBoxEntry* pNext = (SvLBoxEntry*)NextVisible( pEntry );
+ if( pNext )
+ {
+ Point aPos( GetEntryPosition(pNext) );
+ const Size& rSize = pImp->GetOutputSize();
+ if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() )
+ return 0;
+ }
+ return pNext;
+}
+
+void SvTreeListBox::ShowFocusRect( const SvLBoxEntry* pEntry )
+{
+ pImp->ShowFocusRect( pEntry );
+}
+
+void SvTreeListBox::SetTabBar( TabBar* pTabBar )
+{
+ pImp->SetTabBar( pTabBar );
+}
+
+void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ nEntryHeight = 0; // _together_ with TRUE of 1. par (bFont) of InitSettings() a zero-height
+ // forces complete recalc of heights!
+ InitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+ else
+ Control::DataChanged( rDCEvt );
+}
+
+void SvTreeListBox::InitSettings(BOOL bFont,BOOL bForeground,BOOL bBackground)
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetFieldFont();
+ aFont.SetColor( rStyleSettings.GetWindowTextColor() );
+ SetPointFont( aFont );
+ AdjustEntryHeight( aFont );
+ RecalcViewData();
+ }
+
+ if( bForeground || bFont )
+ {
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+ SetTextFillColor();
+ }
+
+ if( bBackground )
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ // always try to re-create default-SvLBoxButtonData
+ if( pCheckButtonData && pCheckButtonData->HasDefaultImages() )
+ pCheckButtonData->SetDefaultImages( this );
+}
+
+BOOL SvTreeListBox::IsCellFocusEnabled() const
+{
+ return pImp->IsCellFocusEnabled();
+}
+
+bool SvTreeListBox::SetCurrentTabPos( USHORT _nNewPos )
+{
+ return pImp->SetCurrentTabPos( _nNewPos );
+}
+
+USHORT SvTreeListBox::GetCurrentTabPos() const
+{
+ return pImp->GetCurrentTabPos();
+}
+
+void SvTreeListBox::InitStartEntry()
+{
+ if( !pImp->pStartEntry )
+ pImp->pStartEntry = GetModel()->First();
+}
+
+void SvTreeListBox::CancelPendingEdit()
+{
+ if( pImp )
+ pImp->CancelPendingEdit();
+}
+
+PopupMenu* SvTreeListBox::CreateContextMenu( void )
+{
+ return NULL;
+}
+
+void SvTreeListBox::ExcecuteContextMenuAction( USHORT )
+{
+ DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
+}
+
+void SvTreeListBox::EnableContextMenuHandling( void )
+{
+ DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
+
+ pImp->bContextMenuHandling = TRUE;
+}
+
+void SvTreeListBox::EnableContextMenuHandling( BOOL b )
+{
+ DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
+
+ pImp->bContextMenuHandling = b;
+}
+
+BOOL SvTreeListBox::IsContextMenuHandlingEnabled( void ) const
+{
+ DBG_ASSERT( pImp, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" );
+
+ return pImp->bContextMenuHandling;
+}
+
+void SvTreeListBox::EnableList( bool _bEnable )
+{
+ // call base class method
+ Window::Enable( _bEnable != false );
+ // then paint immediately
+ Paint( Rectangle( Point(), GetSizePixel() ) );
+}
+
+::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible()
+{
+ Window* pParent = GetAccessibleParentWindow();
+ DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" );
+
+ ::com::sun::star::uno::Reference< XAccessible > xAccessible;
+ if ( pParent )
+ {
+ ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
+ if ( xAccParent.is() )
+ {
+ // need to be done here to get the vclxwindow later on in the accessbile
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface());
+ xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent );
+ }
+ }
+ return xAccessible;
+}
+
+void SvTreeListBox::FillAccessibleEntryStateSet( SvLBoxEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const
+{
+ DBG_ASSERT( pEntry, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" );
+
+ if ( pEntry->HasChildsOnDemand() || pEntry->HasChilds() )
+ {
+ rStateSet.AddState( AccessibleStateType::EXPANDABLE );
+ if ( IsExpanded( pEntry ) )
+ rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED );
+ }
+
+ if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED )
+ rStateSet.AddState( AccessibleStateType::CHECKED );
+ if ( IsEntryVisible( pEntry ) )
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ if ( IsSelected( pEntry ) )
+ rStateSet.AddState( AccessibleStateType::SELECTED );
+}
+
+Rectangle SvTreeListBox::GetBoundingRect( SvLBoxEntry* pEntry )
+{
+ Point aPos = GetEntryPosition( pEntry );
+ Rectangle aRect = GetFocusRect( pEntry, aPos.Y() );
+ return aRect;
+}
+
+void SvTreeListBox::EnableCellFocus()
+{
+ pImp->EnableCellFocus();
+}
+
+void SvTreeListBox::CallImplEventListeners(ULONG nEvent, void* pData)
+{
+ CallEventListeners(nEvent, pData);
+}
+
+void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet ) const
+{
+ SvLBox::FillAccessibleStateSet( rStateSet );
+}
diff --git a/svtools/source/contnr/templwin.cxx b/svtools/source/contnr/templwin.cxx
new file mode 100644
index 000000000000..61112f6669ca
--- /dev/null
+++ b/svtools/source/contnr/templwin.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_svtools.hxx"
+#include "templwin.hxx"
+#include "templdlg.hxx"
+#include <svtools/svtdata.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/dynamicmenuoptions.hxx>
+#include <unotools/extendedsecurityoptions.hxx>
+#include <svtools/xtextedt.hxx>
+#include <svl/inettype.hxx>
+#include "imagemgr.hxx"
+#include <svtools/miscopt.hxx>
+#include "templatefoldercache.hxx"
+#include "imgdef.hxx"
+#include "txtattr.hxx"
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#ifndef _SVTOOLS_TEMPLWIN_HRC
+#include "templwin.hrc"
+#endif
+#ifndef _SVT_HELPID_HRC
+#include <svtools/helpid.hrc>
+#endif
+#include <unotools/pathoptions.hxx>
+#include <unotools/viewoptions.hxx>
+#include <unotools/ucbhelper.hxx>
+
+#include "unotools/configmgr.hxx"
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDocumentTemplates.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <unotools/localedatawrapper.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <vcl/waitobj.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/datetime.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/split.hxx>
+#include <vcl/msgbox.hxx>
+#include "DocumentInfoPreview.hxx"
+#include <vcl/mnemonic.hxx>
+
+#include <ucbhelper/content.hxx>
+#include <comphelper/string.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::view;
+using namespace svtools;
+
+extern ::rtl::OUString CreateExactSizeText_Impl( sal_Int64 nSize ); // fileview.cxx
+
+#define SPLITSET_ID 0
+#define COLSET_ID 1
+#define ICONWIN_ID 2
+#define FILEWIN_ID 3
+#define FRAMEWIN_ID 4
+
+#define ICON_POS_NEWDOC 0
+#define ICON_POS_TEMPLATES 1
+#define ICON_POS_MYDOCS 2
+#define ICON_POS_SAMPLES 3
+
+#define ASCII_STR(s) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) )
+#define VIEWSETTING_NEWFROMTEMPLATE ASCII_STR("NewFromTemplate")
+#define VIEWSETTING_SELECTEDGROUP ASCII_STR("SelectedGroup")
+#define VIEWSETTING_SELECTEDVIEW ASCII_STR("SelectedView")
+#define VIEWSETTING_SPLITRATIO ASCII_STR("SplitRatio")
+#define VIEWSETTING_LASTFOLDER ASCII_STR("LastFolder")
+
+struct FolderHistory
+{
+ String m_sURL;
+ ULONG m_nGroup;
+
+ FolderHistory( const String& _rURL, sal_Int32 _nGroup ) :
+ m_sURL( _rURL ), m_nGroup( _nGroup ) {}
+};
+
+DECLARE_LIST( HistoryList_Impl, FolderHistory* )
+DECLARE_LIST( NewDocList_Impl, ::rtl::OUString* )
+
+ODocumentInfoPreview::ODocumentInfoPreview( Window* pParent ,WinBits _nBits) : Window(pParent,WB_DIALOGCONTROL)
+{
+ m_pEditWin = new SvtExtendedMultiLineEdit_Impl(this,_nBits);
+ m_pEditWin->Show();
+ m_pEditWin->EnableCursor( FALSE );
+ m_pInfoTable = new SvtDocInfoTable_Impl();
+ // detect application language
+ m_aLocale = SvtPathOptions().GetLocale();
+}
+// -----------------------------------------------------------------------------
+ODocumentInfoPreview::~ODocumentInfoPreview()
+{
+ delete m_pEditWin;
+ delete m_pInfoTable;
+}
+// -----------------------------------------------------------------------------
+void ODocumentInfoPreview::Resize()
+{
+ Size aOutputSize( GetOutputSize() );
+ m_pEditWin->SetPosSizePixel( Point(0,0),aOutputSize);
+}
+// -----------------------------------------------------------------------------
+void ODocumentInfoPreview::Clear()
+{
+ m_pEditWin->Clear();
+}
+// -----------------------------------------------------------------------------
+
+void lcl_insertDateTimeEntry(SvtExtendedMultiLineEdit_Impl* i_pEditWin,
+ const ::rtl::OUString & i_rName, const util::DateTime & i_rUDT)
+{
+ DateTime aToolsDT =
+ DateTime( Date( i_rUDT.Day, i_rUDT.Month, i_rUDT.Year ),
+ Time( i_rUDT.Hours, i_rUDT.Minutes,
+ i_rUDT.Seconds, i_rUDT.HundredthSeconds ) );
+ if ( aToolsDT.IsValid() )
+ {
+ LocaleDataWrapper aLocaleWrapper(
+ ::comphelper::getProcessServiceFactory(),
+ Application::GetSettings().GetLocale() );
+ String aDateStr = aLocaleWrapper.getDate( aToolsDT );
+ aDateStr += String( RTL_CONSTASCII_STRINGPARAM(", ") );
+ aDateStr += aLocaleWrapper.getTime( aToolsDT );
+ i_pEditWin->InsertEntry( i_rName, aDateStr );
+ }
+}
+
+void ODocumentInfoPreview::fill(
+ const Reference< XDocumentProperties >& i_xDocProps, const String& i_rURL)
+{
+ if (!i_xDocProps.is()) throw RuntimeException();
+
+ ::rtl::OUString aStr;
+ m_pEditWin->SetAutoScroll( FALSE );
+
+ aStr = i_xDocProps->getTitle();
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_TITLE ), aStr );
+ }
+
+ aStr = i_xDocProps->getAuthor();
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_FROM ), aStr );
+ }
+
+ lcl_insertDateTimeEntry(m_pEditWin,
+ m_pInfoTable->GetString( DI_DATE ),
+ i_xDocProps->getCreationDate());
+
+ aStr = i_xDocProps->getModifiedBy();
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString(DI_MODIFIEDBY), aStr );
+ }
+
+ lcl_insertDateTimeEntry(m_pEditWin,
+ m_pInfoTable->GetString( DI_MODIFIEDDATE ),
+ i_xDocProps->getModificationDate());
+
+ aStr = i_xDocProps->getPrintedBy();
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_PRINTBY ), aStr );
+ }
+
+ lcl_insertDateTimeEntry(m_pEditWin,
+ m_pInfoTable->GetString( DI_PRINTDATE ),
+ i_xDocProps->getPrintDate());
+
+ aStr = i_xDocProps->getSubject();
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_THEME ), aStr );
+ }
+
+ aStr =
+ ::comphelper::string::convertCommaSeparated(i_xDocProps->getKeywords());
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_KEYWORDS ), aStr );
+ }
+
+ aStr = i_xDocProps->getDescription();
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_DESCRIPTION ),
+ aStr );
+ }
+
+ // size
+ if ( i_rURL.Len() > 0 )
+ {
+ ULONG nDocSize = ::utl::UCBContentHelper::GetSize( i_rURL );
+ m_pEditWin->InsertEntry(
+ m_pInfoTable->GetString( DI_SIZE ),
+ CreateExactSizeText_Impl( nDocSize ) );
+ }
+
+ // MIMEType
+ if ( i_rURL.Len() > 0 )
+ {
+ INetContentType eTypeID =
+ INetContentTypes::GetContentTypeFromURL( i_rURL );
+ if ( eTypeID != CONTENT_TYPE_APP_OCTSTREAM ) {
+ aStr = INetContentTypes::GetPresentation( eTypeID, m_aLocale );
+ } else {
+ aStr = SvFileInformationManager::GetDescription(
+ INetURLObject(i_rURL) );
+ }
+ if (aStr.getLength()) {
+ m_pEditWin->InsertEntry( m_pInfoTable->GetString( DI_MIMETYPE ),
+ aStr );
+ }
+ }
+
+ // user-defined (custom) properties
+ Reference< XPropertySet > xUserDefined(
+ i_xDocProps->getUserDefinedProperties(), UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xUDInfo = xUserDefined->getPropertySetInfo();
+ Sequence< Property > props = xUDInfo->getProperties();
+ for (sal_Int32 i = 0; i < props.getLength(); ++i) {
+ const ::rtl::OUString name = props[i].Name;
+ uno::Any aAny;
+ try {
+ aAny = xUserDefined->getPropertyValue(name);
+ uno::Reference < script::XTypeConverter > xConverter(
+ comphelper::getProcessServiceFactory()->createInstance(
+ ASCII_STR("com.sun.star.script.Converter")),
+ UNO_QUERY );
+ uno::Any aNew;
+ aNew = xConverter->convertToSimpleType( aAny, TypeClass_STRING );
+ if ((aNew >>= aStr) && aStr.getLength()) {
+ m_pEditWin->InsertEntry( name, aStr);
+ }
+ } catch (uno::Exception &) {
+ // ignore
+ }
+ }
+
+ m_pEditWin->SetSelection( Selection( 0, 0 ) );
+ m_pEditWin->SetAutoScroll( TRUE );
+}
+
+// -----------------------------------------------------------------------------
+void ODocumentInfoPreview::InsertEntry( const String& rTitle, const String& rValue )
+{
+ m_pEditWin->InsertEntry( rTitle, rValue);
+}
+// -----------------------------------------------------------------------------
+
+// class SvtDummyHeaderBar_Impl ------------------------------------------
+
+void SvtDummyHeaderBar_Impl::UpdateBackgroundColor()
+{
+ SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetWindowColor() ) );
+}
+
+SvtDummyHeaderBar_Impl::SvtDummyHeaderBar_Impl( Window* pPar ) : Window( pPar )
+{
+ SetSizePixel( HeaderBar( this, 0 ).CalcWindowSizePixel() ); // HeaderBar used only to calculate size
+
+ UpdateBackgroundColor();
+}
+
+SvtDummyHeaderBar_Impl::~SvtDummyHeaderBar_Impl()
+{
+}
+
+void SvtDummyHeaderBar_Impl::DataChanged( const DataChangedEvent& r )
+{
+ Window::DataChanged( r );
+ if( r.GetType() == DATACHANGED_SETTINGS )
+ UpdateBackgroundColor();
+}
+
+// class SvtIconWindow_Impl ----------------------------------------------
+
+SvtIconWindow_Impl::SvtIconWindow_Impl( Window* pParent ) :
+
+ Window( pParent, WB_DIALOGCONTROL | WB_BORDER | WB_3DLOOK ),
+
+ aDummyHeaderBar( this ),
+ aIconCtrl( this, WB_ICON | WB_NOCOLUMNHEADER | WB_HIGHLIGHTFRAME | /*!WB_NOSELECTION |*/
+ WB_NODRAGSELECTION | WB_TABSTOP | WB_CLIPCHILDREN ),
+ aNewDocumentRootURL( ASCII_STR("private:newdoc") ),
+ aMyDocumentsRootURL( SvtPathOptions().GetWorkPath() ),
+ aSamplesFolderRootURL( SvtPathOptions().
+ SubstituteVariable( String( ASCII_STR("$(insturl)/share/samples/$(vlang)") ) ) ),
+ nMaxTextLength( 0 )
+
+{
+ aDummyHeaderBar.Show();
+
+ aIconCtrl.SetAccessibleName( String( RTL_CONSTASCII_USTRINGPARAM("Groups") ) );
+ aIconCtrl.SetHelpId( HID_TEMPLATEDLG_ICONCTRL );
+ aIconCtrl.SetChoiceWithCursor( TRUE );
+ aIconCtrl.SetSelectionMode( SINGLE_SELECTION );
+ aIconCtrl.Show();
+
+ // detect the root URL of templates
+ Reference< XDocumentTemplates > xTemplates( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.frame.DocumentTemplates") ), UNO_QUERY );
+
+ if ( xTemplates.is() )
+ {
+ Reference < XContent > aRootContent = xTemplates->getContent();
+ Reference < XCommandEnvironment > aCmdEnv;
+
+ if ( aRootContent.is() )
+ aTemplateRootURL = aRootContent->getIdentifier()->getContentIdentifier();
+ }
+
+ // insert the categories
+ // "New Document"
+ sal_Bool bHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
+ Image aImage( SvtResId( bHiContrast ? IMG_SVT_NEWDOC_HC : IMG_SVT_NEWDOC ) );
+ nMaxTextLength = aImage.GetSizePixel().Width();
+ String aEntryStr = String( SvtResId( STR_SVT_NEWDOC ) );
+ SvxIconChoiceCtrlEntry* pEntry =
+ aIconCtrl.InsertEntry( aEntryStr, aImage, ICON_POS_NEWDOC );
+ pEntry->SetUserData( new String( aNewDocumentRootURL ) );
+ pEntry->SetQuickHelpText( String( SvtResId( STR_SVT_NEWDOC_HELP ) ) );
+ DBG_ASSERT( !pEntry->GetBoundRect().IsEmpty(), "empty rectangle" );
+ long nTemp = pEntry->GetBoundRect().GetSize().Width();
+ if (nTemp > nMaxTextLength)
+ nMaxTextLength = nTemp;
+
+ // "Templates"
+ if( aTemplateRootURL.Len() > 0 )
+ {
+ aEntryStr = String( SvtResId( STR_SVT_TEMPLATES ) );
+ pEntry = aIconCtrl.InsertEntry(
+ aEntryStr, Image( SvtResId( bHiContrast ? IMG_SVT_TEMPLATES_HC : IMG_SVT_TEMPLATES ) ), ICON_POS_TEMPLATES );
+ pEntry->SetUserData( new String( aTemplateRootURL ) );
+ pEntry->SetQuickHelpText( String( SvtResId( STR_SVT_TEMPLATES_HELP ) ) );
+ DBG_ASSERT( !pEntry->GetBoundRect().IsEmpty(), "empty rectangle" );
+ nTemp = pEntry->GetBoundRect().GetSize().Width();
+ if (nTemp > nMaxTextLength)
+ nMaxTextLength = nTemp;
+ }
+
+ // "My Documents"
+ aEntryStr = String( SvtResId( STR_SVT_MYDOCS ) );
+ pEntry = aIconCtrl.InsertEntry(
+ aEntryStr, Image( SvtResId( bHiContrast ? IMG_SVT_MYDOCS_HC : IMG_SVT_MYDOCS ) ), ICON_POS_MYDOCS );
+ pEntry->SetUserData( new String( aMyDocumentsRootURL ) );
+ pEntry->SetQuickHelpText( String( SvtResId( STR_SVT_MYDOCS_HELP ) ) );
+ DBG_ASSERT( !pEntry->GetBoundRect().IsEmpty(), "empty rectangle" );
+ nTemp = pEntry->GetBoundRect().GetSize().Width();
+ if( nTemp > nMaxTextLength )
+ nMaxTextLength = nTemp;
+
+ // "Samples"
+ aEntryStr = String( SvtResId( STR_SVT_SAMPLES ) );
+ pEntry = aIconCtrl.InsertEntry(
+ aEntryStr, Image( SvtResId( bHiContrast ? IMG_SVT_SAMPLES_HC : IMG_SVT_SAMPLES ) ), ICON_POS_SAMPLES );
+ pEntry->SetUserData( new String( aSamplesFolderRootURL ) );
+ pEntry->SetQuickHelpText( String( SvtResId( STR_SVT_SAMPLES_HELP ) ) );
+ DBG_ASSERT( !pEntry->GetBoundRect().IsEmpty(), "empty rectangle" );
+ nTemp = pEntry->GetBoundRect().GetSize().Width();
+ if (nTemp > nMaxTextLength)
+ nMaxTextLength = nTemp;
+
+ aIconCtrl.CreateAutoMnemonics();
+}
+
+SvtIconWindow_Impl::~SvtIconWindow_Impl()
+{
+ for ( ULONG i = 0; i < aIconCtrl.GetEntryCount(); ++i )
+ {
+ SvxIconChoiceCtrlEntry* pEntry = aIconCtrl.GetEntry( i );
+ delete (String*)pEntry->GetUserData();
+ }
+}
+
+SvxIconChoiceCtrlEntry* SvtIconWindow_Impl::GetEntry( const String& rURL ) const
+{
+ SvxIconChoiceCtrlEntry* pEntry = NULL;
+ for ( ULONG i = 0; i < aIconCtrl.GetEntryCount(); ++i )
+ {
+ SvxIconChoiceCtrlEntry* pTemp = aIconCtrl.GetEntry( i );
+ String aURL( *( (String*)pTemp->GetUserData() ) );
+ if ( aURL == rURL )
+ {
+ pEntry = pTemp;
+ break;
+ }
+ }
+
+ return pEntry;
+}
+
+void SvtIconWindow_Impl::Resize()
+{
+ Size aWinSize = GetOutputSizePixel();
+ Size aHeaderSize = aDummyHeaderBar.GetSizePixel();
+ aHeaderSize.Width() = aWinSize.Width();
+ aDummyHeaderBar.SetSizePixel( aHeaderSize );
+ long nHeaderHeight = aHeaderSize.Height();
+ aWinSize.Height() -= nHeaderHeight;
+ aIconCtrl.SetPosSizePixel( Point( 0, nHeaderHeight ), aWinSize );
+ aIconCtrl.ArrangeIcons();
+}
+
+String SvtIconWindow_Impl::GetCursorPosIconURL() const
+{
+ String aURL;
+ SvxIconChoiceCtrlEntry* pEntry = aIconCtrl.GetCursor( );
+ if ( pEntry )
+ aURL = *static_cast<String*>(pEntry->GetUserData());
+ return aURL;
+
+}
+
+String SvtIconWindow_Impl::GetSelectedIconURL() const
+{
+ ULONG nPos;
+ SvxIconChoiceCtrlEntry* pEntry = aIconCtrl.GetSelectedEntry( nPos );
+ String aURL;
+ if ( pEntry )
+ aURL = *static_cast<String*>(pEntry->GetUserData());
+ return aURL;
+}
+
+String SvtIconWindow_Impl::GetSelectedIconText() const
+{
+ ULONG nPos;
+ return MnemonicGenerator::EraseAllMnemonicChars( aIconCtrl.GetSelectedEntry( nPos )->GetText() );
+}
+
+String SvtIconWindow_Impl::GetIconText( const String& rURL ) const
+{
+ String aText;
+ SvxIconChoiceCtrlEntry* pEntry = GetEntry( rURL );
+ if ( pEntry )
+ aText = MnemonicGenerator::EraseAllMnemonicChars( pEntry->GetText() );
+ return aText;
+}
+
+void SvtIconWindow_Impl::InvalidateIconControl()
+{
+ aIconCtrl.Invalidate();
+}
+
+ULONG SvtIconWindow_Impl::GetCursorPos() const
+{
+ ULONG nPos = ~ULONG(0);
+
+ SvxIconChoiceCtrlEntry* pCursorEntry = aIconCtrl.GetCursor( );
+ if ( pCursorEntry )
+ nPos = aIconCtrl.GetEntryListPos( pCursorEntry );
+
+ return nPos;
+}
+
+ULONG SvtIconWindow_Impl::GetSelectEntryPos() const
+{
+ ULONG nPos;
+ if ( !aIconCtrl.GetSelectedEntry( nPos ) )
+ nPos = ~ULONG(0);
+ return nPos;
+}
+
+void SvtIconWindow_Impl::SetCursorPos( ULONG nPos )
+{
+ SvxIconChoiceCtrlEntry* pEntry = aIconCtrl.GetEntry( nPos );
+ aIconCtrl.SetCursor( pEntry );
+ aIconCtrl.Invalidate();
+ aIconCtrl.Update();
+}
+
+void SvtIconWindow_Impl::SetFocus()
+{
+ aIconCtrl.GrabFocus();
+}
+
+long SvtIconWindow_Impl::CalcHeight() const
+{
+ // calculate the required height of the IconControl
+ long nHeight = 0;
+ ULONG nCount = aIconCtrl.GetEntryCount();
+ if ( nCount > 0 )
+ // bottom of the last icon
+ nHeight = aIconCtrl.GetEntry(nCount-1)->GetBoundRect().Bottom();
+
+ // + headerbar height
+ nHeight += aDummyHeaderBar.GetSizePixel().Height();
+
+ return nHeight;
+}
+
+sal_Bool SvtIconWindow_Impl::IsRootURL( const String& rURL ) const
+{
+ return rURL == aNewDocumentRootURL ||
+ rURL == aTemplateRootURL ||
+ rURL == aMyDocumentsRootURL ||
+ rURL == aSamplesFolderRootURL;
+}
+
+ULONG SvtIconWindow_Impl::GetRootPos( const String& rURL ) const
+{
+ ULONG nPos = ~ULONG(0);
+ if ( aNewDocumentRootURL.Match( rURL ) == STRING_MATCH )
+ nPos = 0;
+ else if ( aTemplateRootURL.Match( rURL ) == STRING_MATCH )
+ nPos = 1;
+ else if ( aMyDocumentsRootURL.Match( rURL ) == STRING_MATCH )
+ nPos = 2;
+ else if ( aSamplesFolderRootURL.Match( rURL ) == STRING_MATCH )
+ nPos = 3;
+ else if ( rURL.Match( aMyDocumentsRootURL ) == STRING_MATCH )
+ nPos = 2;
+ else
+ {
+ DBG_WARNING( "SvtIconWindow_Impl::GetRootPos(): invalid position" );
+ nPos = 2;
+ }
+
+ return nPos;
+}
+
+void SvtIconWindow_Impl::UpdateIcons( sal_Bool _bHiContrast )
+{
+ aIconCtrl.GetEntry( ICON_POS_NEWDOC )->SetImage(
+ Image( SvtResId( _bHiContrast ? IMG_SVT_NEWDOC_HC : IMG_SVT_NEWDOC ) ) );
+ aIconCtrl.GetEntry( ICON_POS_TEMPLATES )->SetImage(
+ Image( SvtResId( _bHiContrast ? IMG_SVT_TEMPLATES_HC : IMG_SVT_TEMPLATES ) ) );
+ aIconCtrl.GetEntry( ICON_POS_MYDOCS )->SetImage(
+ Image( SvtResId( _bHiContrast ? IMG_SVT_MYDOCS_HC : IMG_SVT_MYDOCS ) ) );
+ aIconCtrl.GetEntry( ICON_POS_SAMPLES )->SetImage(
+ Image( SvtResId( _bHiContrast ? IMG_SVT_SAMPLES_HC : IMG_SVT_SAMPLES ) ) );
+}
+/* -----------------27.11.2002 16:58-----------------
+ *
+ * --------------------------------------------------*/
+void SvtIconWindow_Impl::SelectFolder(sal_Int32 nFolderPosition)
+{
+ SvxIconChoiceCtrlEntry* pEntry = aIconCtrl.GetEntry( nFolderPosition );
+ if(pEntry)
+ {
+ aIconCtrl.SetCursor( pEntry );
+ aIconCtrl.GetClickHdl().Call(&aIconCtrl);
+ }
+}
+
+// class SvtFileViewWindow_Impl -----------------------------------------_
+
+SvtFileViewWindow_Impl::SvtFileViewWindow_Impl( SvtTemplateWindow* pParent ) :
+
+ Window( pParent, WB_DIALOGCONTROL | WB_TABSTOP | WB_BORDER | WB_3DLOOK ),
+
+ rParent ( *pParent ),
+ aFileView ( this, SvtResId( CTRL_FILEVIEW ), FILEVIEW_SHOW_TITLE ),
+ bIsTemplateFolder ( sal_False )
+
+{
+ aFileView.SetStyle( aFileView.GetStyle() | WB_DIALOGCONTROL | WB_TABSTOP );
+ aFileView.SetHelpId( HID_TEMPLATEDLG_FILEVIEW );
+ aFileView.Show();
+ aFileView.SetPosPixel( Point( 0, 0 ) );
+ aFileView.EnableAutoResize();
+ aFileView.EnableContextMenu( sal_False );
+ aFileView.EnableDelete( sal_False );
+}
+
+SvtFileViewWindow_Impl::~SvtFileViewWindow_Impl()
+{
+}
+
+void GetMenuEntry_Impl
+(
+ Sequence< PropertyValue >& aDynamicMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rFrame,
+ ::rtl::OUString& rImageId
+)
+{
+ for ( int i = 0; i < aDynamicMenuEntry.getLength(); i++ )
+ {
+ if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_URL )
+ aDynamicMenuEntry[i].Value >>= rURL;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_TITLE )
+ aDynamicMenuEntry[i].Value >>= rTitle;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER )
+ aDynamicMenuEntry[i].Value >>= rImageId;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_TARGETNAME )
+ aDynamicMenuEntry[i].Value >>= rFrame;
+ }
+}
+Sequence< ::rtl::OUString > SvtFileViewWindow_Impl::GetNewDocContents() const
+{
+ NewDocList_Impl aNewDocs;
+ Sequence< Sequence< PropertyValue > > aDynamicMenuEntries;
+ aDynamicMenuEntries = SvtDynamicMenuOptions().GetMenu( E_NEWMENU );
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aImageURL;
+ ::rtl::OUString aTargetFrame;
+
+ UINT32 i, nCount = aDynamicMenuEntries.getLength();
+ ::rtl::OUString sSeparator( ASCII_STR("private:separator") );
+ ::rtl::OUString sSlotURL( ASCII_STR("slot:5500") );
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ GetMenuEntry_Impl( aDynamicMenuEntries[i], aTitle, aURL, aTargetFrame, aImageURL );
+
+ if ( aURL == sSeparator || aURL == sSlotURL )
+ continue;
+ else
+ {
+ // title
+ String aRow = MnemonicGenerator::EraseAllMnemonicChars( String( aTitle ) );
+ aRow += '\t';
+ // no type
+ aRow += '\t';
+ // no size
+ aRow += '\t';
+ // no date
+ aRow += '\t';
+ // url
+ aRow += String( aURL );
+ aRow += '\t';
+ // folder == false
+ aRow += '0';
+ // image url?
+ if ( aImageURL.getLength() > 0 )
+ {
+ aRow += '\t';
+ aRow += String( aImageURL );
+ }
+
+ ::rtl::OUString* pRow = new ::rtl::OUString( aRow );
+ aNewDocs.Insert( pRow, LIST_APPEND );
+ }
+ }
+
+ nCount = aNewDocs.Count();
+ Sequence < ::rtl::OUString > aRet( nCount );
+ ::rtl::OUString* pRet = aRet.getArray();
+ for ( i = 0; i < nCount; ++i )
+ {
+ ::rtl::OUString* pNewDoc = aNewDocs.GetObject(i);
+ pRet[i] = *( pNewDoc );
+ delete pNewDoc;
+ }
+
+ return aRet;
+}
+
+void SvtFileViewWindow_Impl::Resize()
+{
+ Size aWinSize = GetOutputSizePixel();
+
+ static int x = 0;
+ static int y = 0;
+
+ aWinSize.nA += x;
+ aWinSize.nB += y;
+ aFileView.SetSizePixel( aWinSize );
+}
+
+String SvtFileViewWindow_Impl::GetSelectedFile() const
+{
+ return aFileView.GetCurrentURL();
+}
+
+void SvtFileViewWindow_Impl::OpenFolder( const String& rURL )
+{
+ aFolderURL = rURL;
+
+ rParent.SetPrevLevelButtonState( rURL );
+
+ aFileView.SetUrlFilter( &aURLFilter );
+
+ INetProtocol eProt = INetURLObject( rURL ).GetProtocol();
+ bIsTemplateFolder = ( eProt == INET_PROT_VND_SUN_STAR_HIER );
+ bool isNewDocumentFolder = ( eProt == INET_PROT_PRIVATE );
+
+ aURLFilter.enableFilter( !bIsTemplateFolder && !isNewDocumentFolder );
+
+ if ( isNewDocumentFolder )
+ {
+ aFileView.EnableNameReplacing( sal_False );
+ aFileView.Initialize( GetNewDocContents() );
+ }
+ else
+ {
+ xub_StrLen nSampFoldLen = aSamplesFolderURL.Len();
+ aFileView.EnableNameReplacing(
+ nSampFoldLen && rURL.CompareTo( aSamplesFolderURL, nSampFoldLen ) == COMPARE_EQUAL );
+ aFileView.Initialize( rURL, String(), NULL );
+ }
+ aNewFolderLink.Call( this );
+}
+
+sal_Bool SvtFileViewWindow_Impl::HasPreviousLevel( String& rURL ) const
+{
+ INetURLObject aViewObj( aFileView.GetViewURL() );
+ INetURLObject aRootObj( aCurrentRootURL );
+ INetURLObject aMyDocObj( aMyDocumentsURL );
+
+ return ( ( aViewObj != aRootObj || aRootObj == aMyDocObj ) && aFileView.GetParentURL( rURL ) );
+}
+
+String SvtFileViewWindow_Impl::GetFolderTitle() const
+{
+ String aTitle;
+ ::utl::UCBContentHelper::GetTitle( aFolderURL, aTitle );
+ return aTitle;
+}
+
+void SvtFileViewWindow_Impl::SetFocus()
+{
+ aFileView.SetFocus();
+}
+
+// class SvtDocInfoTable_Impl --------------------------------------------
+
+SvtDocInfoTable_Impl::SvtDocInfoTable_Impl() :
+
+ ResStringArray( SvtResId( STRARY_SVT_DOCINFO ) )
+
+{
+}
+// -----------------------------------------------------------------------------
+// class SvtExtendedMultiLineEdit_Impl --------------------------------------------
+SvtExtendedMultiLineEdit_Impl::SvtExtendedMultiLineEdit_Impl( Window* pParent,WinBits _nBits ) :
+
+ ExtMultiLineEdit( pParent, _nBits )
+
+{
+ SetLeftMargin( 10 );
+}
+// -----------------------------------------------------------------------------
+void SvtExtendedMultiLineEdit_Impl::InsertEntry( const String& rTitle, const String& rValue )
+{
+ String aText( '\n' );
+ aText += rTitle;
+ aText += ':';
+ InsertText( aText );
+ ULONG nPara = GetParagraphCount() - 1;
+ SetAttrib( TextAttribFontWeight( WEIGHT_BOLD ), nPara, 0, aText.Len() );
+
+ aText = '\n';
+ aText += rValue;
+ InsertText( aText );
+ nPara = GetParagraphCount() - 1;
+ SetAttrib( TextAttribFontWeight( WEIGHT_NORMAL ), nPara, 0, aText.Len() );
+
+ InsertText( String( '\n' ) );
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+const String& SvtDocInfoTable_Impl::GetString( long nId ) const
+{
+ sal_uInt32 nPos( FindIndex( nId ) );
+
+ if ( RESARRAY_INDEX_NOTFOUND != nPos )
+ return ResStringArray::GetString( nPos );
+ else
+ return aEmptyString;
+}
+
+// class SvtFrameWindow_Impl ---------------------------------------------
+
+SvtFrameWindow_Impl::SvtFrameWindow_Impl( Window* pParent ) :
+
+ Window( pParent )
+
+{
+ // detect application language
+ aLocale= SvtPathOptions().GetLocale();
+
+ // create windows and frame
+ pEditWin = new ODocumentInfoPreview( this ,WB_LEFT | WB_VSCROLL | WB_READONLY | WB_BORDER | WB_3DLOOK);
+ pTextWin = new Window( this );
+ xFrame = Reference < XFrame > ( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.frame.Frame") ), UNO_QUERY );
+ xWindow = VCLUnoHelper::GetInterface( pTextWin );
+ xFrame->initialize( xWindow );
+
+ // create docinfo instance
+ m_xDocProps.set( ::comphelper::getProcessServiceFactory()->createInstance(
+ ASCII_STR("com.sun.star.document.DocumentProperties") ),
+ UNO_QUERY );
+
+ pEmptyWin = new Window( this, WB_BORDER | WB_3DLOOK );
+}
+
+SvtFrameWindow_Impl::~SvtFrameWindow_Impl()
+{
+ delete pEditWin;
+ delete pEmptyWin;
+ xFrame->dispose();
+}
+
+void SvtFrameWindow_Impl::ViewEditWin()
+{
+ pEmptyWin->Hide();
+ xWindow->setVisible( sal_False );
+ pTextWin->Hide();
+ pEditWin->Show();
+}
+
+void SvtFrameWindow_Impl::ViewTextWin()
+{
+ pEmptyWin->Hide();
+ pEditWin->Hide();
+ xWindow->setVisible( sal_True );
+ pTextWin->Show();
+}
+
+void SvtFrameWindow_Impl::ViewEmptyWin()
+{
+ xWindow->setVisible( sal_False );
+ pTextWin->Hide();
+ pEditWin->Hide();
+ pEmptyWin->Show();
+}
+
+void SvtFrameWindow_Impl::ViewNonEmptyWin()
+{
+ if( bDocInfo )
+ ViewEditWin();
+ else
+ ViewTextWin();
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( SvtFrameWindow_Impl, ExecuteHdl_Impl, SvtExecuteInfo*, pExecuteInfo )
+{
+ try
+ {
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, Sequence < PropertyValue >() );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ delete pExecuteInfo;
+ return 0;
+}
+
+void SvtFrameWindow_Impl::ShowDocInfo( const String& rURL )
+{
+ try
+ {
+ uno::Reference < task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY );
+ uno::Sequence < beans::PropertyValue> aProps(1);
+ aProps[0].Name = ::rtl::OUString::createFromAscii("InteractionHandler");
+ aProps[0].Value <<= xInteractionHandler;
+ m_xDocProps->loadFromMedium( rURL, aProps );
+ pEditWin->fill( m_xDocProps, rURL );
+ }
+ catch ( UnknownPropertyException& ) {}
+ catch ( Exception& ) {}
+}
+
+void SvtFrameWindow_Impl::Resize()
+{
+ Size aWinSize = GetOutputSizePixel();
+ pEditWin->SetSizePixel( aWinSize );
+ pTextWin->SetSizePixel( aWinSize );
+ pEmptyWin->SetSizePixel( aWinSize );
+}
+
+void SvtFrameWindow_Impl::OpenFile( const String& rURL, sal_Bool bPreview, sal_Bool bIsTemplate, sal_Bool bAsTemplate )
+{
+ if ( bPreview )
+ aCurrentURL = rURL;
+
+ ViewNonEmptyWin();
+ pEditWin->Clear();
+
+ if ( rURL.Len() > 0 && bPreview && m_xDocProps.is() )
+ ShowDocInfo( rURL );
+
+ if ( rURL.Len() == 0 )
+ {
+ xFrame->setComponent( Reference < com::sun::star::awt::XWindow >(), Reference < XController >() );
+ ViewEmptyWin();
+ }
+ else if ( !::utl::UCBContentHelper::IsFolder( rURL ) )
+ {
+ com::sun::star::util::URL aURL;
+ aURL.Complete = rURL;
+ Reference < com::sun::star::util::XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.util.URLTransformer" ) ), UNO_QUERY );
+ xTrans->parseStrict( aURL );
+
+ String aTarget;
+ Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY );
+ if ( bPreview )
+ aTarget = ASCII_STR("_self");
+ else
+ {
+ // can be removed if the database application change its URL
+ String sServiceScheme( RTL_CONSTASCII_STRINGPARAM( "service:" ) );
+ if ( rURL.Match( sServiceScheme ) != sServiceScheme.Len() )
+ // service URL has no default target
+ aTarget = ASCII_STR("_default");
+ xProv = Reference < XDispatchProvider >( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.frame.Desktop") ), UNO_QUERY );
+ }
+
+ Reference < XDispatch > xDisp = xProv.is() ?
+ xProv->queryDispatch( aURL, aTarget, 0 ) : Reference < XDispatch >();
+
+ if ( xDisp.is() )
+ {
+ if ( bPreview )
+ {
+ if ( m_aOpenURL != aURL.Complete )
+ {
+ WaitObject aWaitCursor( GetParent() );
+ // disabling must be done here, does not work in ctor because
+ // execute of the dialog will overwrite it
+ // ( own execute method would help )
+ pTextWin->EnableInput( FALSE, TRUE );
+ if ( pTextWin->IsReallyVisible() )
+ {
+ sal_Bool b = sal_True;
+ Sequence < PropertyValue > aArgs( 4 );
+ aArgs[0].Name = ASCII_STR("Preview");
+ aArgs[0].Value.setValue( &b, ::getBooleanCppuType() );
+ aArgs[1].Name = ASCII_STR("ReadOnly");
+ aArgs[1].Value.setValue( &b, ::getBooleanCppuType() );
+ aArgs[2].Name = ASCII_STR("AsTemplate"); // prevents getting an empty URL with getURL()!
+
+ uno::Reference < task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY );
+ aArgs[3].Name = ::rtl::OUString::createFromAscii("InteractionHandler");
+ aArgs[3].Value <<= xInteractionHandler;
+
+ b = sal_False;
+ aArgs[2].Value.setValue( &b, ::getBooleanCppuType() );
+ xDisp->dispatch( aURL, aArgs );
+
+ ::rtl::OUString aDispURL;
+ Reference< ::com::sun::star::frame::XController > xCtrl = xFrame->getController();
+ if( xCtrl.is() )
+ {
+ Reference< ::com::sun::star::frame::XModel > xMdl = xCtrl->getModel();
+ if( xMdl.is() )
+ aDispURL = xMdl->getURL();
+ }
+
+ if( aDispURL != aURL.Complete )
+ {
+ xFrame->setComponent( Reference < com::sun::star::awt::XWindow >(), Reference < XController >() );
+ ViewEmptyWin();
+ m_aOpenURL = rtl::OUString();
+ }
+ else
+ m_aOpenURL = aDispURL;
+ }
+ }
+ }
+ else if ( bIsTemplate )
+ {
+ Sequence < PropertyValue > aArgs( 1 );
+ aArgs[0].Name = ASCII_STR("AsTemplate");
+ aArgs[0].Value <<= bAsTemplate;
+ xDisp->dispatch( aURL, aArgs );
+ m_aOpenURL = rtl::OUString();
+ }
+ else
+ {
+ /*
+ SvtExecuteInfo* pExecuteInfo = new SvtExecuteInfo;
+ pExecuteInfo->xDispatch = xDisp;
+ pExecuteInfo->aTargetURL = aURL;
+ Application::PostUserEvent(
+ STATIC_LINK(0, SvtFrameWindow_Impl, ExecuteHdl_Impl), pExecuteInfo );
+ */
+ Sequence < PropertyValue > aArgs;
+ xDisp->dispatch( aURL, aArgs );
+ m_aOpenURL = rtl::OUString();
+ }
+ }
+ }
+}
+
+void SvtFrameWindow_Impl::ToggleView( sal_Bool bDI )
+{
+ bDocInfo = bDI;
+
+ // view is set properly in OpenFile()
+
+ OpenFile( aCurrentURL, sal_True, sal_False, sal_False );
+}
+
+// class SvtTemplateWindow -----------------------------------------------
+
+SvtTemplateWindow::SvtTemplateWindow( Window* pParent ) :
+
+ Window( pParent, WB_DIALOGCONTROL ),
+
+ aFileViewTB ( this, SvtResId( TB_SVT_FILEVIEW ) ),
+ aFrameWinTB ( this, SvtResId( TB_SVT_FRAMEWIN ) ),
+ aSplitWin ( this, WB_DIALOGCONTROL | WB_NOSPLITDRAW ),
+ pHistoryList ( NULL )
+
+{
+ // create windows
+ pIconWin = new SvtIconWindow_Impl( this );
+ pFileWin = new SvtFileViewWindow_Impl( this );
+ pFileWin->SetMyDocumentsURL( pIconWin->GetMyDocumentsRootURL() );
+ pFileWin->SetSamplesFolderURL( pIconWin->GetSamplesFolderURL() );
+ pFrameWin = new SvtFrameWindow_Impl( this );
+
+ // set handlers
+ pIconWin->SetClickHdl( LINK( this, SvtTemplateWindow, IconClickHdl_Impl ) );
+ pFileWin->SetSelectHdl( LINK( this, SvtTemplateWindow, FileSelectHdl_Impl ) );
+ pFileWin->SetDoubleClickHdl( LINK( this, SvtTemplateWindow, FileDblClickHdl_Impl ) );
+ pFileWin->SetNewFolderHdl( LINK( this, SvtTemplateWindow, NewFolderHdl_Impl ) );
+
+ // create the split items
+ aSplitWin.SetAlign( WINDOWALIGN_LEFT );
+ long nWidth = pIconWin->GetMaxTextLength() * 8 / 7 + 1; // extra space for border
+ aSplitWin.InsertItem( ICONWIN_ID, pIconWin, nWidth, SPLITWINDOW_APPEND, 0, SWIB_FIXED );
+ aSplitWin.InsertItem( FILEWIN_ID, pFileWin, 50, SPLITWINDOW_APPEND, 0, SWIB_PERCENTSIZE );
+ aSplitWin.InsertItem( FRAMEWIN_ID, pFrameWin, 50, SPLITWINDOW_APPEND, 0, SWIB_PERCENTSIZE );
+ aSplitWin.SetSplitHdl( LINK( this, SvtTemplateWindow, ResizeHdl_Impl ) );
+
+ // show the windows
+ pIconWin->Show();
+ pFileWin->Show();
+ pFrameWin->Show();
+ aSplitWin.Show();
+
+ // initialize the timers
+ aSelectTimer.SetTimeout( 200 );
+ aSelectTimer.SetTimeoutHdl( LINK( this, SvtTemplateWindow, TimeoutHdl_Impl ) );
+
+ // initialize the toolboxes and then show them
+ InitToolBoxes();
+ aFileViewTB.Show();
+ aFrameWinTB.Show();
+
+ ReadViewSettings( );
+
+ Application::PostUserEvent( LINK( this, SvtTemplateWindow, ResizeHdl_Impl ) );
+}
+
+// ------------------------------------------------------------------------
+
+SvtTemplateWindow::~SvtTemplateWindow()
+{
+ WriteViewSettings( );
+
+ delete pIconWin;
+ delete pFileWin;
+ delete pFrameWin;
+ if ( pHistoryList )
+ {
+ for ( UINT32 i = 0; i < pHistoryList->Count(); ++i )
+ delete pHistoryList->GetObject(i);
+ delete pHistoryList;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , IconClickHdl_Impl, SvtIconChoiceCtrl *, EMPTYARG )
+{
+ String aURL = pIconWin->GetSelectedIconURL();
+ if ( !aURL.Len() )
+ aURL = pIconWin->GetCursorPosIconURL();
+ if ( pFileWin->GetRootURL() != aURL )
+ {
+ pFileWin->OpenRoot( aURL );
+ pIconWin->InvalidateIconControl();
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_PRINT, FALSE );
+ }
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , FileSelectHdl_Impl, SvtFileView *, EMPTYARG )
+{
+ aSelectTimer.Start();
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , FileDblClickHdl_Impl, SvtFileView *, EMPTYARG )
+{
+ if ( aSelectTimer.IsActive() )
+ aSelectTimer.Stop();
+
+ String aURL = pFileWin->GetSelectedFile();
+ if ( aURL.Len() > 0 )
+ {
+ if ( ::utl::UCBContentHelper::IsFolder( aURL ) )
+ pFileWin->OpenFolder( aURL );
+ else
+ aDoubleClickHdl.Call( this );
+ }
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , NewFolderHdl_Impl, SvtFileView *, EMPTYARG )
+{
+ pFrameWin->OpenFile( String(), sal_True, sal_False, sal_False );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_PRINT, FALSE );
+
+ String sURL = pFileWin->GetFolderURL();
+ ULONG nPos = pIconWin->GetRootPos( sURL );
+ AppendHistoryURL( sURL, nPos );
+
+ aNewFolderHdl.Call( this );
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , TimeoutHdl_Impl, Timer *, EMPTYARG )
+{
+ aSelectHdl.Call( this );
+ String sURL = pFileWin->GetSelectedFile();
+ sal_Bool bIsNewDoc = ( pIconWin->GetSelectEntryPos() == ICON_POS_NEWDOC );
+ sal_Bool bIsFile = ( sURL.Len() != 0 && !::utl::UCBContentHelper::IsFolder( sURL ) &&
+ INetURLObject( sURL ).GetProtocol() != INET_PROT_PRIVATE && !bIsNewDoc );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_PRINT, bIsFile );
+ aFrameWinTB.EnableItem( TI_DOCTEMPLATE_PREVIEW, !bIsNewDoc );
+
+ if ( bIsFile )
+ pFrameWin->OpenFile( sURL, sal_True, sal_False, sal_False );
+ else if ( bIsNewDoc && aFrameWinTB.IsItemChecked( TI_DOCTEMPLATE_PREVIEW ) )
+ {
+ aFrameWinTB.CheckItem( TI_DOCTEMPLATE_DOCINFO );
+ DoAction( TI_DOCTEMPLATE_DOCINFO );
+ }
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , ClickHdl_Impl, ToolBox *, pToolBox )
+{
+ DoAction( pToolBox->GetCurItemId() );
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtTemplateWindow , ResizeHdl_Impl, SplitWindow *, EMPTYARG )
+{
+ Resize();
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::PrintFile( const String& rURL )
+{
+ // open the file readonly and hidden
+ Sequence < PropertyValue > aArgs( 2 );
+ aArgs[0].Name = ASCII_STR("ReadOnly");
+ aArgs[0].Value <<= sal_True;
+ aArgs[1].Name = ASCII_STR("Hidden");
+ aArgs[1].Value <<= sal_True;
+
+ Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.frame.Desktop") ), UNO_QUERY );
+ Reference < XModel > xModel( xDesktop->loadComponentFromURL(
+ rURL, ASCII_STR("_blank"), 0, aArgs ), UNO_QUERY );
+ if ( xModel.is() )
+ {
+ // print
+ Reference < XPrintable > xPrintable( xModel, UNO_QUERY );
+ if ( xPrintable.is() )
+ xPrintable->print( Sequence < PropertyValue >() );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::AppendHistoryURL( const String& rURL, ULONG nGroup )
+{
+ sal_Bool bInsert = sal_True;
+ if ( !pHistoryList )
+ pHistoryList = new HistoryList_Impl;
+ else if ( pHistoryList->Count() > 0 )
+ {
+ FolderHistory* pLastEntry = pHistoryList->GetObject( pHistoryList->Count() - 1 );
+ bInsert = ( rURL != pLastEntry->m_sURL);
+ }
+
+ if ( bInsert )
+ {
+ FolderHistory* pEntry = new FolderHistory( rURL, nGroup );
+ pHistoryList->Insert( pEntry, LIST_APPEND );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_BACK, pHistoryList->Count() > 1 );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::OpenHistory()
+{
+ FolderHistory* pEntry = pHistoryList->Remove( pHistoryList->Count() - 1 );
+ pEntry = pHistoryList->Remove( pHistoryList->Count() - 1 );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_BACK, pHistoryList->Count() > 1 );
+ pFileWin->OpenFolder( pEntry->m_sURL );
+ pIconWin->SetCursorPos( pEntry->m_nGroup );
+ delete pEntry;
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::DoAction( USHORT nAction )
+{
+ switch( nAction )
+ {
+ case TI_DOCTEMPLATE_BACK :
+ {
+ if ( pHistoryList && pHistoryList->Count() > 1 )
+ OpenHistory();
+ break;
+ }
+
+ case TI_DOCTEMPLATE_PREV :
+ {
+ String aURL;
+ if ( pFileWin->HasPreviousLevel( aURL ) )
+ pFileWin->OpenFolder( aURL );
+ break;
+ }
+
+ case TI_DOCTEMPLATE_PRINT :
+ {
+ String sPrintFile( pFileWin->GetSelectedFile() );
+ if ( sPrintFile.Len() > 0 )
+ PrintFile( sPrintFile );
+ break;
+ }
+
+ case TI_DOCTEMPLATE_DOCINFO :
+ case TI_DOCTEMPLATE_PREVIEW :
+ {
+ pFrameWin->ToggleView( TI_DOCTEMPLATE_DOCINFO == nAction );
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::InitToolBoxes()
+{
+ InitToolBoxImages();
+
+ Size aSize = aFileViewTB.CalcWindowSizePixel();
+ aSize.Height() += 4;
+ aFileViewTB.SetPosSizePixel( Point( 0, 2 ), aSize );
+ aSize = aFrameWinTB.CalcWindowSizePixel();
+ aSize.Height() += 4;
+ aFrameWinTB.SetPosSizePixel( Point( pFrameWin->GetPosPixel().X() + 2, 2 ), aSize );
+
+ BOOL bFlat = ( SvtMiscOptions().GetToolboxStyle() == TOOLBOX_STYLE_FLAT );
+ if ( bFlat )
+ {
+ aFileViewTB.SetOutStyle( TOOLBOX_STYLE_FLAT );
+ aFrameWinTB.SetOutStyle( TOOLBOX_STYLE_FLAT );
+ }
+
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_BACK, FALSE );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_PREV, FALSE );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_PRINT, FALSE );
+
+ Link aLink = LINK( this, SvtTemplateWindow, ClickHdl_Impl );
+ aFileViewTB.SetClickHdl( aLink );
+ aFrameWinTB.SetClickHdl( aLink );
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::InitToolBoxImages()
+{
+ SvtMiscOptions aMiscOpt;
+ BOOL bLarge = aMiscOpt.AreCurrentSymbolsLarge();
+ sal_Bool bHiContrast = aFileViewTB.GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ aFileViewTB.SetItemImage( TI_DOCTEMPLATE_BACK, Image( SvtResId(
+ bLarge ? bHiContrast ? IMG_SVT_DOCTEMPL_HC_BACK_LARGE : IMG_SVT_DOCTEMPLATE_BACK_LARGE
+ : bHiContrast ? IMG_SVT_DOCTEMPL_HC_BACK_SMALL : IMG_SVT_DOCTEMPLATE_BACK_SMALL ) ) );
+ aFileViewTB.SetItemImage( TI_DOCTEMPLATE_PREV, Image( SvtResId(
+ bLarge ? bHiContrast ? IMG_SVT_DOCTEMPL_HC_PREV_LARGE : IMG_SVT_DOCTEMPLATE_PREV_LARGE
+ : bHiContrast ? IMG_SVT_DOCTEMPL_HC_PREV_SMALL : IMG_SVT_DOCTEMPLATE_PREV_SMALL ) ) );
+ aFileViewTB.SetItemImage( TI_DOCTEMPLATE_PRINT, Image( SvtResId(
+ bLarge ? bHiContrast ? IMG_SVT_DOCTEMPL_HC_PRINT_LARGE : IMG_SVT_DOCTEMPLATE_PRINT_LARGE
+ : bHiContrast ? IMG_SVT_DOCTEMPL_HC_PRINT_SMALL : IMG_SVT_DOCTEMPLATE_PRINT_SMALL ) ) );
+
+ aFrameWinTB.SetItemImage( TI_DOCTEMPLATE_DOCINFO, Image( SvtResId(
+ bLarge ? bHiContrast ? IMG_SVT_DOCTEMPL_HC_DOCINFO_LARGE : IMG_SVT_DOCTEMPLATE_DOCINFO_LARGE
+ : bHiContrast ? IMG_SVT_DOCTEMPL_HC_DOCINFO_SMALL : IMG_SVT_DOCTEMPLATE_DOCINFO_SMALL ) ) );
+ aFrameWinTB.SetItemImage( TI_DOCTEMPLATE_PREVIEW, Image( SvtResId(
+ bLarge ? bHiContrast ? IMG_SVT_DOCTEMPL_HC_PREVIEW_LARGE : IMG_SVT_DOCTEMPLATE_PREVIEW_LARGE
+ : bHiContrast ? IMG_SVT_DOCTEMPL_HC_PREVIEW_SMALL : IMG_SVT_DOCTEMPLATE_PREVIEW_SMALL ) ) );
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::UpdateIcons()
+{
+ pIconWin->UpdateIcons( aFileViewTB.GetSettings().GetStyleSettings().GetHighContrastMode() );
+}
+
+// ------------------------------------------------------------------------
+
+long SvtTemplateWindow::PreNotify( NotifyEvent& rNEvt )
+{
+ USHORT nType = rNEvt.GetType();
+ long nRet = 0;
+
+ if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
+ {
+ const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
+ USHORT nCode = rKeyCode.GetCode();
+
+ if ( KEY_BACKSPACE == nCode && !rKeyCode.GetModifier() && pFileWin->HasChildPathFocus() )
+ {
+ DoAction( TI_DOCTEMPLATE_BACK );
+ nRet = 1;
+ }
+ else if ( pIconWin->ProcessKeyEvent( *rNEvt.GetKeyEvent() ) )
+ {
+ nRet = 1;
+ }
+ }
+
+ return nRet ? nRet : Window::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------------
+
+void SvtTemplateWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
+ ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
+ {
+ // update of the background for the area left of the FileView toolbox
+ SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
+ // update of the images of the IconChoiceControl
+ UpdateIcons();
+ // update of the toolbox images
+ InitToolBoxImages();
+ }
+}
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::Resize()
+{
+ long nItemSize = aSplitWin.GetItemSize( ICONWIN_ID );
+ long nSplitterWidth = Splitter( this, 0 ).GetSizePixel().Width();
+
+ Point aPos = aFileViewTB.GetPosPixel();
+ aPos.X() = nItemSize + nSplitterWidth / 2;
+ aFileViewTB.SetPosPixel( aPos );
+
+ Size aWinSize = GetOutputSizePixel();
+ long nWidth = aWinSize.Width() - aPos.X();
+
+ nItemSize = nWidth * aSplitWin.GetItemSize( FILEWIN_ID ) / 100;
+ aPos.X() = pFrameWin->GetPosPixel().X() + 2;
+ aFrameWinTB.SetPosPixel( aPos );
+
+ Size aSize = aFileViewTB.GetSizePixel();
+ aSize.Width() = nItemSize;
+ aFileViewTB.SetSizePixel( aSize );
+
+ aSize = aFrameWinTB.GetSizePixel();
+ aSize.Width() = nWidth - nItemSize;
+ aFrameWinTB.SetSizePixel( aSize );
+
+ long nToolBoxHeight = aSize.Height() + aFrameWinTB.GetPosPixel().Y();
+ aSize = aWinSize;
+ aSize.Height() -= nToolBoxHeight;
+ aSplitWin.SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize );
+}
+
+// ------------------------------------------------------------------------
+
+String SvtTemplateWindow::GetSelectedFile() const
+{
+ return pFileWin->GetSelectedFile();
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool SvtTemplateWindow::IsFileSelected() const
+{
+ String aURL = pFileWin->GetSelectedFile();
+ sal_Bool bRet = ( aURL.Len() > 0 && !::utl::UCBContentHelper::IsFolder( aURL ) );
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::OpenFile( sal_Bool bNotAsTemplate )
+{
+ String aURL = pFileWin->GetSelectedFile();
+ if ( aURL.Len() > 0 && !::utl::UCBContentHelper::IsFolder( aURL ) )
+ pFrameWin->OpenFile( aURL, sal_False, pFileWin->IsTemplateFolder(), !bNotAsTemplate );
+}
+
+// ------------------------------------------------------------------------
+
+String SvtTemplateWindow::GetFolderTitle() const
+{
+ String sTitle;
+ String sFolderURL = pFileWin->GetFolderURL();
+ if ( pIconWin->IsRootURL( sFolderURL ) )
+ sTitle = pIconWin->GetIconText( sFolderURL );
+ else
+ sTitle = pFileWin->GetFolderTitle();
+ return sTitle;
+}
+
+// ------------------------------------------------------------------------
+
+String SvtTemplateWindow::GetFolderURL() const
+{
+ return pFileWin->GetFolderURL();
+}
+
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::SetFocus( sal_Bool bIconWin )
+{
+ if ( bIconWin )
+ pIconWin->SetFocus();
+ else
+ pFileWin->SetFocus();
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::OpenTemplateRoot()
+{
+ pFileWin->OpenFolder( pIconWin->GetTemplateRootURL() );
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::SetPrevLevelButtonState( const String& rURL )
+{
+ // disable the prev level button on root folder of the icon pane (except My Documents)
+ // and on the root of all (file:/// -> count == 0)
+ INetURLObject aObj( rURL );
+ sal_Int32 nCount = aObj.getSegmentCount();
+ sal_Bool bEnable =
+ ( nCount > 0 &&
+ ( !pIconWin->IsRootURL( rURL ) || rURL == pIconWin->GetMyDocumentsRootURL() ) );
+ aFileViewTB.EnableItem( TI_DOCTEMPLATE_PREV, bEnable );
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::ClearHistory()
+{
+ if( pHistoryList )
+ pHistoryList->Clear();
+}
+
+// ------------------------------------------------------------------------
+
+long SvtTemplateWindow::CalcHeight() const
+{
+ // toolbox height
+ long nHeight = aFileViewTB.GetSizePixel().Height();
+ // + iconwin height
+ nHeight += pIconWin->CalcHeight();
+ // + little offset
+ nHeight += 8;
+ return nHeight;
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::ReadViewSettings()
+{
+ // defaults
+ sal_Int32 nSelectedGroup = ICON_POS_TEMPLATES;
+ sal_Int32 nSelectedView = TI_DOCTEMPLATE_DOCINFO;
+ double nSplitRatio = 0.5;
+ ::rtl::OUString sLastFolder;
+
+ SvtViewOptions aViewSettings( E_DIALOG, VIEWSETTING_NEWFROMTEMPLATE );
+ if ( aViewSettings.Exists() )
+ {
+ // read the settings
+ Sequence< NamedValue > aSettings = aViewSettings.GetUserData( );
+
+ aViewSettings.GetUserItem( VIEWSETTING_SELECTEDGROUP ) >>= nSelectedGroup;
+ aViewSettings.GetUserItem( VIEWSETTING_SELECTEDVIEW ) >>= nSelectedView;
+ aViewSettings.GetUserItem( VIEWSETTING_SPLITRATIO ) >>= nSplitRatio;
+ aViewSettings.GetUserItem( VIEWSETTING_LASTFOLDER ) >>= sLastFolder;
+ }
+ // normalize
+ if ( nSelectedGroup < ICON_POS_NEWDOC ) nSelectedGroup = ICON_POS_NEWDOC;
+ if ( nSelectedGroup > ICON_POS_SAMPLES ) nSelectedGroup = ICON_POS_SAMPLES;
+
+ if ( ( TI_DOCTEMPLATE_DOCINFO != nSelectedView ) && ( TI_DOCTEMPLATE_PREVIEW != nSelectedView ) )
+ nSelectedView = TI_DOCTEMPLATE_DOCINFO;
+
+ if ( nSplitRatio < 0.2 ) nSplitRatio = 0.2;
+ if ( nSplitRatio > 0.8 ) nSplitRatio = 0.8;
+
+ // change our view according to the settings
+
+ // the selected view (details or preview)
+ pFrameWin->ToggleView( TI_DOCTEMPLATE_DOCINFO == nSelectedView );
+ aFrameWinTB.CheckItem( (sal_uInt16)nSelectedView, TRUE );
+
+ // the split ratio
+ sal_Int32 nSplitFileAndFrameSize = aSplitWin.GetItemSize( FILEWIN_ID ) + aSplitWin.GetItemSize( FRAMEWIN_ID );
+ sal_Int32 nSplitFileSize = (sal_Int32)(nSplitFileAndFrameSize * nSplitRatio);
+ sal_Int32 nSplitFrameSize = nSplitFileAndFrameSize - nSplitFileSize;
+ aSplitWin.SetItemSize( FILEWIN_ID, nSplitFileSize );
+ aSplitWin.SetItemSize( FRAMEWIN_ID, nSplitFrameSize );
+ Resize();
+
+ // the selected folder
+ pIconWin->SetCursorPos( nSelectedGroup );
+
+ // open the last folder or the selected group
+ if ( sLastFolder.getLength() > 0 )
+ pFileWin->OpenFolder( sLastFolder );
+ else
+ IconClickHdl_Impl( NULL );
+}
+
+// ------------------------------------------------------------------------
+
+void SvtTemplateWindow::WriteViewSettings()
+{
+ // collect
+ Sequence< NamedValue > aSettings(4);
+
+ // the selected group
+ aSettings[0].Name = VIEWSETTING_SELECTEDGROUP;
+ pIconWin->SetFocus();
+ aSettings[0].Value <<= (sal_Int32)pIconWin->GetCursorPos( );
+
+ // the selected view mode
+ aSettings[1].Name = VIEWSETTING_SELECTEDVIEW;
+ aSettings[1].Value <<= sal_Int32( aFrameWinTB.IsItemChecked( TI_DOCTEMPLATE_DOCINFO ) ? TI_DOCTEMPLATE_DOCINFO : TI_DOCTEMPLATE_PREVIEW );
+
+ // the split ratio
+ aSettings[2].Name = VIEWSETTING_SPLITRATIO;
+ sal_Int32 nSplitFileSize = aSplitWin.GetItemSize( FILEWIN_ID );
+ sal_Int32 nSplitFileAndFrameSize = nSplitFileSize + aSplitWin.GetItemSize( FRAMEWIN_ID );
+ aSettings[2].Value <<= double( 1.0 * nSplitFileSize / nSplitFileAndFrameSize );
+
+ // last folder
+ aSettings[3].Name = VIEWSETTING_LASTFOLDER;
+ aSettings[3].Value <<= ::rtl::OUString( pFileWin->GetFolderURL() );
+
+ // write
+ SvtViewOptions aViewSettings( E_DIALOG, VIEWSETTING_NEWFROMTEMPLATE );
+ aViewSettings.SetUserData( aSettings );
+}
+/* -----------------27.11.2002 17:20-----------------
+ *
+ * --------------------------------------------------*/
+
+void SvtTemplateWindow::SelectFolder(sal_Int32 nFolderPosition)
+{
+ pIconWin->SelectFolder(nFolderPosition);
+}
+// struct SvtTmplDlg_Impl ------------------------------------------------
+
+struct SvtTmplDlg_Impl
+{
+ SvtTemplateWindow* pWin;
+ String aTitle;
+ Timer aUpdateTimer;
+ sal_Bool bSelectNoOpen;
+
+ uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+
+ SvtTmplDlg_Impl( Window* pParent ) : pWin( new SvtTemplateWindow( pParent ) ) ,bSelectNoOpen( sal_False ) {}
+
+ ~SvtTmplDlg_Impl() { delete pWin; }
+
+ uno::Reference< util::XOfficeInstallationDirectories > getOfficeInstDirs();
+};
+
+uno::Reference< util::XOfficeInstallationDirectories > SvtTmplDlg_Impl::getOfficeInstDirs()
+{
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xSMgr = comphelper::getProcessServiceFactory();
+
+ uno::Reference< beans::XPropertySet > xPropSet( xSMgr, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ uno::Reference< uno::XComponentContext > xCtx;
+ xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
+ >>= xCtx;
+
+ if ( xCtx.is() )
+ {
+ xCtx->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.util.theOfficeInstallationDirectories" ) ) )
+ >>= m_xOfficeInstDirs;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ return m_xOfficeInstDirs;
+}
+
+// class SvtDocumentTemplateDialog ---------------------------------------
+
+SvtDocumentTemplateDialog::SvtDocumentTemplateDialog( Window* _pParent, SelectOnly ) :
+ ModalDialog( _pParent, SvtResId( DLG_DOCTEMPLATE ) ),
+
+ aMoreTemplatesLink ( this, SvtResId( FT_DOCTEMPLATE_LINK ) ),
+ aLine ( this, SvtResId( FL_DOCTEMPLATE ) ),
+ aManageBtn ( this, SvtResId( BTN_DOCTEMPLATE_MANAGE ) ),
+ aEditBtn ( this, SvtResId( BTN_DOCTEMPLATE_EDIT ) ),
+ aOKBtn ( this, SvtResId( BTN_DOCTEMPLATE_OPEN ) ),
+ aCancelBtn ( this, SvtResId( BTN_DOCTEMPLATE_CANCEL ) ),
+ aHelpBtn ( this, SvtResId( BTN_DOCTEMPLATE_HELP ) ),
+ pImpl ( NULL )
+{
+ FreeResource();
+ InitImpl( );
+
+ // no editing of templates
+ aEditBtn.Hide();
+
+ pImpl->bSelectNoOpen = sal_True;
+}
+
+// ------------------------------------------------------------------------
+
+SvtDocumentTemplateDialog::SvtDocumentTemplateDialog( Window* pParent ) :
+
+ ModalDialog( pParent, SvtResId( DLG_DOCTEMPLATE ) ),
+
+ aMoreTemplatesLink ( this, SvtResId( FT_DOCTEMPLATE_LINK ) ),
+ aLine ( this, SvtResId( FL_DOCTEMPLATE ) ),
+ aManageBtn ( this, SvtResId( BTN_DOCTEMPLATE_MANAGE ) ),
+ aEditBtn ( this, SvtResId( BTN_DOCTEMPLATE_EDIT ) ),
+ aOKBtn ( this, SvtResId( BTN_DOCTEMPLATE_OPEN ) ),
+ aCancelBtn ( this, SvtResId( BTN_DOCTEMPLATE_CANCEL ) ),
+ aHelpBtn ( this, SvtResId( BTN_DOCTEMPLATE_HELP ) ),
+ pImpl ( NULL )
+{
+ FreeResource();
+ InitImpl( );
+}
+
+// ------------------------------------------------------------------------
+
+void SvtDocumentTemplateDialog::InitImpl( )
+{
+ pImpl = new SvtTmplDlg_Impl( this );
+ pImpl->aTitle = GetText();
+
+ bool bHideLink = ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
+ == SvtExtendedSecurityOptions::OPEN_NEVER );
+ if ( !bHideLink )
+ {
+ aMoreTemplatesLink.SetURL( String(
+ RTL_CONSTASCII_STRINGPARAM( "http://templates.services.openoffice.org/?cid=923508" ) ) );
+ aMoreTemplatesLink.SetClickHdl( LINK( this, SvtDocumentTemplateDialog, OpenLinkHdl_Impl ) );
+ }
+ else
+ aMoreTemplatesLink.Hide();
+
+ aManageBtn.SetClickHdl( LINK( this, SvtDocumentTemplateDialog, OrganizerHdl_Impl ) );
+ Link aLink = LINK( this, SvtDocumentTemplateDialog, OKHdl_Impl );
+ aEditBtn.SetClickHdl( aLink );
+ aOKBtn.SetClickHdl( aLink );
+
+ pImpl->pWin->SetSelectHdl( LINK( this, SvtDocumentTemplateDialog, SelectHdl_Impl ) );
+ pImpl->pWin->SetDoubleClickHdl( LINK( this, SvtDocumentTemplateDialog, DoubleClickHdl_Impl ) );
+ pImpl->pWin->SetNewFolderHdl( LINK( this, SvtDocumentTemplateDialog, NewFolderHdl_Impl ) );
+ pImpl->pWin->SetSendFocusHdl( LINK( this, SvtDocumentTemplateDialog, SendFocusHdl_Impl ) );
+
+ // dynamic height adjustment
+ long nHeight = pImpl->pWin->CalcHeight();
+
+ Size aSize = GetOutputSizePixel();
+ Point aPos = aMoreTemplatesLink.GetPosPixel();
+ Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
+ if ( bHideLink )
+ aPos.Y() += aMoreTemplatesLink.GetSizePixel().Height();
+ else
+ aPos.Y() -= a6Size.Height();
+ long nDelta = aPos.Y() - nHeight;
+ aSize.Height() -= nDelta;
+ SetOutputSizePixel( aSize );
+
+ aSize.Height() = nHeight;
+ aSize.Width() -= ( a6Size.Width() * 2 );
+ pImpl->pWin->SetPosSizePixel( Point( a6Size.Width(), 0 ), aSize );
+
+ aPos = aMoreTemplatesLink.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aMoreTemplatesLink.SetPosPixel( aPos );
+ aPos = aLine.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aLine.SetPosPixel( aPos );
+ aPos = aManageBtn.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aManageBtn.SetPosPixel( aPos );
+ aPos = aEditBtn.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aEditBtn.SetPosPixel( aPos );
+ aPos = aOKBtn.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aOKBtn.SetPosPixel( aPos );
+ aPos = aCancelBtn.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aCancelBtn.SetPosPixel( aPos );
+ aPos = aHelpBtn.GetPosPixel();
+ aPos.Y() -= nDelta;
+ aHelpBtn.SetPosPixel( aPos );
+
+ pImpl->pWin->Show();
+
+ SelectHdl_Impl( NULL );
+ NewFolderHdl_Impl( NULL );
+
+ UpdateHdl_Impl( NULL );
+}
+
+// ------------------------------------------------------------------------
+
+SvtDocumentTemplateDialog::~SvtDocumentTemplateDialog()
+{
+ delete pImpl;
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool SvtDocumentTemplateDialog::IsFileSelected( ) const
+{
+ return pImpl->pWin->IsFileSelected();
+}
+
+// ------------------------------------------------------------------------
+
+String SvtDocumentTemplateDialog::GetSelectedFileURL( ) const
+{
+ return pImpl->pWin->GetSelectedFile();
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool SvtDocumentTemplateDialog::CanEnableEditBtn() const
+{
+ sal_Bool bEnable = sal_False;
+
+ ::rtl::OUString aFolderURL = pImpl->pWin->GetFolderURL();
+ if ( pImpl->pWin->IsFileSelected() && aFolderURL.getLength() )
+ {
+ ::rtl::OUString aFileTargetURL = pImpl->pWin->GetSelectedFile();
+ bEnable = aFileTargetURL.getLength() > 0;
+ }
+
+ return bEnable;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog , SelectHdl_Impl, SvtTemplateWindow *, EMPTYARG )
+{
+ aEditBtn.Enable( pImpl->pWin->IsTemplateFolderOpen() && CanEnableEditBtn() );
+ aOKBtn.Enable( pImpl->pWin->IsFileSelected() );
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog , DoubleClickHdl_Impl, SvtTemplateWindow *, EMPTYARG )
+{
+ EndDialog( RET_OK );
+
+ if ( !pImpl->bSelectNoOpen )
+ pImpl->pWin->OpenFile( !pImpl->pWin->IsTemplateFolderOpen() );
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog , NewFolderHdl_Impl, SvtTemplateWindow *, EMPTYARG )
+{
+ String aNewTitle( pImpl->aTitle );
+ aNewTitle += String( ASCII_STR(" - ") );
+ aNewTitle += pImpl->pWin->GetFolderTitle();
+ SetText( aNewTitle );
+
+ SelectHdl_Impl( NULL );
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog , SendFocusHdl_Impl, SvtTemplateWindow *, EMPTYARG )
+{
+ if ( pImpl->pWin->HasIconWinFocus() )
+ aHelpBtn.GrabFocus();
+ else
+ {
+ if ( aEditBtn.IsEnabled() )
+ aEditBtn.GrabFocus();
+ else if ( aOKBtn.IsEnabled() )
+ aOKBtn.GrabFocus();
+ else
+ aCancelBtn.GrabFocus();
+ }
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog , OKHdl_Impl, PushButton *, pBtn )
+{
+ if ( pImpl->pWin->IsFileSelected() )
+ {
+ EndDialog( RET_OK );
+
+ if ( !pImpl->bSelectNoOpen )
+ pImpl->pWin->OpenFile( &aEditBtn == pBtn );
+ }
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog , OrganizerHdl_Impl, PushButton *, EMPTYARG )
+{
+ Window* pOldDefWin = Application::GetDefDialogParent();
+ Application::SetDefDialogParent( this );
+ Reference < XFramesSupplier > xDesktop = Reference < XFramesSupplier >(
+ ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.frame.Desktop") ), UNO_QUERY );
+ Reference < XFrame > xFrame( xDesktop->getActiveFrame() );
+ if ( !xFrame.is() )
+ xFrame = Reference < XFrame >( xDesktop, UNO_QUERY );
+
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = ASCII_STR("slot:5540");
+ Reference < com::sun::star::util::XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.util.URLTransformer") ), UNO_QUERY );
+ xTrans->parseStrict( aTargetURL );
+
+ Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY );
+ Reference < XDispatch > xDisp;
+ xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ if ( xDisp.is() )
+ {
+ Sequence<PropertyValue> aArgs(1);
+ PropertyValue* pArg = aArgs.getArray();
+ pArg[0].Name = ASCII_STR("Referer");
+ pArg[0].Value <<= ASCII_STR("private:user");
+ xDisp->dispatch( aTargetURL, aArgs );
+ }
+
+ Application::SetDefDialogParent( pOldDefWin );
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog, UpdateHdl_Impl, Timer*, _pEventSource )
+{
+ pImpl->pWin->SetFocus( sal_False );
+ Reference< XDocumentTemplates > xTemplates( ::comphelper::getProcessServiceFactory()->
+ createInstance( ASCII_STR("com.sun.star.frame.DocumentTemplates") ), UNO_QUERY );
+ if ( xTemplates.is() )
+ {
+ if ( _pEventSource )
+ { // it was no direct call, which means it was triggered by the timer, which means we alread checked the necessity
+ WaitObject aWaitCursor( this );
+ xTemplates->update();
+ if ( pImpl->pWin->IsTemplateFolderOpen() )
+ {
+ pImpl->pWin->ClearHistory();
+ pImpl->pWin->OpenTemplateRoot();
+ }
+ }
+ else
+ {
+ // check if we really need to do the update
+ ::svt::TemplateFolderCache aCache;
+ if ( aCache.needsUpdate() )
+ { // yes -> do it asynchronous (it will take a noticeable time)
+
+ // (but first store the current state)
+ aCache.storeState();
+
+ // start the timer for the async update
+ pImpl->aUpdateTimer.SetTimeout( 300 );
+ pImpl->aUpdateTimer.SetTimeoutHdl( LINK( this, SvtDocumentTemplateDialog, UpdateHdl_Impl ) );
+ pImpl->aUpdateTimer.Start();
+ }
+ }
+ }
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK ( SvtDocumentTemplateDialog, OpenLinkHdl_Impl, svt::FixedHyperlink*, EMPTYARG )
+{
+ ::rtl::OUString sURL( aMoreTemplatesLink.GetURL() );
+ if ( sURL.getLength() > 0 )
+ {
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xSMGR =
+ ::comphelper::getProcessServiceFactory();
+ uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShell(
+ xSMGR->createInstance( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.system.SystemShellExecute" ) ) ),
+ uno::UNO_QUERY_THROW );
+ if ( xSystemShell.is() )
+ xSystemShell->execute( sURL, ::rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS );
+ EndDialog( RET_CANCEL );
+ }
+ catch( const uno::Exception& e )
+ {
+ OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
+ rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ return 0;
+}
+
+/* -----------------27.11.2002 16:54-----------------
+ *
+ * --------------------------------------------------*/
+void SvtDocumentTemplateDialog::SelectTemplateFolder()
+{
+ pImpl->pWin->SelectFolder(ICON_POS_TEMPLATES);
+}
+
diff --git a/svtools/source/contnr/templwin.hrc b/svtools/source/contnr/templwin.hrc
new file mode 100644
index 000000000000..5a0d84f1d377
--- /dev/null
+++ b/svtools/source/contnr/templwin.hrc
@@ -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 _SVTOOLS_TEMPLWIN_HRC
+#define _SVTOOLS_TEMPLWIN_HRC
+
+#define FL_DOCTEMPLATE 10
+#define BTN_DOCTEMPLATE_MANAGE 11
+#define BTN_DOCTEMPLATE_EDIT 12
+#define BTN_DOCTEMPLATE_OPEN 13
+#define BTN_DOCTEMPLATE_CANCEL 14
+#define BTN_DOCTEMPLATE_HELP 15
+#define FT_DOCTEMPLATE_LINK 16
+
+#define TI_DOCTEMPLATE_BACK 1
+#define TI_DOCTEMPLATE_PREV 2
+#define TI_DOCTEMPLATE_PRINT 3
+#define TI_DOCTEMPLATE_DOCINFO 4
+#define TI_DOCTEMPLATE_PREVIEW 5
+
+#define HBI_CATEGORY 1
+
+#define DI_TITLE 1
+#define DI_FROM 2
+#define DI_DATE 3
+#define DI_KEYWORDS 4
+#define DI_DESCRIPTION 5
+#define DI_MIMETYPE 6
+#define DI_MODIFIEDDATE 7
+#define DI_MODIFIEDBY 8
+#define DI_PRINTDATE 9
+#define DI_PRINTBY 10
+#define DI_THEME 11
+#define DI_SIZE 12
+
+#endif // _SVTOOLS_TEMPLWIN_HRC
diff --git a/svtools/source/contnr/templwin.hxx b/svtools/source/contnr/templwin.hxx
new file mode 100644
index 000000000000..acb7c602ad30
--- /dev/null
+++ b/svtools/source/contnr/templwin.hxx
@@ -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.
+ *
+ ************************************************************************/
+#ifndef _SVTOOLS_TEMPLWIN_HXX
+#define _SVTOOLS_TEMPLWIN_HXX
+
+#include <tools/resary.hxx>
+#include <vcl/splitwin.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/window.hxx>
+#include <svtools/headbar.hxx>
+#include "fileview.hxx"
+#include "ivctrl.hxx"
+#include <svtools/svmedit2.hxx>
+#include <svl/restrictedpaths.hxx>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+namespace com{ namespace sun { namespace star { namespace awt { class XWindow; } } } }
+namespace com{ namespace sun { namespace star { namespace frame { class XFrame; } } } }
+namespace com{ namespace sun { namespace star { namespace document {
+ class XDocumentProperties;
+} } } }
+namespace svtools
+{
+ class ODocumentInfoPreview;
+}
+
+// class SvtDummyHeaderBar_Impl ------------------------------------------
+
+class SvtDummyHeaderBar_Impl : public Window
+{
+private:
+ void UpdateBackgroundColor();
+
+public:
+ SvtDummyHeaderBar_Impl( Window* pParent );
+ ~SvtDummyHeaderBar_Impl();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+};
+
+// class SvtIconWindow_Impl ----------------------------------------------
+
+class SvtIconWindow_Impl : public Window
+{
+private:
+ SvtDummyHeaderBar_Impl aDummyHeaderBar; // spaceholder instead of HeaderBar
+ SvtIconChoiceCtrl aIconCtrl;
+
+ String aNewDocumentRootURL;
+ String aTemplateRootURL;
+ String aMyDocumentsRootURL;
+ String aSamplesFolderRootURL;
+
+ long nMaxTextLength;
+
+ SvxIconChoiceCtrlEntry* GetEntry( const String& rURL ) const;
+
+public:
+ SvtIconWindow_Impl( Window* pParent );
+ ~SvtIconWindow_Impl();
+
+ virtual void Resize();
+
+ inline long GetMaxTextLength() const { return nMaxTextLength; }
+ inline void SetClickHdl( const Link& rLink ) { aIconCtrl.SetClickHdl( rLink ); }
+
+ String GetSelectedIconURL() const;
+ String GetSelectedIconText() const;
+ String GetCursorPosIconURL() const;
+ String GetIconText( const String& rURL ) const;
+ void InvalidateIconControl();
+ void SetCursorPos( ULONG nPos );
+ ULONG GetCursorPos() const;
+ ULONG GetSelectEntryPos() const;
+ void SetFocus();
+ long CalcHeight() const;
+ sal_Bool IsRootURL( const String& rURL ) const;
+ ULONG GetRootPos( const String& rURL ) const;
+ void UpdateIcons( sal_Bool _bHiContrast );
+
+ inline sal_Bool ProcessKeyEvent( const KeyEvent& rKEvt );
+
+ inline const String& GetTemplateRootURL() const { return aTemplateRootURL; }
+ inline const String& GetMyDocumentsRootURL() const { return aMyDocumentsRootURL; }
+ inline const String& GetSamplesFolderURL() const { return aSamplesFolderRootURL; }
+
+ void SelectFolder(sal_Int32 nFolderPos);
+};
+
+inline sal_Bool SvtIconWindow_Impl::ProcessKeyEvent( const KeyEvent& rKEvt )
+{
+ return ( rKEvt.GetKeyCode().IsMod2() ? aIconCtrl.DoKeyInput( rKEvt ) : sal_False );
+}
+
+// class SvtFileViewWindow_Impl ------------------------------------------
+
+class SvtTemplateWindow;
+
+class SvtFileViewWindow_Impl : public Window
+{
+private:
+ SvtTemplateWindow& rParent;
+ SvtFileView aFileView;
+ Link aNewFolderLink;
+ String aCurrentRootURL;
+ String aFolderURL;
+ String aMyDocumentsURL;
+ String aSamplesFolderURL;
+ ::svt::RestrictedPaths
+ aURLFilter;
+
+ sal_Bool bIsTemplateFolder;
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ GetNewDocContents() const;
+
+public:
+ SvtFileViewWindow_Impl( SvtTemplateWindow* pParent );
+ ~SvtFileViewWindow_Impl();
+
+ virtual void Resize();
+
+ inline void SetSelectHdl( const Link& rLink ) { aFileView.SetSelectHdl( rLink ); }
+ inline void SetDoubleClickHdl( const Link& rLink ) { aFileView.SetDoubleClickHdl( rLink ); }
+ inline void SetNewFolderHdl( const Link& rLink ) { aNewFolderLink = rLink; }
+ inline void ResetCursor() { aFileView.ResetCursor(); }
+ inline sal_Bool IsTemplateFolder() const { return bIsTemplateFolder; }
+ inline String GetFolderURL() const { return aFolderURL; }
+ inline String GetRootURL() const { return aCurrentRootURL; }
+ inline void OpenRoot( const String& rRootURL )
+ { aCurrentRootURL = rRootURL; OpenFolder( rRootURL ); }
+ inline void SetMyDocumentsURL( const String& _rNewURL ) { aMyDocumentsURL = _rNewURL; }
+ inline void SetSamplesFolderURL( const String& _rNewURL ) { aSamplesFolderURL = _rNewURL; }
+
+ String GetSelectedFile() const;
+ void OpenFolder( const String& rURL );
+ sal_Bool HasPreviousLevel( String& rURL ) const;
+ String GetFolderTitle() const;
+ void SetFocus();
+};
+
+// class SvtFrameWindow_Impl ---------------------------------------------
+
+class SvtDocInfoTable_Impl : public ResStringArray
+{
+private:
+ String aEmptyString;
+
+public:
+ SvtDocInfoTable_Impl();
+
+ const String& GetString( long nId ) const;
+};
+
+class SvtExtendedMultiLineEdit_Impl : public ExtMultiLineEdit
+{
+public:
+ SvtExtendedMultiLineEdit_Impl( Window* pParent,WinBits _nBits );
+ inline ~SvtExtendedMultiLineEdit_Impl() {}
+
+ inline void Clear() { SetText( String() ); }
+ void InsertEntry( const String& rTitle, const String& rValue );
+};
+
+class SvtFrameWindow_Impl : public Window
+{
+private:
+ ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >
+ xFrame;
+ ::com::sun::star::uno::Reference < ::com::sun::star::document::XDocumentProperties>
+ m_xDocProps;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >
+ xWindow;
+
+ ::svtools::ODocumentInfoPreview*
+ pEditWin;
+ Window* pTextWin;
+ Window* pEmptyWin;
+ ::com::sun::star::lang::Locale aLocale;
+ SvtDocInfoTable_Impl aInfoTable;
+ String aCurrentURL;
+ ::rtl::OUString m_aOpenURL;
+ sal_Bool bDocInfo;
+
+ void ShowDocInfo( const String& rURL );
+ void ViewEditWin();
+ void ViewTextWin();
+ void ViewEmptyWin();
+ void ViewNonEmptyWin(); // views depending on bDocInfo
+
+ struct SvtExecuteInfo
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatch;
+ ::com::sun::star::util::URL aTargetURL;
+ };
+
+ DECL_STATIC_LINK( SvtFrameWindow_Impl, ExecuteHdl_Impl, SvtExecuteInfo* );
+
+public:
+ SvtFrameWindow_Impl( Window* pParent );
+ ~SvtFrameWindow_Impl();
+
+ virtual void Resize();
+
+ void OpenFile( const String& rURL, sal_Bool bPreview, sal_Bool bIsTemplate, sal_Bool bAsTemplate );
+ void ToggleView( sal_Bool bDocInfo );
+};
+
+// class SvtTemplateWindow -----------------------------------------------
+
+class HistoryList_Impl;
+
+class SvtTemplateWindow : public Window
+{
+private:
+ ToolBox aFileViewTB;
+ ToolBox aFrameWinTB;
+ SplitWindow aSplitWin;
+
+ SvtIconWindow_Impl* pIconWin;
+ SvtFileViewWindow_Impl* pFileWin;
+ SvtFrameWindow_Impl* pFrameWin;
+ HistoryList_Impl* pHistoryList;
+
+ Link aSelectHdl;
+ Link aDoubleClickHdl;
+ Link aNewFolderHdl;
+ Link aSendFocusHdl;
+
+ Timer aSelectTimer;
+
+ String aFolderTitle;
+
+ virtual void Resize();
+
+ DECL_LINK( IconClickHdl_Impl, SvtIconChoiceCtrl* );
+ DECL_LINK( FileSelectHdl_Impl, SvtFileView* );
+ DECL_LINK( FileDblClickHdl_Impl, SvtFileView* );
+ DECL_LINK( NewFolderHdl_Impl, SvtFileView* );
+ DECL_LINK( TimeoutHdl_Impl, Timer* );
+ DECL_LINK( ClickHdl_Impl, ToolBox* );
+ DECL_LINK( ResizeHdl_Impl, SplitWindow* ); // used for split and initial setting of toolbar pos
+
+ void PrintFile( const String& rURL );
+ void AppendHistoryURL( const String& rURL, ULONG nGroup );
+ void OpenHistory();
+ void DoAction( USHORT nAction );
+ void InitToolBoxes();
+ void InitToolBoxImages();
+ void UpdateIcons();
+
+protected:
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+public:
+ SvtTemplateWindow( Window* pParent );
+ ~SvtTemplateWindow();
+
+ inline void SetSelectHdl( const Link& rLink ) { aSelectHdl = rLink; }
+ inline void SetDoubleClickHdl( const Link& rLink ) { aDoubleClickHdl = rLink; }
+ inline void SetNewFolderHdl( const Link& rLink ) { aNewFolderHdl = rLink; }
+ inline void SetSendFocusHdl( const Link& rLink ) { aSendFocusHdl = rLink; }
+ inline sal_Bool IsTemplateFolderOpen() const { return pFileWin->IsTemplateFolder(); }
+ inline sal_Bool HasIconWinFocus() const { return pIconWin->HasChildPathFocus(); }
+
+ void ReadViewSettings( );
+ void WriteViewSettings( );
+ sal_Bool IsFileSelected() const;
+ String GetSelectedFile() const;
+ void OpenFile( sal_Bool bNotAsTemplate );
+ String GetFolderTitle() const;
+ String GetFolderURL() const;
+ void SetFocus( sal_Bool bIconWin );
+ void OpenTemplateRoot();
+ void SetPrevLevelButtonState( const String& rURL ); // sets state (enable/disable) for previous level button
+ void ClearHistory();
+ long CalcHeight() const;
+
+ void SelectFolder(sal_Int32 nFolderPosition);
+};
+
+#endif // _SVTOOLS_TEMPLWIN_HXX
+
diff --git a/svtools/source/contnr/templwin.src b/svtools/source/contnr/templwin.src
new file mode 100644
index 000000000000..048d052c18d8
--- /dev/null
+++ b/svtools/source/contnr/templwin.src
@@ -0,0 +1,376 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ // includes ------------------------------------------------------------------
+
+#include "templwin.hrc"
+#include "controldims.hrc"
+#include <svtools/helpid.hrc>
+#include <svtools/svtools.hrc>
+
+// Magenta and Grey as mask colors
+#define MASK_COL_MAGENTA Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+
+Control CTRL_FILEVIEW
+{
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 200 , 180 ) ;
+};
+
+String STR_SVT_NEWDOC
+{
+ Text [ en-US ] = "New Document";
+};
+
+Image IMG_SVT_NEWDOC
+{
+ ImageBitmap = Bitmap { File = "new_doc.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+Image IMG_SVT_NEWDOC_HC
+{
+ ImageBitmap = Bitmap { File = "new_doc_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+String STR_SVT_MYDOCS
+{
+ Text [ en-US ] = "My Documents";
+};
+
+Image IMG_SVT_MYDOCS
+{
+ ImageBitmap = Bitmap { File = "my_docs.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+Image IMG_SVT_MYDOCS_HC
+{
+ ImageBitmap = Bitmap { File = "my_docs_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+String STR_SVT_TEMPLATES
+{
+ Text [ en-US ] = "Templates";
+};
+
+Image IMG_SVT_TEMPLATES
+{
+ ImageBitmap = Bitmap { File = "template.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+Image IMG_SVT_TEMPLATES_HC
+{
+ ImageBitmap = Bitmap { File = "template_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+String STR_SVT_SAMPLES
+{
+ Text [ en-US ] = "Samples";
+};
+
+Image IMG_SVT_SAMPLES
+{
+ ImageBitmap = Bitmap { File = "samples.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+Image IMG_SVT_SAMPLES_HC
+{
+ ImageBitmap = Bitmap { File = "samples_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+ToolBox TB_SVT_FILEVIEW
+{
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 100 , 12 ) ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = TI_DOCTEMPLATE_BACK;
+ HelpId = HID_TEMPLATEDLG_TB_BACK;
+ Text [ en-US ] = "Back" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = TI_DOCTEMPLATE_PREV;
+ HelpId = HID_TEMPLATEDLG_TB_PREV;
+ Text [ en-US ] = "Up One Level" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SEPARATOR ;
+ };
+ ToolBoxItem
+ {
+ Identifier = TI_DOCTEMPLATE_PRINT;
+ HelpId = HID_TEMPLATEDLG_TB_PRINT;
+ Text [ en-US ] = "Print" ;
+ };
+ };
+};
+
+Image IMG_SVT_DOCTEMPLATE_BACK_SMALL
+{
+ ImageBitmap = Bitmap { File = "back_small.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_BACK_LARGE
+{
+ ImageBitmap = Bitmap { File = "back_large.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_PREV_SMALL
+{
+ ImageBitmap = Bitmap { File = "up_small.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_PREV_LARGE
+{
+ ImageBitmap = Bitmap { File = "up_large.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_PRINT_SMALL
+{
+ ImageBitmap = Bitmap { File = "sc05509.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_PRINT_LARGE
+{
+ ImageBitmap = Bitmap { File = "lc05509.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_BACK_SMALL
+{
+ ImageBitmap = Bitmap { File = "back_small_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_BACK_LARGE
+{
+ ImageBitmap = Bitmap { File = "back_large_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_PREV_SMALL
+{
+ ImageBitmap = Bitmap { File = "up_small_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_PREV_LARGE
+{
+ ImageBitmap = Bitmap { File = "up_large_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_PRINT_SMALL
+{
+ ImageBitmap = Bitmap { File = "sch05509.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_PRINT_LARGE
+{
+ ImageBitmap = Bitmap { File = "lch05509.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+ToolBox TB_SVT_FRAMEWIN
+{
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 100 , 12 ) ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ RadioCheck = TRUE;
+ AutoCheck = TRUE;
+ Identifier = TI_DOCTEMPLATE_DOCINFO;
+ HelpId = HID_TEMPLATEDLG_TB_DOCINFO;
+ Text [ en-US ] = "Document Properties" ;
+ };
+ ToolBoxItem
+ {
+ RadioCheck = TRUE;
+ AutoCheck = TRUE;
+ Identifier = TI_DOCTEMPLATE_PREVIEW;
+ HelpId = HID_TEMPLATEDLG_TB_PREVIEW;
+ Text [ en-US ] = "Preview" ;
+ };
+ };
+};
+
+Image IMG_SVT_DOCTEMPLATE_DOCINFO_SMALL
+{
+ ImageBitmap = Bitmap { File = "info_small.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_DOCINFO_LARGE
+{
+ ImageBitmap = Bitmap { File = "info_large.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_PREVIEW_SMALL
+{
+ ImageBitmap = Bitmap { File = "preview_small.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPLATE_PREVIEW_LARGE
+{
+ ImageBitmap = Bitmap { File = "preview_large.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_DOCINFO_SMALL
+{
+ ImageBitmap = Bitmap { File = "info_small_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_DOCINFO_LARGE
+{
+ ImageBitmap = Bitmap { File = "info_large_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_PREVIEW_SMALL
+{
+ ImageBitmap = Bitmap { File = "preview_small_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+Image IMG_SVT_DOCTEMPL_HC_PREVIEW_LARGE
+{
+ ImageBitmap = Bitmap { File = "preview_large_h.bmp" ; };
+ MaskColor = MASK_COL_MAGENTA
+};
+
+ModalDialog DLG_DOCTEMPLATE
+{
+ HelpId = HID_TEMPLATEDLG_DIALOG ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 320, 250 );
+ Text [ en-US ] = "Templates and Documents" ;
+ Moveable = TRUE ;
+ FixedText FT_DOCTEMPLATE_LINK
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 208 ) ;
+ Size = MAP_APPFONT ( 311 , RSC_CD_FIXEDTEXT_HEIGHT ) ;
+ Text [ en-US ] = "~Get more templates online...";
+ };
+ FixedLine FL_DOCTEMPLATE
+ {
+ Pos = MAP_APPFONT( 0, 219 );
+ Size = MAP_APPFONT( 320, 8 );
+ };
+ PushButton BTN_DOCTEMPLATE_MANAGE
+ {
+ Pos = MAP_APPFONT( 6, 230 );
+ Size = MAP_APPFONT( 50, 14 );
+ Text [ en-US ] = "Organi~ze...";
+ };
+ PushButton BTN_DOCTEMPLATE_EDIT
+ {
+ Pos = MAP_APPFONT( 59, 230 );
+ Size = MAP_APPFONT( 50, 14 );
+ Text [ en-US ] = "~Edit";
+ };
+ OKButton BTN_DOCTEMPLATE_OPEN
+ {
+ Pos = MAP_APPFONT( 155, 230 );
+ Size = MAP_APPFONT( 50, 14 );
+ DefButton = TRUE;
+ Text [ en-US ] = "~Open";
+ };
+ CancelButton BTN_DOCTEMPLATE_CANCEL
+ {
+ Pos = MAP_APPFONT( 208, 230 );
+ Size = MAP_APPFONT( 50, 14 );
+ };
+ HelpButton BTN_DOCTEMPLATE_HELP
+ {
+ Pos = MAP_APPFONT( 264, 230 );
+ Size = MAP_APPFONT( 50, 14 );
+ };
+};
+
+StringArray STRARY_SVT_DOCINFO
+{
+ ItemList [ en-US ] =
+ {
+ < "Title" ; DI_TITLE ; > ;
+ < "By" ; DI_FROM ; > ;
+ < "Date" ; DI_DATE ; > ;
+ < "Keywords" ; DI_KEYWORDS ; > ;
+ < "Description" ; DI_DESCRIPTION ; > ;
+ < "Type" ; DI_MIMETYPE ; > ;
+ < "Modified on" ; DI_MODIFIEDDATE ; > ;
+ < "Modified by" ; DI_MODIFIEDBY ; > ;
+ < "Printed on" ; DI_PRINTDATE ; > ;
+ < "Printed by" ; DI_PRINTBY ; > ;
+ < "Subject" ; DI_THEME ; > ;
+ < "Size" ; DI_SIZE ; > ;
+ };
+ };
+
+String STR_SVT_NEWDOC_HELP
+{
+ Text [ en-US ] = "Click here to create new documents.";
+};
+String STR_SVT_MYDOCS_HELP
+{
+ Text [ en-US ] = "Contains your letters, reports and other documents";
+};
+String STR_SVT_TEMPLATES_HELP
+{
+ Text [ en-US ] = "Contains templates for creating new documents";
+};
+String STR_SVT_SAMPLES_HELP
+{
+ Text [ en-US ] = "Contains a selection of sample letters, reports and other documents";
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/contnr/tooltiplbox.cxx b/svtools/source/contnr/tooltiplbox.cxx
new file mode 100644
index 000000000000..6aae495bd504
--- /dev/null
+++ b/svtools/source/contnr/tooltiplbox.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_svtools.hxx"
+#include "tooltiplbox.hxx"
+#include <vcl/help.hxx>
+
+// ============================================================================
+
+namespace svtools {
+
+// ----------------------------------------------------------------------------
+
+void lcl_ToolTipLBox_ShowToolTip( ListBox& rListBox, const HelpEvent& rHEvt )
+{
+ // only show tooltip if helpmode is BALLOON or QUICK
+ if ( !( rHEvt.GetMode() & HELPMODE_BALLOON ) && !( rHEvt.GetMode() & HELPMODE_QUICK ) )
+ {
+ // else call base class method
+ rListBox.ListBox::RequestHelp( rHEvt );
+ return ;
+ }
+
+ // find the list box entry the mouse points to
+ Point aMousePos( rListBox.ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+
+ sal_uInt16 nTop = rListBox.GetTopEntry();
+ sal_uInt16 nBottom = nTop + rListBox.GetDisplayLineCount();
+
+ sal_uInt16 nPos;
+ for( nPos = nTop; nPos < nBottom; ++nPos )
+ {
+ Rectangle aItemRect( rListBox.GetBoundingRectangle( nPos ) );
+ if( (aItemRect.Top() <= aMousePos.Y()) && (aMousePos.Y() <= aItemRect.Bottom()) )
+ break;
+ }
+
+ // show text content of the entry, if it does not fit
+ if( nPos < nBottom )
+ {
+ String aHelpText( rListBox.GetEntry( nPos ) );
+ if( rListBox.GetTextWidth( aHelpText ) > rListBox.GetOutputSizePixel().Width() )
+ {
+ Point aLBoxPos( rListBox.OutputToScreenPixel( Point( 0, 0 ) ) );
+ Size aLBoxSize( rListBox.GetSizePixel() );
+ Rectangle aLBoxRect( aLBoxPos, aLBoxSize );
+
+ if( rHEvt.GetMode() == HELPMODE_BALLOON )
+ Help::ShowBalloon( &rListBox, aLBoxRect.Center(), aLBoxRect, aHelpText );
+ else
+ Help::ShowQuickHelp( &rListBox, aLBoxRect, aHelpText );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+ToolTipListBox::ToolTipListBox( Window* pParent, WinBits nStyle ) :
+ ListBox( pParent, nStyle )
+{
+}
+
+ToolTipListBox::ToolTipListBox( Window* pParent, const ResId& rResId ) :
+ ListBox( pParent, rResId )
+{
+}
+
+void ToolTipListBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ lcl_ToolTipLBox_ShowToolTip( *this, rHEvt );
+}
+
+// ----------------------------------------------------------------------------
+
+ToolTipMultiListBox::ToolTipMultiListBox( Window* pParent, WinBits nStyle ) :
+ MultiListBox( pParent, nStyle )
+{
+}
+
+ToolTipMultiListBox::ToolTipMultiListBox( Window* pParent, const ResId& rResId ) :
+ MultiListBox( pParent, rResId )
+{
+}
+
+void ToolTipMultiListBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ lcl_ToolTipLBox_ShowToolTip( *this, rHEvt );
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace svtools
+
+// ============================================================================
+
diff --git a/svtools/source/contnr/treelist.cxx b/svtools/source/contnr/treelist.cxx
new file mode 100644
index 000000000000..3395dffc28f5
--- /dev/null
+++ b/svtools/source/contnr/treelist.cxx
@@ -0,0 +1,2126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _TREELIST_CXX
+
+#ifndef GCC
+#endif
+
+#include <svtools/treelist.hxx>
+
+#ifdef DBG_UTIL
+// Prueft Integritaet der Liste nach jeder Operation
+//#define CHECK_INTEGRITY
+#endif
+
+
+DBG_NAME(SvListEntry);
+
+SvListEntry::SvListEntry()
+{
+ DBG_CTOR(SvListEntry,0);
+ pChilds = 0;
+ pParent = 0;
+ nListPos = 0;
+ nAbsPos = 0;
+}
+
+SvListEntry::SvListEntry( const SvListEntry& rEntry )
+{
+ DBG_CTOR(SvListEntry,0);
+ pChilds = 0;
+ pParent = 0;
+ nListPos &= 0x80000000;
+ nListPos |= ( rEntry.nListPos & 0x7fffffff);
+ nAbsPos = rEntry.nAbsPos;
+}
+
+SvListEntry::~SvListEntry()
+{
+ DBG_DTOR(SvListEntry,0);
+ if ( pChilds )
+ {
+ pChilds->DestroyAll();
+ delete pChilds;
+ }
+#ifdef DBG_UTIL
+ pChilds = 0;
+ pParent = 0;
+#endif
+}
+
+void SvListEntry::Clone( SvListEntry* pSource)
+{
+ DBG_CHKTHIS(SvListEntry,0);
+ nListPos &= 0x80000000;
+ nListPos |= ( pSource->nListPos & 0x7fffffff);
+ nAbsPos = pSource->nAbsPos;
+}
+
+void SvListEntry::SetListPositions()
+{
+ if( pChilds )
+ {
+ SvListEntry *pEntry = (SvListEntry*)pChilds->First();
+ ULONG nCur = 0;
+ while ( pEntry )
+ {
+ pEntry->nListPos &= 0x80000000;
+ pEntry->nListPos |= nCur;
+ nCur++;
+ pEntry = (SvListEntry*)pChilds->Next();
+ }
+ }
+ nListPos &= (~0x80000000);
+}
+
+
+DBG_NAME(SvViewData);
+
+SvViewData::SvViewData()
+{
+ DBG_CTOR(SvViewData,0);
+ nFlags = 0;
+ nVisPos = 0;
+}
+
+SvViewData::SvViewData( const SvViewData& rData )
+{
+ DBG_CTOR(SvViewData,0);
+ nFlags = rData.nFlags;
+ nFlags &= ~( SVLISTENTRYFLAG_SELECTED | SVLISTENTRYFLAG_FOCUSED );
+ nVisPos = rData.nVisPos;
+}
+
+SvViewData::~SvViewData()
+{
+ DBG_DTOR(SvViewData,0);
+#ifdef DBG_UTIL
+ nVisPos = 0x12345678;
+ nFlags = 0x1234;
+#endif
+}
+
+void SvTreeEntryList::DestroyAll()
+{
+ SvListEntry* pPtr = (SvListEntry*)First();
+ while( pPtr )
+ {
+ delete pPtr;
+ pPtr = (SvListEntry*)Next();
+ }
+}
+
+
+
+
+#if defined (WIN) && defined (MSC)
+// siehe BugId 42896: Die Funktionen Prev, PrevVisible, Next, NextVisible
+// (andere?) funktionieren nicht mit Optimierung.
+#pragma optimize ("", off)
+#endif
+
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvTreeList::SvTreeList()
+{
+ nEntryCount = 0;
+ bAbsPositionsValid = FALSE;
+ nRefCount = 1;
+ pRootItem = new SvListEntry;
+ eSortMode = SortNone;
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::~SvTreeList
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvTreeList::~SvTreeList()
+{
+ Clear();
+ delete pRootItem;
+#ifdef DBG_UTIL
+ pRootItem = 0;
+#endif
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::Broadcast
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::Broadcast( USHORT nActionId, SvListEntry* pEntry1,
+ SvListEntry* pEntry2, ULONG nPos )
+{
+ ULONG nViewCount = aViewList.Count();
+ for( ULONG nCurView = 0; nCurView < nViewCount; nCurView++ )
+ {
+ SvListView* pView = (SvListView*)aViewList.GetObject( nCurView );
+ if( pView )
+ pView->ModelNotification( nActionId, pEntry1, pEntry2, nPos );
+ }
+}
+
+void SvTreeList::InsertView( SvListView* pView)
+{
+ ULONG nPos = aViewList.GetPos( pView );
+ if ( nPos == LIST_ENTRY_NOTFOUND )
+ {
+ aViewList.Insert( pView, LIST_APPEND );
+ nRefCount++;
+ }
+}
+
+void SvTreeList::RemoveView( SvListView* pView )
+{
+ ULONG nPos = aViewList.GetPos( pView );
+ if ( nPos != LIST_ENTRY_NOTFOUND )
+ {
+ aViewList.Remove( pView );
+ nRefCount--;
+ }
+}
+
+
+// Ein Entry ist sichtbar, wenn alle Parents expandiert sind
+BOOL SvTreeList::IsEntryVisible( const SvListView* pView, SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pView&&pEntry,"IsVisible:Invalid Params");
+ BOOL bRetVal=FALSE;
+ do
+ {
+ if ( pEntry == pRootItem )
+ {
+ bRetVal=TRUE;
+ break;
+ }
+ pEntry = pEntry->pParent;
+ } while( pView->IsExpanded( pEntry ) );
+ return bRetVal;
+}
+
+USHORT SvTreeList::GetDepth( SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pEntry&&pEntry!=pRootItem,"GetDepth:Bad Entry");
+ USHORT nDepth = 0;
+ while( pEntry->pParent != pRootItem )
+ {
+ nDepth++;
+ pEntry = pEntry->pParent;
+ }
+ return nDepth;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::Clear()
+{
+ Broadcast( LISTACTION_CLEARING );
+ SvTreeEntryList* pRootList = pRootItem->pChilds;
+ if ( pRootList )
+ {
+ SvListEntry* pEntry = (SvListEntry*)(pRootList->First());
+ while( pEntry )
+ {
+ delete pEntry;
+ pEntry = (SvListEntry*)(pRootList->Next());
+ }
+ delete pRootItem->pChilds;
+ pRootItem->pChilds = 0;
+ }
+ nEntryCount = 0;
+ Broadcast( LISTACTION_CLEARED );
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+BOOL SvTreeList::IsChild( SvListEntry* pParent, SvListEntry* pChild ) const
+{
+ if ( !pParent )
+ pParent = pRootItem;
+
+ BOOL bIsChild = FALSE;
+ SvTreeEntryList* pList = pParent->pChilds;
+ if ( !pList )
+ return FALSE;
+ SvListEntry* pActualChild = (SvListEntry*)(pList->First());
+ while( !bIsChild && pActualChild )
+ {
+ if ( pActualChild == pChild )
+ bIsChild = TRUE;
+ else
+ {
+ if ( pActualChild->pChilds )
+ bIsChild = IsChild( pActualChild, pChild );
+ pActualChild = (SvListEntry*)(pList->Next());
+ }
+ }
+ return bIsChild;
+}
+
+ULONG SvTreeList::Move(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,ULONG nListPos)
+{
+ // pDest darf Null sein!
+ DBG_ASSERT(pSrcEntry,"Entry?");
+ if ( !pTargetParent )
+ pTargetParent = pRootItem;
+ DBG_ASSERT(pSrcEntry!=pTargetParent,"Move:Source=Target");
+
+ Broadcast( LISTACTION_MOVING, pSrcEntry, pTargetParent, nListPos );
+
+ if ( !pTargetParent->pChilds )
+ pTargetParent->pChilds = new SvTreeEntryList;
+ if ( pSrcEntry == pTargetParent )
+ return pSrcEntry->GetChildListPos();
+
+ bAbsPositionsValid = FALSE;
+
+ SvTreeEntryList* pDstList = pTargetParent->pChilds;
+ SvTreeEntryList* pSrcList = pSrcEntry->pParent->pChilds;
+
+ // Dummy-Ptr einfuegen, weil nListPos durch das
+ // folgende Remove ungueltig werden koennte
+ SvListEntry* pDummy = 0; pDstList->Insert( pDummy, nListPos );
+
+ // loeschen
+ pSrcList->Remove( pSrcEntry );
+ // Hat Parent noch Childs ?
+ if ( pSrcList->Count() == 0 )
+ {
+ // Keine Childs, deshalb Child-List loeschen
+ SvListEntry* pParent = pSrcEntry->pParent;
+ pParent->pChilds = 0;
+ delete pSrcList;
+ pSrcList = 0;
+ }
+
+ // Parent umsetzen (erst hier, weil wir zum Loeschen
+ // der ChildList den alten Parent noch benoetigen!)
+ pSrcEntry->pParent = pTargetParent;
+
+ pDstList->Replace( pSrcEntry, pDummy );
+
+ // Listenpositionen in Zielliste korrigieren
+ SetListPositions( pDstList );
+ if ( pSrcList && (ULONG)pSrcList != (ULONG)pDstList )
+ SetListPositions( pSrcList );
+
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+
+ ULONG nRetVal = pDstList->GetPos( pSrcEntry );
+ DBG_ASSERT(nRetVal==pSrcEntry->GetChildListPos(),"ListPos not valid");
+ Broadcast( LISTACTION_MOVED,pSrcEntry,pTargetParent,nRetVal);
+ return nRetVal;
+}
+
+ULONG SvTreeList::Copy(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,ULONG nListPos)
+{
+ // pDest darf Null sein!
+ DBG_ASSERT(pSrcEntry,"Entry?");
+ if ( !pTargetParent )
+ pTargetParent = pRootItem;
+ if ( !pTargetParent->pChilds )
+ pTargetParent->pChilds = new SvTreeEntryList;
+
+ bAbsPositionsValid = FALSE;
+
+ ULONG nCloneCount = 0;
+ SvListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount );
+ nEntryCount += nCloneCount;
+
+ SvTreeEntryList* pDstList = pTargetParent->pChilds;
+ pClonedEntry->pParent = pTargetParent; // Parent umsetzen
+ pDstList->Insert( pClonedEntry, nListPos ); // Einfuegen
+ SetListPositions( pDstList ); // Listenpositionen in Zielliste korrigieren
+
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+ Broadcast( LISTACTION_INSERTED_TREE, pClonedEntry );
+ ULONG nRetVal = pDstList->GetPos( pClonedEntry );
+ return nRetVal;
+}
+
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::Move( SvListEntry* pSrcEntry, SvListEntry* pDstEntry )
+{
+ SvListEntry* pParent;
+ ULONG nPos;
+
+ if ( !pDstEntry )
+ {
+ pParent = pRootItem;
+ nPos = 0UL;
+ }
+ else
+ {
+ pParent = pDstEntry->pParent;
+ nPos = pDstEntry->GetChildListPos();
+ nPos++; // UNTER (Bildschirm) pDstEntry einfuegen
+ }
+ Move( pSrcEntry, pParent, nPos );
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::Copy( SvListEntry* pSrcEntry, SvListEntry* pDstEntry )
+{
+ SvListEntry* pParent;
+ ULONG nPos;
+
+ if ( !pDstEntry )
+ {
+ pParent = pRootItem;
+ nPos = 0UL;
+ }
+ else
+ {
+ pParent = pDstEntry->pParent;
+ nPos = pDstEntry->GetChildListPos()+1;
+ }
+ Copy( pSrcEntry, pParent, nPos );
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+void SvTreeList::InsertTree( SvListEntry* pSrcEntry, SvListEntry* pDstEntry)
+{
+ SvListEntry* pParent;
+ ULONG nPos;
+
+ if ( !pDstEntry )
+ {
+ pParent = pRootItem;
+ nPos = 0UL;
+ }
+ else
+ {
+ pParent = pDstEntry->pParent;
+ nPos = pDstEntry->GetChildListPos()+1;
+ }
+ InsertTree( pSrcEntry, pParent, nPos );
+}
+
+
+void SvTreeList::InsertTree(SvListEntry* pSrcEntry,
+ SvListEntry* pTargetParent,ULONG nListPos)
+{
+ DBG_ASSERT(pSrcEntry,"InsertTree:Entry?");
+ if ( !pSrcEntry )
+ return;
+
+ if ( !pTargetParent )
+ pTargetParent = pRootItem;
+ if ( !pTargetParent->pChilds )
+ pTargetParent->pChilds = new SvTreeEntryList;
+
+ // Sortierung beruecksichtigen
+ GetInsertionPos( pSrcEntry, pTargetParent, nListPos );
+
+ bAbsPositionsValid = FALSE;
+
+ pSrcEntry->pParent = pTargetParent; // Parent umsetzen
+ SvTreeEntryList* pDstList = pTargetParent->pChilds;
+ pDstList->Insert( pSrcEntry, nListPos ); // einfuegen
+ SetListPositions(pDstList); // Listenpositionen in Zielliste korrigieren
+ nEntryCount += GetChildCount( pSrcEntry );
+ nEntryCount++; // der Parent ist ja auch neu
+
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+ Broadcast(LISTACTION_INSERTED_TREE, pSrcEntry );
+}
+
+SvListEntry* SvTreeList::CloneEntry( SvListEntry* pSource ) const
+{
+ if( aCloneLink.IsSet() )
+ return (SvListEntry*)aCloneLink.Call( pSource );
+ SvListEntry* pEntry = CreateEntry();
+ pSource->Clone( pEntry );
+ return pSource;
+}
+
+SvListEntry* SvTreeList::CreateEntry() const
+{
+ return new SvListEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::Clone( SvListEntry* pEntry, ULONG& nCloneCount ) const
+{
+ SvListEntry* pClonedEntry = CloneEntry( pEntry );
+ nCloneCount = 1;
+ SvTreeEntryList* pChilds = pEntry->pChilds;
+ if ( pChilds )
+ pClonedEntry->pChilds=CloneChilds(pChilds,pClonedEntry,nCloneCount);
+ return pClonedEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvTreeEntryList* SvTreeList::CloneChilds( SvTreeEntryList* pChilds,
+ SvListEntry* pNewParent,
+ ULONG& nCloneCount ) const
+{
+ DBG_ASSERT(pChilds->Count(),"Childs?");
+ SvTreeEntryList* pClonedChilds = new SvTreeEntryList;
+ SvListEntry* pChild = (SvListEntry*)pChilds->First();
+ while ( pChild )
+ {
+ SvListEntry* pNewChild = CloneEntry( pChild );
+ nCloneCount++;
+ pNewChild->pParent = pNewParent;
+ SvTreeEntryList* pSubChilds = pChild->pChilds;
+ if ( pSubChilds )
+ {
+ pSubChilds = CloneChilds( pSubChilds, pNewChild, nCloneCount );
+ pNewChild->pChilds = pSubChilds;
+ }
+
+ pClonedChilds->Insert( pNewChild, LIST_APPEND );
+ pChild = (SvListEntry*)pChilds->Next();
+ }
+ return pClonedChilds;
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::GetChildCount
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+ULONG SvTreeList::GetChildCount( SvListEntry* pParent ) const
+{
+ if ( !pParent )
+ return GetEntryCount();
+
+ if ( !pParent || !pParent->pChilds)
+ return 0;
+ ULONG nCount = 0;
+ USHORT nRefDepth = GetDepth( pParent );
+ USHORT nActDepth = nRefDepth;
+ do
+ {
+ pParent = Next( pParent, &nActDepth );
+ nCount++;
+ } while( pParent && nRefDepth < nActDepth );
+ nCount--;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+ULONG SvTreeList::GetVisibleChildCount(const SvListView* pView, SvListEntry* pParent) const
+{
+ DBG_ASSERT(pView,"GetVisChildCount:No View");
+ if ( !pParent )
+ pParent = pRootItem;
+ if ( !pParent || !pView->IsExpanded(pParent) || !pParent->pChilds )
+ return 0;
+ ULONG nCount = 0;
+ USHORT nRefDepth = GetDepth( pParent );
+ USHORT nActDepth = nRefDepth;
+ do
+ {
+ pParent = NextVisible( pView, pParent, &nActDepth );
+ nCount++;
+ } while( pParent && nRefDepth < nActDepth );
+ nCount--;
+ return nCount;
+}
+
+ULONG SvTreeList::GetChildSelectionCount(const SvListView* pView,SvListEntry* pParent) const
+{
+ DBG_ASSERT(pView,"GetChildSelCount:No View");
+ if ( !pParent )
+ pParent = pRootItem;
+ if ( !pParent || !pParent->pChilds)
+ return 0;
+ ULONG nCount = 0;
+ USHORT nRefDepth = GetDepth( pParent );
+ USHORT nActDepth = nRefDepth;
+ do
+ {
+ pParent = Next( pParent, &nActDepth );
+ if( pParent && pView->IsSelected( pParent ) && nRefDepth < nActDepth)
+ nCount++;
+ } while( pParent && nRefDepth < nActDepth );
+// nCount--;
+ return nCount;
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::First() const
+{
+ if ( nEntryCount )
+ return (SvListEntry*)(pRootItem->pChilds->GetObject(0));
+ else
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::Next
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+SvListEntry* SvTreeList::Next( SvListEntry* pActEntry, USHORT* pDepth ) const
+{
+ DBG_ASSERT( pActEntry && pActEntry->pParent, "SvTreeList::Next: invalid entry/parent!" );
+ if ( !pActEntry || !pActEntry->pParent )
+ return NULL;
+
+ USHORT nDepth = 0;
+ int bWithDepth = FALSE;
+ if ( pDepth )
+ {
+ nDepth = *pDepth;
+ bWithDepth = TRUE;
+ }
+
+ SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
+ ULONG nActualPos = pActEntry->GetChildListPos();
+
+ if ( pActEntry->pChilds /* && pActEntry->pChilds->Count() */ )
+ {
+ nDepth++;
+ pActEntry = (SvListEntry*)(pActEntry->pChilds->GetObject(0));
+ if ( bWithDepth )
+ *pDepth = nDepth;
+ return pActEntry;
+ }
+
+ if ( pActualList->Count() > ( nActualPos + 1 ) )
+ {
+ pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos + 1 ));
+ if ( bWithDepth )
+ *pDepth = nDepth;
+ return pActEntry;
+ }
+
+ SvListEntry* pParent = pActEntry->pParent;
+ nDepth--;
+ while( pParent != pRootItem && pParent != 0 )
+ {
+ DBG_ASSERT(pParent!=0,"TreeData corrupt!");
+ pActualList = pParent->pParent->pChilds;
+ DBG_ASSERT(pActualList,"TreeData corrupt!");
+ nActualPos = pParent->GetChildListPos();
+ if ( pActualList->Count() > ( nActualPos + 1 ) )
+ {
+ pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos + 1 ));
+ if ( bWithDepth )
+ *pDepth = nDepth;
+ return pActEntry;
+ }
+ pParent = pParent->pParent;
+ nDepth--;
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::Prev
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+SvListEntry* SvTreeList::Prev( SvListEntry* pActEntry, USHORT* pDepth ) const
+{
+ DBG_ASSERT(pActEntry!=0,"Entry?");
+
+ USHORT nDepth = 0;
+ int bWithDepth = FALSE;
+ if ( pDepth )
+ {
+ nDepth = *pDepth;
+ bWithDepth = TRUE;
+ }
+
+ SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
+ ULONG nActualPos = pActEntry->GetChildListPos();
+
+ if ( nActualPos > 0 )
+ {
+ pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos - 1 ));
+ while( pActEntry->pChilds /* && pActEntry->pChilds->Count() */ )
+ {
+ pActualList = pActEntry->pChilds;
+ nDepth++;
+ pActEntry = (SvListEntry*)(pActualList->Last());
+ }
+ if ( bWithDepth )
+ *pDepth = nDepth;
+ return pActEntry;
+ }
+ if ( pActEntry->pParent == pRootItem )
+ return 0;
+
+ pActEntry = pActEntry->pParent;
+
+ if ( pActEntry )
+ {
+ nDepth--;
+ if ( bWithDepth )
+ *pDepth = nDepth;
+ return pActEntry;
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::Last( USHORT* /* nDepth */ ) const
+{
+ SvTreeEntryList* pActList = pRootItem->pChilds;
+// if ( pActList->Count() == 0 )
+// return 0;
+ SvListEntry* pEntry = 0;
+ while( pActList )
+ {
+ pEntry = (SvListEntry*)(pActList->Last());
+ pActList = pEntry->pChilds;
+// if ( pActList->Count() == 0 )
+// pActList = 0;
+ }
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+ULONG SvTreeList::GetVisiblePos( const SvListView* pView, SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pView&&pEntry,"View/Entry?");
+
+ if ( !pView->bVisPositionsValid )
+ {
+ // damit GetVisibleCount die Positionen aktualisiert
+ ((SvListView*)pView)->nVisibleCount = 0;
+ GetVisibleCount( pView );
+ }
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ return pViewData->nVisPos;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+ULONG SvTreeList::GetVisibleCount( const SvListView* pView ) const
+{
+ DBG_ASSERT(pView,"GetVisCount:No View");
+ if( !pView->HasViewData() )
+ return 0;
+ if ( pView->nVisibleCount )
+ return pView->nVisibleCount;
+
+ ULONG nPos = 0;
+ SvListEntry* pEntry = First(); // erster Eintrag immer sichtbar
+ while ( pEntry )
+ {
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ pViewData->nVisPos = nPos;
+ nPos++;
+ pEntry = NextVisible( pView, pEntry );
+ }
+#ifdef DBG_UTIL
+ if( nPos > 10000000 )
+ {
+ DBG_ERROR("nVisibleCount bad");
+ }
+#endif
+ ((SvListView*)pView)->nVisibleCount = nPos;
+ ((SvListView*)pView)->bVisPositionsValid = TRUE;
+ return nPos;
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+// Funktion geht aus Geschwindigkeitsgruenden davon aus,
+// das der uebergebene Eintrag bereits sichtbar ist
+
+SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEntry,USHORT* pActDepth) const
+{
+ DBG_ASSERT(pView,"NextVisible:No View");
+ if ( !pActEntry )
+ return 0;
+
+ USHORT nDepth = 0;
+ int bWithDepth = FALSE;
+ if ( pActDepth )
+ {
+ nDepth = *pActDepth;
+ bWithDepth = TRUE;
+ }
+
+ SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
+ ULONG nActualPos = pActEntry->GetChildListPos();
+
+ if ( pView->IsExpanded(pActEntry) )
+ {
+ DBG_ASSERT(pActEntry->pChilds,"Childs?");
+ nDepth++;
+ pActEntry = (SvListEntry*)(pActEntry->pChilds->GetObject(0));
+ if ( bWithDepth )
+ *pActDepth = nDepth;
+ return pActEntry;
+ }
+
+ nActualPos++;
+ if ( pActualList->Count() > nActualPos )
+ {
+ pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos ));
+ if ( bWithDepth )
+ *pActDepth = nDepth;
+ return pActEntry;
+ }
+
+ SvListEntry* pParent = pActEntry->pParent;
+ nDepth--;
+ while( pParent != pRootItem )
+ {
+ pActualList = pParent->pParent->pChilds;
+ nActualPos = pParent->GetChildListPos();
+ nActualPos++;
+ if ( pActualList->Count() > nActualPos )
+ {
+ pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos ));
+ if ( bWithDepth )
+ *pActDepth = nDepth;
+ return pActEntry;
+ }
+ pParent = pParent->pParent;
+ nDepth--;
+ }
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+// Funktion geht aus Geschwindigkeitsgruenden davon aus,
+// das der uebergebene Eintrag bereits sichtbar ist
+
+SvListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvListEntry* pActEntry, USHORT* pActDepth) const
+{
+ DBG_ASSERT(pView&&pActEntry,"PrevVis:View/Entry?");
+
+ USHORT nDepth = 0;
+ int bWithDepth = FALSE;
+ if ( pActDepth )
+ {
+ nDepth = *pActDepth;
+ bWithDepth = TRUE;
+ }
+
+ SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
+ ULONG nActualPos = pActEntry->GetChildListPos();
+
+ if ( nActualPos > 0 )
+ {
+ pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos - 1 ));
+ while( pView->IsExpanded(pActEntry) )
+ {
+ pActualList = pActEntry->pChilds;
+ nDepth++;
+ pActEntry = (SvListEntry*)(pActualList->Last());
+ }
+ if ( bWithDepth )
+ *pActDepth = nDepth;
+ return pActEntry;
+ }
+
+ if ( pActEntry->pParent == pRootItem )
+ return 0;
+
+ pActEntry = pActEntry->pParent;
+ if ( pActEntry )
+ {
+ nDepth--;
+ if ( bWithDepth )
+ *pActDepth = nDepth;
+ return pActEntry;
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::LastVisible( const SvListView* pView, USHORT* pDepth) const
+{
+ DBG_ASSERT(pView,"LastVis:No View");
+ SvListEntry* pEntry = Last();
+ while( pEntry && !IsEntryVisible( pView, pEntry ) )
+ pEntry = PrevVisible( pView, pEntry );
+ if ( pEntry && pDepth )
+ *pDepth = GetDepth( pEntry );
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pEntry,USHORT& nDelta) const
+{
+ DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"NextVis:Wrong Prms/!Vis");
+
+ ULONG nVisPos = GetVisiblePos( pView, pEntry );
+ // nDelta Eintraege vorhanden ?
+ // Beispiel: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7
+ // nNewDelta = 10-nVisPos-1 == 4
+ if ( nVisPos+nDelta >= pView->nVisibleCount )
+ {
+ nDelta = (USHORT)(pView->nVisibleCount-nVisPos);
+ nDelta--;
+ }
+ USHORT nDeltaTmp = nDelta;
+ while( nDeltaTmp )
+ {
+ pEntry = NextVisible( pView, pEntry );
+ nDeltaTmp--;
+ DBG_ASSERT(pEntry,"Entry?");
+ }
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvListEntry* pEntry, USHORT& nDelta ) const
+{
+ DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"PrevVis:Parms/!Vis");
+
+ ULONG nVisPos = GetVisiblePos( pView, pEntry );
+ // nDelta Eintraege vorhanden ?
+ // Beispiel: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20
+ // nNewDelta = nNewVisPos
+ if ( nDelta > nVisPos )
+ nDelta = (USHORT)nVisPos;
+ USHORT nDeltaTmp = nDelta;
+ while( nDeltaTmp )
+ {
+ pEntry = PrevVisible( pView, pEntry );
+ nDeltaTmp--;
+ DBG_ASSERT(pEntry,"Entry?");
+ }
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::FirstSelected( const SvListView* pView) const
+{
+ DBG_ASSERT(pView,"FirstSel:No View");
+ if( !pView )
+ return 0;
+ SvListEntry* pActSelEntry = First();
+ while( pActSelEntry && !pView->IsSelected(pActSelEntry) )
+ pActSelEntry = NextVisible( pView, pActSelEntry );
+ return pActSelEntry;
+}
+
+
+SvListEntry* SvTreeList::FirstChild( SvListEntry* pParent ) const
+{
+ if ( !pParent )
+ pParent = pRootItem;
+ SvListEntry* pResult;
+ if ( pParent->pChilds )
+ pResult = (SvListEntry*)(pParent->pChilds->GetObject( 0 ));
+ else
+ pResult = 0;
+ return pResult;
+}
+
+SvListEntry* SvTreeList::NextSibling( SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pEntry,"Entry?");
+ if( !pEntry )
+ return 0;
+ SvTreeEntryList* pList = pEntry->pParent->pChilds;
+// ULONG nPos = pList->GetPos( pEntry );
+ ULONG nPos = pEntry->GetChildListPos();
+ nPos++;
+ pEntry = (SvListEntry*)(pList->GetObject( nPos ));
+ return pEntry;
+}
+
+SvListEntry* SvTreeList::PrevSibling( SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pEntry,"Entry?");
+ if( !pEntry )
+ return 0;
+
+ SvTreeEntryList* pList = pEntry->pParent->pChilds;
+ // ULONG nPos = pList->GetPos( pEntry );
+ ULONG nPos = pEntry->GetChildListPos();
+ if ( nPos == 0 )
+ return 0;
+ nPos--;
+ pEntry = (SvListEntry*)(pList->GetObject( nPos ));
+ return pEntry;
+}
+
+
+SvListEntry* SvTreeList::LastSibling( SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pEntry,"LastSibling:Entry?");
+ if( !pEntry )
+ return 0;
+ SvListEntry* pSib = 0;
+ SvTreeEntryList* pSibs = pEntry->pParent->pChilds;
+ if ( pSibs )
+ pSib = (SvListEntry*)(pSibs->Last());
+ return pSib;
+}
+
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::NextSelected( const SvListView* pView, SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pView&&pEntry,"NextSel:View/Entry?");
+ pEntry = Next( pEntry );
+ while( pEntry && !pView->IsSelected(pEntry) )
+ pEntry = Next( pEntry );
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvListEntry* pEntry) const
+{
+ DBG_ASSERT(pView&&pEntry,"PrevSel:View/Entry?");
+ pEntry = Prev( pEntry );
+ while( pEntry && !pView->IsSelected(pEntry) )
+ pEntry = Prev( pEntry );
+
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+SvListEntry* SvTreeList::LastSelected( const SvListView* pView ) const
+{
+ DBG_ASSERT(pView,"LastSel:No View");
+ SvListEntry* pEntry = Last();
+ while( pEntry && !pView->IsSelected(pEntry) )
+ pEntry = Prev( pEntry );
+ return pEntry;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::Insert
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+ULONG SvTreeList::Insert( SvListEntry* pEntry,SvListEntry* pParent,ULONG nPos )
+{
+ DBG_ASSERT( pEntry,"Entry?");
+
+ if ( !pParent )
+ pParent = pRootItem;
+
+
+ SvTreeEntryList* pList = pParent->pChilds;
+ if ( !pList )
+ {
+ // Parent bekommt zum erstenmal ein Kind
+ pList = new SvTreeEntryList;
+ pParent->pChilds = pList;
+ }
+
+ // Sortierung beruecksichtigen
+ GetInsertionPos( pEntry, pParent, nPos );
+
+ bAbsPositionsValid = FALSE;
+ pEntry->pParent = pParent;
+
+ pList->Insert( pEntry, nPos );
+ nEntryCount++;
+ if( nPos != LIST_APPEND && (nPos != (pList->Count()-1)) )
+ SetListPositions( pList );
+ else
+ pEntry->nListPos = pList->Count()-1;
+
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+ Broadcast( LISTACTION_INSERTED, pEntry );
+ return nPos; // pEntry->nListPos;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+ULONG SvTreeList::GetAbsPos( SvListEntry* pEntry) const
+{
+ if ( !bAbsPositionsValid )
+ ((SvTreeList*)this)->SetAbsolutePositions();
+ return pEntry->nAbsPos;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::SetAbsolutePositions()
+{
+ ULONG nPos = 0;
+ SvListEntry* pEntry = First();
+ while ( pEntry )
+ {
+ pEntry->nAbsPos = nPos;
+ nPos++;
+ pEntry = Next( pEntry );
+ }
+ bAbsPositionsValid = TRUE;
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::Expand
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::Expand( SvListView* pView, SvListEntry* pEntry )
+{
+ DBG_ASSERT(pEntry&&pView,"Expand:View/Entry?");
+ if ( pView->IsExpanded(pEntry) )
+ return;
+
+ DBG_ASSERT(pEntry->pChilds,"Expand:No Childs!");
+
+ SvViewData* pViewData = pView->GetViewData(pEntry);
+ pViewData->nFlags |= SVLISTENTRYFLAG_EXPANDED;
+ SvListEntry* pParent = pEntry->pParent;
+ // wenn Parent sichtbar dann Statusdaten invalidieren
+ if ( pView->IsExpanded( pParent ) )
+ {
+ pView->bVisPositionsValid = FALSE;
+ pView->nVisibleCount = 0;
+ }
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::Collapse
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+void SvTreeList::Collapse( SvListView* pView, SvListEntry* pEntry )
+{
+ DBG_ASSERT(pView&&pEntry,"Collapse:View/Entry?");
+ if ( !pView->IsExpanded(pEntry) )
+ return;
+
+ DBG_ASSERT(pEntry->pChilds,"Collapse:No Childs!");
+
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ pViewData->nFlags &=(~SVLISTENTRYFLAG_EXPANDED);
+
+ SvListEntry* pParent = pEntry->pParent;
+ if ( pView->IsExpanded(pParent) )
+ {
+ pView->nVisibleCount = 0;
+ pView->bVisPositionsValid = FALSE;
+ }
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+}
+
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+BOOL SvTreeList::Select( SvListView* pView, SvListEntry* pEntry, BOOL bSelect )
+{
+ DBG_ASSERT(pView&&pEntry,"Select:View/Entry?");
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ if ( bSelect )
+ {
+ if ( pViewData->IsSelected() || !pViewData->IsSelectable() )
+ return FALSE;
+ else
+ {
+ pViewData->nFlags |= SVLISTENTRYFLAG_SELECTED;
+ pView->nSelectionCount++;
+ }
+ }
+ else
+ {
+ if ( !pViewData->IsSelected() )
+ return FALSE;
+ else
+ {
+ pViewData->nFlags &= ~( SVLISTENTRYFLAG_SELECTED );
+ pView->nSelectionCount--;
+ }
+ }
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::Remove
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 05.04.01
+|*
+*************************************************************************/
+BOOL SvTreeList::Remove( SvListEntry* pEntry )
+{
+ DBG_ASSERT(pEntry,"Cannot remove root, use clear");
+
+ if( !pEntry->pParent )
+ {
+ DBG_ERROR("Removing entry not in model!");
+ // unter gewissen Umstaenden (welche?) loescht der
+ // Explorer aus der View Eintraege, die er nicht in die View
+ // eingefuegt hat. Da sich der Kunde fuer ein platzendes
+ // Office nichts kaufen kann, fange ich diesen Fall ab.
+ return FALSE;
+ }
+
+ Broadcast( LISTACTION_REMOVING, pEntry );
+ ULONG nRemoved = 1 + GetChildCount(pEntry);
+ bAbsPositionsValid = FALSE;
+
+ SvListEntry* pParent = pEntry->pParent;
+ SvTreeEntryList* pList = pParent->pChilds;
+ DBG_ASSERT(pList,"Remove:No Childlist");
+ BOOL bLastEntry = FALSE;
+
+ if ( pEntry->HasChildListPos() )
+ {
+ ULONG nListPos = pEntry->GetChildListPos();
+ bLastEntry = (nListPos == (pList->Count()-1) ) ? TRUE : FALSE;
+ pList->Remove( nListPos );
+ }
+ else
+ {
+ pList->Remove( (void*) pEntry );
+ }
+
+
+ // moved to end of method because it is used later with Broadcast
+ // delete pEntry; // loescht auch alle Childs
+
+ if ( pList->Count() == 0 )
+ {
+ pParent->pChilds = 0;
+ delete pList;
+ }
+ else
+ {
+ if( !bLastEntry )
+ SetListPositions( pList );
+ }
+ nEntryCount -= nRemoved;
+
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+ Broadcast( LISTACTION_REMOVED, pEntry );
+
+ delete pEntry; // loescht auch alle Childs
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SvTreeList::
+|*
+|* Beschreibung
+|* Ersterstellung 17.08.94
+|* Letzte Aenderung 17.08.94
+|*
+*************************************************************************/
+
+ULONG SvTreeList::SelectChilds(SvListView* pView, SvListEntry* pParent,BOOL bSelect )
+{
+ DBG_ASSERT(pView&&pParent,"SelChilds:View/Parent?");
+ if ( !pParent->pChilds )
+ return 0;
+ if ( pParent->pChilds->Count() == 0 )
+ return 0;
+
+ USHORT nRefDepth = GetDepth( pParent );
+ USHORT nDepth = nRefDepth;
+ ULONG nCount = 0;
+ pParent = Next( pParent );
+ do
+ {
+ if ( Select( pView, pParent, bSelect ) )
+ nCount++; // nur die tatsaechlichen Selektierungen zaehlen
+ pParent = Next( pParent, &nDepth );
+ }
+ while( pParent && nDepth > nRefDepth );
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+ return nCount;
+}
+
+void SvTreeList::SelectAll( SvListView* pView, BOOL bSelect )
+{
+ DBG_ASSERT(pView,"SelectAll:NoView");
+ SvListEntry* pEntry = First();
+ while ( pEntry )
+ {
+ SvViewData* pViewData = pView->GetViewData( pEntry );
+ if ( bSelect )
+ pViewData->nFlags |= SVLISTENTRYFLAG_SELECTED;
+ else
+ pViewData->nFlags &= (~SVLISTENTRYFLAG_SELECTED);
+
+ pEntry = Next( pEntry );
+ }
+ if ( bSelect )
+ pView->nSelectionCount = nEntryCount;
+ else
+ pView->nSelectionCount = 0;
+#ifdef CHECK_INTEGRITY
+CheckIntegrity();
+#endif
+}
+
+
+SvListEntry* SvTreeList::GetEntryAtAbsPos( ULONG nAbsPos ) const
+{
+ SvListEntry* pEntry = First();
+ while ( nAbsPos && pEntry )
+ {
+ pEntry = Next( pEntry );
+ nAbsPos--;
+ }
+ return pEntry;
+}
+
+SvListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, ULONG nVisPos ) const
+{
+ DBG_ASSERT(pView,"GetEntryAtVisPos:No View");
+ SvListEntry* pEntry = First();
+ while ( nVisPos && pEntry )
+ {
+ pEntry = NextVisible( pView, pEntry );
+ nVisPos--;
+ }
+ return pEntry;
+}
+
+void SvTreeList::SetListPositions( SvTreeEntryList* pList )
+{
+ if( pList->Count() )
+ {
+ SvListEntry* pEntry = (SvListEntry*)(pList->GetObject(0));
+ if( pEntry->pParent )
+ pEntry->pParent->InvalidateChildrensListPositions();
+ }
+ /*
+ ULONG nListPos = 0;
+ SvListEntry* pEntry = (SvListEntry*)(pList->First());
+ while( pEntry )
+ {
+ pEntry->nListPos = nListPos;
+ nListPos++;
+ pEntry = (SvListEntry*)(pList->Next());
+ }
+ */
+}
+
+
+void SvTreeList::InvalidateEntry( SvListEntry* pEntry )
+{
+ Broadcast( LISTACTION_INVALIDATE_ENTRY, pEntry );
+}
+
+BOOL SvTreeList::IsInChildList( SvListEntry* pParent, SvListEntry* pChild) const
+{
+ if ( !pParent )
+ pParent = pRootItem;
+ BOOL bIsChild = FALSE;
+ if ( pParent->pChilds )
+ bIsChild = (BOOL)(pParent->pChilds->GetPos(pChild) != LIST_ENTRY_NOTFOUND);
+ return bIsChild;
+}
+
+
+void lcl_CheckList( SvTreeEntryList* pList )
+{
+ SvListEntry* pEntry = (SvListEntry*)(pList->First());
+ ULONG nPos = 0;
+ while ( pEntry )
+ {
+ DBG_ASSERT(pEntry->GetChildListPos()==nPos,"Wrong ListPos");
+ pEntry = (SvListEntry*)(pList->Next());
+ nPos++;
+ }
+}
+
+void SvTreeList::CheckIntegrity() const
+{
+ ULONG nMyEntryCount = 0;
+ if ( pRootItem->pChilds )
+ {
+ lcl_CheckList( pRootItem->pChilds );
+ SvListEntry* pEntry = First();
+ while( pEntry )
+ {
+ nMyEntryCount++;
+ if ( pEntry->pChilds )
+ lcl_CheckList( pEntry->pChilds );
+ pEntry = Next( pEntry );
+ }
+ }
+ DBG_ASSERT(nMyEntryCount==GetEntryCount(),"Entry count invalid");
+}
+
+SvListEntry* SvTreeList::GetRootLevelParent( SvListEntry* pEntry ) const
+{
+ DBG_ASSERT(pEntry,"GetRootLevelParent:No Entry");
+ SvListEntry* pCurParent = 0;
+ if ( pEntry )
+ {
+ pCurParent = pEntry->pParent;
+ if ( pCurParent == pRootItem )
+ return pEntry; // ist sein eigener Parent
+ while( pCurParent && pCurParent->pParent != pRootItem )
+ pCurParent = pCurParent->pParent;
+ }
+ return pCurParent;
+}
+
+
+
+
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+
+DBG_NAME(SvListView);
+
+SvListView::SvListView( SvTreeList* pModell )
+{
+ DBG_CTOR(SvListView,0);
+ pModel = 0;
+ nSelectionCount = 0;
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+ SetModel( pModell );
+}
+
+SvListView::SvListView()
+{
+ DBG_CTOR(SvListView,0);
+ pModel = 0;
+ nSelectionCount = 0;
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+}
+
+
+SvListView::~SvListView()
+{
+ DBG_DTOR(SvListView,0);
+ ClearTable();
+}
+
+void SvListView::InitTable()
+{
+ DBG_CHKTHIS(SvListView,0);
+ DBG_ASSERT(pModel,"InitTable:No Model");
+ DBG_ASSERT(!nSelectionCount&&!nVisibleCount&&!bVisPositionsValid,"InitTable: Not cleared!");
+
+ if( aDataTable.Count() )
+ {
+ DBG_ASSERT(aDataTable.Count()==1,"InitTable: TableCount != 1");
+ // die im Clear fuer die Root allozierten View-Daten loeschen
+ // Achtung: Das zu dem RootEntry (und damit auch der Entry)
+ // gehoerende Model kann bereits geloescht sein!
+ SvViewData* pViewData = (SvViewData*)aDataTable.GetObject( 0 );
+ delete pViewData;
+ aDataTable.Clear();
+ }
+
+ SvListEntry* pEntry;
+ SvViewData* pViewData;
+
+ // RootEntry einfuegen
+ pEntry = pModel->pRootItem;
+ pViewData = new SvViewData;
+ pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED;
+ aDataTable.Insert( (ULONG)pEntry, pViewData );
+ // Jetzt alle anderen Entries
+ pEntry = pModel->First();
+ while( pEntry )
+ {
+ pViewData = CreateViewData( pEntry );
+ DBG_ASSERT(pViewData,"InitTable:No ViewData");
+ InitViewData( pViewData, pEntry );
+ aDataTable.Insert( (ULONG)pEntry, pViewData );
+ pEntry = pModel->Next( pEntry );
+ }
+}
+
+SvViewData* SvListView::CreateViewData( SvListEntry* )
+{
+ DBG_CHKTHIS(SvListView,0);
+ return new SvViewData;
+}
+
+void SvListView::ClearTable()
+{
+ DBG_CHKTHIS(SvListView,0);
+ SvViewData* pViewData = (SvViewData*)aDataTable.First();
+ while( pViewData )
+ {
+ delete pViewData;
+ pViewData = (SvViewData*)aDataTable.Next();
+ }
+ aDataTable.Clear();
+}
+
+void SvListView::Clear()
+{
+ ClearTable();
+ nSelectionCount = 0;
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+ if( pModel )
+ {
+ // RootEntry einfuegen
+ SvListEntry* pEntry = pModel->pRootItem;
+ SvViewData* pViewData = new SvViewData;
+ pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED;
+ aDataTable.Insert( (ULONG)pEntry, pViewData );
+ }
+}
+
+void SvListView::SetModel( SvTreeList* pNewModel )
+{
+ DBG_CHKTHIS(SvListView,0);
+ BOOL bBroadcastCleared = FALSE;
+ if ( pModel )
+ {
+ pModel->RemoveView( this );
+ bBroadcastCleared = TRUE;
+ ModelNotification( LISTACTION_CLEARING,0,0,0 );
+ if ( pModel->GetRefCount() == 0 )
+ delete pModel;
+ }
+ pModel = pNewModel;
+ InitTable();
+ pNewModel->InsertView( this );
+ if( bBroadcastCleared )
+ ModelNotification( LISTACTION_CLEARED,0,0,0 );
+}
+
+
+void SvListView::ModelHasCleared()
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ModelHasInserted( SvListEntry* )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ModelHasInsertedTree( SvListEntry* )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ModelIsMoving( SvListEntry* /* pSource */ ,
+ SvListEntry* /* pTargetParent */ , ULONG /* nPos */ )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+
+void SvListView::ModelHasMoved( SvListEntry* )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ModelIsRemoving( SvListEntry* )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ModelHasRemoved( SvListEntry* )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ModelHasEntryInvalidated( SvListEntry*)
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ActionMoving( SvListEntry* pEntry,SvListEntry*,ULONG)
+{
+ DBG_CHKTHIS(SvListView,0);
+ SvListEntry* pParent = pEntry->pParent;
+ DBG_ASSERT(pParent,"Model not consistent");
+ if( pParent != pModel->pRootItem && pParent->pChilds->Count() == 1 )
+ {
+ SvViewData* pViewData = (SvViewData*)aDataTable.Get( (ULONG)pParent );
+ pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED);
+ }
+ // vorlaeufig
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+}
+
+void SvListView::ActionMoved( SvListEntry* /* pEntry */ ,
+ SvListEntry* /* pTargetPrnt */ ,
+ ULONG /* nChildPos */ )
+{
+ DBG_CHKTHIS(SvListView,0);
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+}
+
+void SvListView::ActionInserted( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvListView,0);
+ DBG_ASSERT(pEntry,"Insert:No Entry");
+ SvViewData* pData = CreateViewData( pEntry );
+ InitViewData( pData, pEntry );
+ #ifdef DBG_UTIL
+ BOOL bSuccess =
+ #endif
+ aDataTable.Insert( (ULONG)pEntry, pData );
+ DBG_ASSERT(bSuccess,"Entry already in View");
+ if ( nVisibleCount && pModel->IsEntryVisible( this, pEntry ))
+ {
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+ }
+}
+
+void SvListView::ActionInsertedTree( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvListView,0);
+ if ( pModel->IsEntryVisible( this, pEntry ))
+ {
+ nVisibleCount = 0;
+ bVisPositionsValid = FALSE;
+ }
+ // ueber Entry und seine Childs iterieren
+ SvListEntry* pCurEntry = pEntry;
+ USHORT nRefDepth = pModel->GetDepth( pCurEntry );
+ while( pCurEntry )
+ {
+ DBG_ASSERT(aDataTable.Get((ULONG)pCurEntry)==0,"Entry already in Table");
+ SvViewData* pViewData = CreateViewData( pCurEntry );
+ DBG_ASSERT(pViewData,"No ViewData");
+ InitViewData( pViewData, pEntry );
+ aDataTable.Insert( (ULONG)pCurEntry, pViewData );
+ pCurEntry = pModel->Next( pCurEntry );
+ if ( pCurEntry && pModel->GetDepth(pCurEntry) <= nRefDepth)
+ pCurEntry = 0;
+ }
+}
+
+void SvListView::RemoveViewData( SvListEntry* pParent )
+{
+ SvTreeEntryList* pChilds = pParent->pChilds;
+ if( pChilds )
+ {
+ SvListEntry* pCur = (SvListEntry*)pChilds->First();
+ while( pCur )
+ {
+ SvViewData* pViewData = (SvViewData*)aDataTable.Get((ULONG)pCur);
+ delete pViewData;
+ aDataTable.Remove( (ULONG)pCur );
+ if( pCur->HasChilds())
+ RemoveViewData( pCur );
+ pCur = (SvListEntry*)pChilds->Next();
+ }
+ }
+}
+
+
+
+void SvListView::ActionRemoving( SvListEntry* pEntry )
+{
+ DBG_CHKTHIS(SvListView,0);
+ DBG_ASSERT(pEntry,"Remove:No Entry");
+
+ SvViewData* pViewData = (SvViewData*)aDataTable.Get( (ULONG)pEntry );
+ ULONG nSelRemoved = 0;
+ if ( pViewData->IsSelected() )
+ nSelRemoved = 1 + pModel->GetChildSelectionCount( this, pEntry );
+ nSelectionCount -= nSelRemoved;
+ ULONG nVisibleRemoved = 0;
+ if ( pModel->IsEntryVisible( this, pEntry ) )
+ nVisibleRemoved = 1 + pModel->GetVisibleChildCount( this, pEntry );
+ if( nVisibleCount )
+ {
+#ifdef DBG_UTIL
+ if( nVisibleCount < nVisibleRemoved )
+ {
+ DBG_ERROR("nVisibleRemoved bad");
+ }
+#endif
+ nVisibleCount -= nVisibleRemoved;
+ }
+ bVisPositionsValid = FALSE;
+
+ pViewData = (SvViewData*)aDataTable.Get((ULONG)pEntry);
+ delete pViewData;
+ aDataTable.Remove( (ULONG)pEntry );
+ RemoveViewData( pEntry );
+
+ SvListEntry* pCurEntry = pEntry->pParent;
+ if ( pCurEntry && pCurEntry != pModel->pRootItem &&
+ pCurEntry->pChilds->Count() == 1 )
+ {
+ pViewData = (SvViewData*)aDataTable.Get((ULONG)pCurEntry);
+ pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED);
+ }
+}
+
+void SvListView::ActionRemoved( SvListEntry* /* pEntry */ )
+{
+ DBG_CHKTHIS(SvListView,0);
+}
+
+void SvListView::ActionClear()
+{
+ DBG_CHKTHIS(SvListView,0);
+ Clear();
+}
+
+void SvListView::ModelNotification( USHORT nActionId, SvListEntry* pEntry1,
+ SvListEntry* pEntry2, ULONG nPos )
+{
+ DBG_CHKTHIS(SvListView,0);
+ switch( nActionId )
+ {
+ case LISTACTION_INSERTED:
+ ActionInserted( pEntry1 );
+ ModelHasInserted( pEntry1 );
+ break;
+ case LISTACTION_INSERTED_TREE:
+ ActionInsertedTree( pEntry1 );
+ ModelHasInsertedTree( pEntry1 );
+ break;
+ case LISTACTION_REMOVING:
+ ModelIsRemoving( pEntry1 );
+ ActionRemoving( pEntry1 );
+ break;
+ case LISTACTION_REMOVED:
+ ActionRemoved( pEntry1 );
+ ModelHasRemoved( pEntry1 );
+ break;
+ case LISTACTION_MOVING:
+ ModelIsMoving( pEntry1, pEntry2, nPos );
+ ActionMoving( pEntry1, pEntry2, nPos );
+ break;
+ case LISTACTION_MOVED:
+ ActionMoved( pEntry1, pEntry2, nPos );
+ ModelHasMoved( pEntry1 );
+ break;
+ case LISTACTION_CLEARING:
+ ActionClear();
+ ModelHasCleared(); //sic! wg. Kompatibilitaet!
+ break;
+ case LISTACTION_CLEARED:
+ break;
+ case LISTACTION_INVALIDATE_ENTRY:
+ // keine Action fuer die Basisklasse
+ ModelHasEntryInvalidated( pEntry1 );
+ break;
+ case LISTACTION_RESORTED:
+ bVisPositionsValid = FALSE;
+ break;
+ case LISTACTION_RESORTING:
+ break;
+ default:
+ DBG_ERROR("unknown ActionId");
+ }
+}
+
+void SvListView::InitViewData( SvViewData*, SvListEntry* )
+{
+}
+
+StringCompare SvTreeList::Compare( SvListEntry* pLeft, SvListEntry* pRight) const
+{
+ if( aCompareLink.IsSet())
+ {
+ SvSortData aSortData;
+ aSortData.pLeft = pLeft;
+ aSortData.pRight = pRight;
+ return (StringCompare)aCompareLink.Call( &aSortData );
+ }
+ return COMPARE_EQUAL;
+}
+
+void SvTreeList::Resort()
+{
+ Broadcast( LISTACTION_RESORTING );
+ bAbsPositionsValid = FALSE;
+ ResortChilds( pRootItem );
+ Broadcast( LISTACTION_RESORTED );
+}
+
+void SvTreeList::ResortChilds( SvListEntry* pParent )
+{
+ DBG_ASSERT(pParent,"Parent not set");
+ List* pChildList = pParent->pChilds;
+ if( !pChildList )
+ return;
+ List aList( *pChildList );
+ pChildList->Clear();
+
+ ULONG nCount = aList.Count();
+ for( ULONG nCur = 0; nCur < nCount; nCur++ )
+ {
+ SvListEntry* pCurEntry = (SvListEntry*)aList.GetObject( nCur );
+ ULONG nListPos = LIST_APPEND;
+ GetInsertionPos( pCurEntry, pParent, nListPos );
+ pChildList->Insert( pCurEntry, nListPos );
+ if( pCurEntry->pChilds )
+ ResortChilds( pCurEntry );
+ }
+ SetListPositions( (SvTreeEntryList*)pChildList );
+}
+
+void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent,
+ ULONG& rPos )
+{
+ DBG_ASSERT(pEntry,"No Entry");
+
+ if( eSortMode == SortNone )
+ return;
+
+ rPos = LIST_APPEND;
+ SvTreeEntryList* pChildList = GetChildList( pParent );
+
+ if( pChildList && pChildList->Count() )
+ {
+ long i = 0;
+ long j = pChildList->Count()-1;
+ long k;
+ StringCompare eCompare = COMPARE_GREATER;
+
+ do
+ {
+ k = (i+j)/2;
+ SvListEntry* pTempEntry = (SvListEntry*)(pChildList->GetObject(k));
+ eCompare = Compare( pEntry, pTempEntry );
+ if( eSortMode == SortDescending && eCompare != COMPARE_EQUAL )
+ {
+ if( eCompare == COMPARE_LESS )
+ eCompare = COMPARE_GREATER;
+ else
+ eCompare = COMPARE_LESS;
+ }
+ if( eCompare == COMPARE_GREATER )
+ i = k + 1;
+ else
+ j = k - 1;
+ } while( (eCompare != COMPARE_EQUAL) && (i <= j) );
+
+ if( eCompare != COMPARE_EQUAL )
+ {
+ if(i > ((long)pChildList->Count() - 1)) // nicht gefunden, Ende der Liste
+ rPos = LIST_APPEND;
+ else
+ rPos = i; // nicht gefunden, Mitte
+ }
+ else
+ rPos = k;
+ }
+}
+
+
diff --git a/svtools/source/control/asynclink.cxx b/svtools/source/control/asynclink.cxx
new file mode 100644
index 000000000000..04b2b58367ee
--- /dev/null
+++ b/svtools/source/control/asynclink.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_svtools.hxx"
+
+#include <asynclink.hxx>
+#include <vos/mutex.hxx>
+#include <tools/debug.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/svapp.hxx>
+
+//--------------------------------------------------------------------
+namespace svtools {
+
+void AsynchronLink::CreateMutex()
+{
+ if( !_pMutex ) _pMutex = new vos::OMutex;
+}
+
+void AsynchronLink::Call( void* pObj, BOOL
+#ifdef DBG_UTIL
+bAllowDoubles
+#endif
+, BOOL bUseTimer )
+{
+#ifdef DBG_UTIL
+ if ( bUseTimer || !_bInCall )
+ DBG_WARNING( "Recursives Call. Eher ueber Timer. TLX Fragen" );
+#endif
+ if( _aLink.IsSet() )
+ {
+ _pArg = pObj;
+ DBG_ASSERT( bAllowDoubles ||
+ ( !_nEventId && ( !_pTimer || !_pTimer->IsActive() ) ),
+ "Schon ein Call unterwegs" );
+ if( _nEventId )
+ {
+ if( _pMutex ) _pMutex->acquire();
+ Application::RemoveUserEvent( _nEventId );
+ if( _pMutex ) _pMutex->release();
+ }
+ if( _pTimer )_pTimer->Stop();
+ if( bUseTimer )
+ {
+ if( !_pTimer )
+ {
+ _pTimer = new Timer;
+ _pTimer->SetTimeout( 0 );
+ _pTimer->SetTimeoutHdl( STATIC_LINK(
+ this, AsynchronLink, HandleCall) );
+ }
+ _pTimer->Start();
+ }
+ else
+ {
+ if( _pMutex ) _pMutex->acquire();
+ Application::PostUserEvent( _nEventId, STATIC_LINK( this, AsynchronLink, HandleCall), 0 );
+ if( _pMutex ) _pMutex->release();
+ }
+ }
+}
+
+AsynchronLink::~AsynchronLink()
+{
+ if( _nEventId )
+ {
+ Application::RemoveUserEvent( _nEventId );
+ }
+ delete _pTimer;
+ if( _pDeleted ) *_pDeleted = TRUE;
+ delete _pMutex;
+}
+
+IMPL_STATIC_LINK( AsynchronLink, HandleCall, void*, EMPTYARG )
+{
+ if( pThis->_pMutex ) pThis->_pMutex->acquire();
+ pThis->_nEventId = 0;
+ if( pThis->_pMutex ) pThis->_pMutex->release();
+ pThis->Call_Impl( pThis->_pArg );
+ return 0;
+}
+
+void AsynchronLink::ForcePendingCall()
+{
+ ClearPendingCall();
+ Call_Impl( _pArg );
+}
+
+void AsynchronLink::ClearPendingCall()
+{
+ if( _pMutex ) _pMutex->acquire();
+ if( _nEventId )
+ {
+ Application::RemoveUserEvent( _nEventId );
+ _nEventId = 0;
+ }
+ if( _pMutex ) _pMutex->release();
+ if( _pTimer ) _pTimer->Stop();
+}
+
+void AsynchronLink::Call_Impl( void* pArg )
+{
+ _bInCall = TRUE;
+ BOOL bDeleted = FALSE;
+ _pDeleted = &bDeleted;
+ _aLink.Call( pArg );
+ if( !bDeleted )
+ {
+ _bInCall = FALSE;
+ _pDeleted = 0;
+ }
+}
+
+}
diff --git a/svtools/source/control/calendar.cxx b/svtools/source/control/calendar.cxx
new file mode 100755
index 000000000000..f7b49ac57eeb
--- /dev/null
+++ b/svtools/source/control/calendar.cxx
@@ -0,0 +1,3051 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifndef _APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _TABLE_HXX
+#include <tools/table.hxx>
+#endif
+#ifndef _HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _MENU_HXX
+#include <vcl/menu.hxx>
+#endif
+#ifndef _DECOVIEW_HXX
+#include <vcl/decoview.hxx>
+#endif
+#ifndef _FLOATWIN_HXX
+#include <vcl/floatwin.hxx>
+#endif
+#ifndef _BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX
+#include <vcl/fixed.hxx>
+#endif
+#include <unotools/calendarwrapper.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <com/sun/star/i18n/Weekdays.hpp>
+#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
+#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
+
+#define _SV_CALENDAR_CXX
+#include <svtools/svtools.hrc>
+#include <svtools/svtdata.hxx>
+#include <calendar.hxx>
+
+// =======================================================================
+
+#define DAY_OFFX 4
+#define DAY_OFFY 2
+#define MONTH_BORDERX 4
+#define MONTH_OFFY 3
+#define WEEKNUMBER_OFFX 4
+#define WEEKDAY_OFFY 3
+#define TITLE_OFFY 3
+#define TITLE_BORDERY 2
+#define SPIN_OFFX 4
+#define SPIN_OFFY TITLE_BORDERY
+
+#define WEEKNUMBER_HEIGHT 85
+
+#define CALENDAR_HITTEST_DAY ((USHORT)0x0001)
+#define CALENDAR_HITTEST_WEEK ((USHORT)0x0002)
+#define CALENDAR_HITTEST_MONTHTITLE ((USHORT)0x0004)
+#define CALENDAR_HITTEST_PREV ((USHORT)0x0008)
+#define CALENDAR_HITTEST_NEXT ((USHORT)0x0010)
+#define CALENDAR_HITTEST_OUTSIDE ((USHORT)0x1000)
+
+#define MENU_YEAR_COUNT 3
+
+#define TABLE_DATE_SELECTED ((void*)0x00000001)
+
+using namespace ::com::sun::star;
+
+// =======================================================================
+
+struct ImplDateInfo
+{
+ XubString maText;
+ Color* mpTextColor;
+ Color* mpFrameColor;
+ USHORT mnFlags;
+
+ ImplDateInfo( const XubString& rText ) :
+ maText( rText )
+ { mpTextColor = mpFrameColor = NULL; mnFlags = 0; }
+ ~ImplDateInfo() { delete mpTextColor; delete mpFrameColor; }
+};
+
+DECLARE_TABLE( ImplDateTable, ImplDateInfo* )
+
+// =======================================================================
+
+static void ImplCalendarSelectDate( Table* pTable, const Date& rDate, BOOL bSelect )
+{
+ if ( bSelect )
+ pTable->Insert( rDate.GetDate(), TABLE_DATE_SELECTED );
+ else
+ pTable->Remove( rDate.GetDate() );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalendarSelectDateRange( Table* pTable,
+ const Date& rStartDate,
+ const Date& rEndDate,
+ BOOL bSelect )
+{
+ Date aStartDate = rStartDate;
+ Date aEndDate = rEndDate;
+ if ( aStartDate > aEndDate )
+ {
+ Date aTempDate = aStartDate;
+ aStartDate = aEndDate;
+ aEndDate = aTempDate;
+ }
+
+ if ( bSelect )
+ {
+ while ( aStartDate <= aEndDate )
+ {
+ pTable->Insert( aStartDate.GetDate(), TABLE_DATE_SELECTED );
+ aStartDate++;
+ }
+ }
+ else
+ {
+ void* p = pTable->First();
+ while ( p )
+ {
+ Date aDate( pTable->GetCurKey() );
+ if ( aDate > aEndDate )
+ break;
+
+ if ( aDate >= aStartDate )
+ pTable->Remove( aDate.GetDate() );
+ else
+ p = pTable->Next();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalendarUnSelectDateRange( Table* pTable,
+ Table* pOldTable,
+ const Date& rStartDate,
+ const Date& rEndDate )
+{
+ Date aStartDate = rStartDate;
+ Date aEndDate = rEndDate;
+ if ( aStartDate > aEndDate )
+ {
+ Date aTempDate = aStartDate;
+ aStartDate = aEndDate;
+ aEndDate = aTempDate;
+ }
+
+ void* p = pTable->First();
+ while ( p )
+ {
+ Date aDate( pTable->GetCurKey() );
+ if ( aDate > aEndDate )
+ break;
+
+ if ( aDate >= aStartDate )
+ pTable->Remove( aDate.GetDate() );
+ else
+ p = pTable->Next();
+ }
+
+ p = pOldTable->First();
+ while ( p )
+ {
+ Date aDate( pOldTable->GetCurKey() );
+ if ( aDate > aEndDate )
+ break;
+ if ( aDate >= aStartDate )
+ pTable->Insert( aDate.GetDate(), TABLE_DATE_SELECTED );
+
+ p = pOldTable->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplCalendarClearSelectDate( Table* pTable )
+{
+ pTable->Clear();
+}
+
+// =======================================================================
+
+void Calendar::ImplInit( WinBits nWinStyle )
+{
+ mpDateTable = NULL;
+ mpSelectTable = new Table;
+ mpOldSelectTable = NULL;
+ mpRestoreSelectTable = NULL;
+ mpStandardColor = NULL;
+ mpSaturdayColor = NULL;
+ mpSundayColor = NULL;
+ mnDayCount = 0;
+ mnWinStyle = nWinStyle;
+ mnFirstYear = 0;
+ mnLastYear = 0;
+ mnRequestYear = 0;
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbMultiSelection = FALSE;
+ mbWeekSel = FALSE;
+ mbUnSel = FALSE;
+ mbMenuDown = FALSE;
+ mbSpinDown = FALSE;
+ mbPrevIn = FALSE;
+ mbNextIn = FALSE;
+ mbDirect = FALSE;
+ mbInSelChange = FALSE;
+ mbTravelSelect = FALSE;
+ mbScrollDateRange = FALSE;
+ mbSelLeft = FALSE;
+ mbAllSel = FALSE;
+ mbDropPos = FALSE;
+
+ ::rtl::OUString aGregorian( RTL_CONSTASCII_USTRINGPARAM( "gregorian"));
+ maCalendarWrapper.loadCalendar( aGregorian,
+ Application::GetAppLocaleDataWrapper().getLocale());
+ if (maCalendarWrapper.getUniqueID() != aGregorian)
+ {
+#ifdef DBG_UTIL
+ ByteString aMsg( "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``");
+ lang::Locale aLoc( Application::GetAppLocaleDataWrapper().getLocale());
+ aMsg += ByteString( String( aLoc.Language), RTL_TEXTENCODING_UTF8);
+ aMsg += '-';
+ aMsg += ByteString( String( aLoc.Country), RTL_TEXTENCODING_UTF8);
+ aMsg += "'' and other calendars aren't supported. Using en-US fallback.";
+ DBG_ERRORFILE( aMsg.GetBuffer());
+#endif
+ /* If we ever wanted to support other calendars than Gregorian a lot of
+ * rewrite would be necessary to internally replace use of class Date
+ * with proper class CalendarWrapper methods, get rid of fixed 12
+ * months, fixed 7 days, ... */
+ maCalendarWrapper.loadCalendar( aGregorian, lang::Locale(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en")),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "US")),
+ ::rtl::OUString()));
+ }
+
+ SetFirstDate( maCurDate );
+ ImplCalendarSelectDate( mpSelectTable, maCurDate, TRUE );
+
+ // Sonstige Strings erzeugen
+ maDayText = XubString( SvtResId( STR_SVT_CALENDAR_DAY ) );
+ maWeekText = XubString( SvtResId( STR_SVT_CALENDAR_WEEK ) );
+
+ // Tagestexte anlegen
+ for ( USHORT i = 0; i < 31; i++ )
+ mpDayText[i] = new UniString( UniString::CreateFromInt32( i+1 ) );
+
+ maDragScrollTimer.SetTimeoutHdl( STATIC_LINK( this, Calendar, ScrollHdl ) );
+ maDragScrollTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
+ mnDragScrollHitTest = 0;
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ maSelColor = rStyleSettings.GetHighlightTextColor();
+ SetPointFont( rStyleSettings.GetToolFont() );
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar::Calendar( Window* pParent, WinBits nWinStyle ) :
+ Control( pParent, nWinStyle & (WB_TABSTOP | WB_GROUP | WB_BORDER | WB_3DLOOK | WB_RANGESELECT | WB_MULTISELECT) ),
+ maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ),
+ maOldFormatFirstDate( 0, 0, 1900 ),
+ maOldFormatLastDate( 0, 0, 1900 ),
+ maFirstDate( 0, 0, 1900 ),
+ maOldFirstDate( 0, 0, 1900 ),
+ maOldCurDate( 0, 0, 1900 ),
+ maAnchorDate( maCurDate ),
+ maDropDate( 0, 0, 1900 )
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar::Calendar( Window* pParent, const ResId& rResId ) :
+ Control( pParent, rResId ),
+ maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ),
+ maOldFormatFirstDate( 0, 0, 1900 ),
+ maOldFormatLastDate( 0, 0, 1900 ),
+ maFirstDate( 0, 0, 1900 ),
+ maOldFirstDate( 0, 0, 1900 ),
+ maOldCurDate( 0, 0, 1900 ),
+ maAnchorDate( maCurDate ),
+ maDropDate( 0, 0, 1900 )
+{
+ ImplInit( rResId.GetWinBits() );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar::~Calendar()
+{
+ delete mpStandardColor;
+ delete mpSaturdayColor;
+ delete mpSundayColor;
+
+ if ( mpDateTable )
+ {
+ ImplDateInfo* pDateInfo = mpDateTable->First();
+ while ( pDateInfo )
+ {
+ delete pDateInfo;
+ pDateInfo = mpDateTable->Next();
+ }
+
+ delete mpDateTable;
+ }
+
+ delete mpSelectTable;
+ if ( mpOldSelectTable )
+ delete mpOldSelectTable;
+ if ( mpRestoreSelectTable )
+ delete mpRestoreSelectTable;
+
+ for ( USHORT i = 0; i < 31; i++ )
+ delete mpDayText[i];
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetMinimumNumberOfDaysInWeek( sal_Int16 nDays )
+{
+ ImplUpdate( TRUE );
+ maCalendarWrapper.setMinimumNumberOfDaysForFirstWeek( nDays);
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetWeekStart( sal_Int16 nDay )
+{
+ ImplUpdate( TRUE );
+ switch (nDay)
+ {
+ case i18n::Weekdays::SUNDAY :
+ case i18n::Weekdays::MONDAY :
+ case i18n::Weekdays::TUESDAY :
+ case i18n::Weekdays::WEDNESDAY :
+ case i18n::Weekdays::THURSDAY :
+ case i18n::Weekdays::FRIDAY :
+ case i18n::Weekdays::SATURDAY :
+ ; // nothing
+ default:
+ DBG_ERRORFILE("Calendar::SetWeekStart: unknown value for setFirstDayOfWeek() of a Gregorian calendar");
+ nDay = i18n::Weekdays::SUNDAY;
+ }
+ maCalendarWrapper.setFirstDayOfWeek( nDay);
+}
+
+// -----------------------------------------------------------------------
+
+DayOfWeek Calendar::ImplGetWeekStart() const
+{
+ // Map i18n::Weekdays to Date DayOfWeek
+ DayOfWeek eDay;
+ sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
+ switch (nDay)
+ {
+ case i18n::Weekdays::SUNDAY :
+ eDay = SUNDAY;
+ break;
+ case i18n::Weekdays::MONDAY :
+ eDay = MONDAY;
+ break;
+ case i18n::Weekdays::TUESDAY :
+ eDay = TUESDAY;
+ break;
+ case i18n::Weekdays::WEDNESDAY :
+ eDay = WEDNESDAY;
+ break;
+ case i18n::Weekdays::THURSDAY :
+ eDay = THURSDAY;
+ break;
+ case i18n::Weekdays::FRIDAY :
+ eDay = FRIDAY;
+ break;
+ case i18n::Weekdays::SATURDAY :
+ eDay = SATURDAY;
+ break;
+ default:
+ DBG_ERRORFILE("Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
+ eDay = SUNDAY;
+ }
+ return eDay;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplGetWeekFont( Font& rFont ) const
+{
+ // Wochennummer geben wir in WEEKNUMBER_HEIGHT%-Fonthoehe aus
+ Size aFontSize = rFont.GetSize();
+ aFontSize.Height() *= WEEKNUMBER_HEIGHT;
+ aFontSize.Height() /= 100;
+ rFont.SetSize( aFontSize );
+ rFont.SetWeight( WEIGHT_NORMAL );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplFormat()
+{
+ if ( !mbFormat )
+ return;
+
+ if ( mbCalc )
+ {
+ Size aOutSize = GetOutputSizePixel();
+
+ if ( (aOutSize.Width() <= 1) || (aOutSize.Height() <= 1) )
+ return;
+
+ XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
+
+ Font aOldFont = GetFont();
+
+ // Wochenanzeige beruecksichtigen
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ {
+ Font aTempFont = aOldFont;
+ ImplGetWeekFont( aTempFont );
+ SetFont( aTempFont );
+ mnWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
+ SetFont( aOldFont );
+ }
+ else
+ mnWeekWidth = 0;
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ {
+ Font aFont = aOldFont;
+ if ( aFont.GetWeight() < WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ SetFont( aFont );
+ }
+
+ long n99TextWidth = GetTextWidth( a99Text );
+ long nTextHeight = GetTextHeight();
+
+ // Breiten und X-Positionen berechnen
+ mnDayWidth = n99TextWidth+DAY_OFFX;
+ mnMonthWidth = mnDayWidth*7;
+ mnMonthWidth += mnWeekWidth;
+ mnMonthWidth += MONTH_BORDERX*2;
+ mnMonthPerLine = aOutSize.Width() / mnMonthWidth;
+ if ( !mnMonthPerLine )
+ mnMonthPerLine = 1;
+ long nOver = ((aOutSize.Width()-(mnMonthPerLine*mnMonthWidth)) / mnMonthPerLine);
+ mnMonthWidth += nOver;
+ mnDaysOffX = MONTH_BORDERX;
+ mnDaysOffX += nOver/2;
+ mnDaysOffX += mnWeekWidth;
+
+ // Hoehen und Y-Positionen berechnen
+ mnDayHeight = nTextHeight + DAY_OFFY;
+ mnWeekDayOffY = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
+ mnDaysOffY = mnWeekDayOffY + nTextHeight + WEEKDAY_OFFY;
+ mnMonthHeight = (mnDayHeight*6) + mnDaysOffY;
+ mnMonthHeight += MONTH_OFFY;
+ mnLines = aOutSize.Height() / mnMonthHeight;
+ if ( !mnLines )
+ mnLines = 1;
+ mnMonthHeight += (aOutSize.Height()-(mnLines*mnMonthHeight)) / mnLines;
+
+ // Spinfelder berechnen
+ long nSpinSize = nTextHeight+TITLE_BORDERY-SPIN_OFFY;
+ maPrevRect.Left() = SPIN_OFFX;
+ maPrevRect.Top() = SPIN_OFFY;
+ maPrevRect.Right() = maPrevRect.Left()+nSpinSize;
+ maPrevRect.Bottom() = maPrevRect.Top()+nSpinSize;
+ maNextRect.Left() = aOutSize.Width()-SPIN_OFFX-nSpinSize-1;
+ maNextRect.Top() = SPIN_OFFY;
+ maNextRect.Right() = maNextRect.Left()+nSpinSize;
+ maNextRect.Bottom() = maNextRect.Top()+nSpinSize;
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ SetFont( aOldFont );
+
+ // Calculate DayOfWeekText (gets displayed in a narrow font)
+ maDayOfWeekText.Erase();
+ long nStartOffX = 0;
+ sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
+ for ( sal_Int16 nDayOfWeek = 0; nDayOfWeek < 7; nDayOfWeek++ )
+ {
+ // Use first character of full name, since the abbreviated name may
+ // be roman digits or similar in some locales. Proper
+ // implementation would need narrow one letter month names defined
+ // in locale data.
+ String aDayOfWeek( maCalendarWrapper.getDisplayName(
+ i18n::CalendarDisplayIndex::DAY, nDay, 1).GetChar(0));
+ long nOffX = (mnDayWidth-GetTextWidth( aDayOfWeek ))/2;
+ if ( mnWinStyle & WB_BOLDTEXT )
+ nOffX++;
+ if ( !nDayOfWeek )
+ nStartOffX = nOffX;
+ else
+ nOffX -= nStartOffX;
+ nOffX += nDayOfWeek * mnDayWidth;
+ mnDayOfWeekAry[nDayOfWeek] = nOffX;
+ maDayOfWeekText += aDayOfWeek;
+ nDay++;
+ nDay %= 7;
+ }
+
+ mbCalc = FALSE;
+ }
+
+ // Anzahl Tage berechnen
+
+ DayOfWeek eStartDay = ImplGetWeekStart();
+
+ USHORT nWeekDay;
+ Date aTempDate = GetFirstMonth();
+ maFirstDate = aTempDate;
+ nWeekDay = (USHORT)aTempDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ maFirstDate -= (ULONG)nWeekDay;
+ mnDayCount = nWeekDay;
+ USHORT nDaysInMonth;
+ USHORT nMonthCount = (USHORT)(mnMonthPerLine*mnLines);
+ for ( USHORT i = 0; i < nMonthCount; i++ )
+ {
+ nDaysInMonth = aTempDate.GetDaysInMonth();
+ mnDayCount += nDaysInMonth;
+ aTempDate += nDaysInMonth;
+ }
+ Date aTempDate2 = aTempDate;
+ aTempDate2--;
+ nDaysInMonth = aTempDate2.GetDaysInMonth();
+ aTempDate2 -= nDaysInMonth-1;
+ nWeekDay = (USHORT)aTempDate2.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ mnDayCount += 42-nDaysInMonth-nWeekDay;
+
+ // Farben festlegen
+ maOtherColor = Color( COL_LIGHTGRAY );
+ if ( maOtherColor.IsRGBEqual( GetBackground().GetColor() ) )
+ maOtherColor.SetColor( COL_GRAY );
+
+ Date aLastDate = GetLastDate();
+ if ( (maOldFormatLastDate != aLastDate) ||
+ (maOldFormatFirstDate != maFirstDate) )
+ {
+ maOldFormatFirstDate = maFirstDate;
+ maOldFormatLastDate = aLastDate;
+ DateRangeChanged();
+ }
+
+ // DateInfo besorgen
+ USHORT nNewFirstYear = maFirstDate.GetYear();
+ USHORT nNewLastYear = GetLastDate().GetYear();
+ if ( mnFirstYear )
+ {
+ if ( nNewFirstYear < mnFirstYear )
+ {
+ for ( mnRequestYear = nNewFirstYear; mnRequestYear < mnFirstYear; mnRequestYear++ )
+ RequestDateInfo();
+ mnFirstYear = nNewFirstYear;
+ }
+ if ( nNewLastYear > mnLastYear )
+ {
+ for ( mnRequestYear = mnLastYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
+ RequestDateInfo();
+ mnLastYear = nNewLastYear;
+ }
+ }
+ else
+ {
+ for ( mnRequestYear = nNewFirstYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
+ RequestDateInfo();
+ mnFirstYear = nNewFirstYear;
+ mnLastYear = nNewLastYear;
+ }
+ mnRequestYear = 0;
+
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Calendar::ImplHitTest( const Point& rPos, Date& rDate ) const
+{
+ if ( mbFormat )
+ return 0;
+
+ if ( maPrevRect.IsInside( rPos ) )
+ return CALENDAR_HITTEST_PREV;
+ else if ( maNextRect.IsInside( rPos ) )
+ return CALENDAR_HITTEST_NEXT;
+
+ long nX;
+ long nY;
+ long nOffX;
+ long nYMonth;
+ USHORT nDay;
+ DayOfWeek eStartDay = ImplGetWeekStart();
+
+ rDate = GetFirstMonth();
+ nY = 0;
+ for ( long i = 0; i < mnLines; i++ )
+ {
+ if ( rPos.Y() < nY )
+ return 0;
+
+ nX = 0;
+ nYMonth = nY+mnMonthHeight;
+ for ( long j = 0; j < mnMonthPerLine; j++ )
+ {
+ if ( (rPos.X() < nX) && (rPos.Y() < nYMonth) )
+ return 0;
+
+ USHORT nDaysInMonth = rDate.GetDaysInMonth();
+
+ // Entsprechender Monat gefunden
+ if ( (rPos.X() > nX) && (rPos.Y() < nYMonth) &&
+ (rPos.X() < nX+mnMonthWidth) )
+ {
+ if ( rPos.Y() < (nY+(TITLE_BORDERY*2)+mnDayHeight))
+ return CALENDAR_HITTEST_MONTHTITLE;
+ else
+ {
+ long nDayX = nX+mnDaysOffX;
+ long nDayY = nY+mnDaysOffY;
+ if ( rPos.Y() < nDayY )
+ return 0;
+ USHORT nDayIndex = (USHORT)rDate.GetDayOfWeek();
+ nDayIndex = (nDayIndex+(7-(USHORT)eStartDay)) % 7;
+ if ( (i == 0) && (j == 0) )
+ {
+ Date aTempDate = rDate;
+ aTempDate -= nDayIndex;
+ for ( nDay = 0; nDay < nDayIndex; nDay++ )
+ {
+ nOffX = nDayX + (nDay*mnDayWidth);
+ if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
+ (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
+ {
+ rDate = aTempDate;
+ rDate += nDay;
+ return CALENDAR_HITTEST_DAY;
+ }
+ }
+ }
+ for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
+ {
+ if ( rPos.Y() < nDayY )
+ {
+ rDate += nDayIndex;
+ return 0;
+ }
+ nOffX = nDayX + (nDayIndex*mnDayWidth);
+ if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
+ (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
+ {
+ rDate += nDay-1;
+ return CALENDAR_HITTEST_DAY;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
+ {
+ USHORT nWeekDay = (USHORT)rDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ USHORT nDayCount = 42-nDaysInMonth-nWeekDay;
+ Date aTempDate = rDate;
+ aTempDate += nDaysInMonth;
+ for ( nDay = 1; nDay <= nDayCount; nDay++ )
+ {
+ if ( rPos.Y() < nDayY )
+ {
+ rDate += nDayIndex;
+ return 0;
+ }
+ nOffX = nDayX + (nDayIndex*mnDayWidth);
+ if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
+ (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
+ {
+ rDate = aTempDate;
+ rDate += nDay-1;
+ return CALENDAR_HITTEST_DAY;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ }
+ }
+ }
+
+ rDate += nDaysInMonth;
+ nX += mnMonthWidth;
+ }
+
+ nY += mnMonthHeight;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawSpinArrow( OutputDevice* pDev, const Rectangle& rRect,
+ BOOL bPrev )
+{
+ long i;
+ long n;
+ long nLines;
+ long nHeight = rRect.GetHeight();
+ long nWidth = rRect.GetWidth();
+ if ( nWidth < nHeight )
+ n = nWidth;
+ else
+ n = nHeight;
+ if ( !(n & 0x01) )
+ n--;
+ nLines = n/2;
+
+ Rectangle aRect( Point( rRect.Left()+(nWidth/2)-(nLines/2),
+ rRect.Top()+(nHeight/2) ),
+ Size( 1, 1 ) );
+ if ( !bPrev )
+ {
+ aRect.Left() += nLines;
+ aRect.Right() += nLines;
+ }
+
+ pDev->DrawRect( aRect );
+ for ( i = 0; i < nLines; i++ )
+ {
+ if ( bPrev )
+ {
+ aRect.Left()++;
+ aRect.Right()++;
+ }
+ else
+ {
+ aRect.Left()--;
+ aRect.Right()--;
+ }
+ aRect.Top()--;
+ aRect.Bottom()++;
+ pDev->DrawRect( aRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplDrawSpin( BOOL bDrawPrev, BOOL bDrawNext )
+{
+ if ( !bDrawPrev && !bDrawNext )
+ return;
+
+ SetLineColor();
+ SetFillColor( GetSettings().GetStyleSettings().GetButtonTextColor() );
+ if ( bDrawPrev )
+ {
+ Rectangle aOutRect = maPrevRect;
+ aOutRect.Left() += 3;
+ aOutRect.Top() += 3;
+ aOutRect.Right() -= 3;
+ aOutRect.Bottom() -= 3;
+ ImplDrawSpinArrow( this, aOutRect, TRUE );
+ }
+ if ( bDrawNext )
+ {
+ Rectangle aOutRect = maNextRect;
+ aOutRect.Left() += 3;
+ aOutRect.Top() += 3;
+ aOutRect.Right() -= 3;
+ aOutRect.Bottom() -= 3;
+ ImplDrawSpinArrow( this, aOutRect, FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplDrawDate( long nX, long nY,
+ USHORT nDay, USHORT nMonth, USHORT nYear,
+ DayOfWeek eDayOfWeek,
+ BOOL bBack, BOOL bOther, ULONG nToday )
+{
+ ImplDateInfo* pDateInfo;
+ Color* pTextColor = NULL;
+ const String& rDay = *(mpDayText[nDay-1]);
+ Rectangle aDateRect( nX, nY, nX+mnDayWidth-1, nY+mnDayHeight-1 );
+
+ BOOL bSel = FALSE;
+ BOOL bFocus = FALSE;
+ // Aktueller Tag
+ if ( (nDay == maCurDate.GetDay()) &&
+ (nMonth == maCurDate.GetMonth()) &&
+ (nYear == maCurDate.GetYear()) )
+ bFocus = TRUE;
+ if ( mpSelectTable )
+ {
+ if ( mpSelectTable->IsKeyValid( Date( nDay, nMonth, nYear ).GetDate() ) )
+ bSel = TRUE;
+ }
+
+ // Dateinfo ermitteln
+ if ( mpDateTable )
+ {
+ pDateInfo = mpDateTable->Get( Date( nDay, nMonth, nYear ).GetDate() );
+ if ( !pDateInfo )
+ pDateInfo = mpDateTable->Get( Date( nDay, nMonth, 0 ).GetDate() );
+ }
+ else
+ pDateInfo = NULL;
+
+ // Textfarbe ermitteln
+ if ( bSel )
+ pTextColor = &maSelColor;
+ else if ( bOther )
+ pTextColor = &maOtherColor;
+ else
+ {
+ if ( pDateInfo && pDateInfo->mpTextColor )
+ pTextColor = pDateInfo->mpTextColor;
+ else
+ {
+ if ( eDayOfWeek == SATURDAY )
+ pTextColor = mpSaturdayColor;
+ else if ( eDayOfWeek == SUNDAY )
+ pTextColor = mpSundayColor;
+ if ( !pTextColor )
+ pTextColor = mpStandardColor;
+ }
+ }
+
+ if ( bFocus )
+ HideFocus();
+
+ // Font ermitteln
+ Font aOldFont = GetFont();
+ BOOL bBoldFont = FALSE;
+ if ( (mnWinStyle & WB_BOLDTEXT) &&
+ pDateInfo && (pDateInfo->mnFlags & DIB_BOLD) )
+ {
+ bBoldFont = TRUE;
+ Font aFont = aOldFont;
+ if ( aFont.GetWeight() < WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ SetFont( aFont );
+ }
+
+ // Hintergrund ausgeben
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( bSel || bBack )
+ {
+ if ( bSel )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( aDateRect );
+ }
+ else
+ Erase( aDateRect );
+ }
+
+ // Text ausgeben
+ long nTextX = nX+(mnDayWidth-GetTextWidth( rDay ))-(DAY_OFFX/2);
+ long nTextY = nY+(mnDayHeight-GetTextHeight())/2;
+ if ( pTextColor )
+ {
+ Color aOldColor = GetTextColor();
+ SetTextColor( *pTextColor );
+ DrawText( Point( nTextX, nTextY ), rDay );
+ SetTextColor( aOldColor );
+ }
+ else
+ DrawText( Point( nTextX, nTextY ), rDay );
+
+ // Heute
+ Date aTodayDate( maCurDate );
+ if ( nToday )
+ aTodayDate.SetDate( nToday );
+ else
+ aTodayDate = Date();
+ if ( (nDay == aTodayDate.GetDay()) &&
+ (nMonth == aTodayDate.GetMonth()) &&
+ (nYear == aTodayDate.GetYear()) )
+ {
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ SetFillColor();
+ DrawRect( aDateRect );
+ }
+
+ // Evt. DateInfo ausgeben
+ if ( (mnWinStyle & WB_FRAMEINFO) && pDateInfo && pDateInfo->mpFrameColor )
+ {
+ SetLineColor( *(pDateInfo->mpFrameColor) );
+ SetFillColor();
+ Rectangle aFrameRect( aDateRect );
+ aFrameRect.Left()++;
+ aFrameRect.Top()++;
+ long nFrameWidth = aFrameRect.GetWidth();
+ long nFrameHeight = aFrameRect.GetHeight();
+ long nFrameOff;
+ if ( nFrameWidth < nFrameHeight )
+ {
+ nFrameOff = nFrameHeight-nFrameWidth;
+ aFrameRect.Top() += nFrameOff/2;
+ nFrameOff %= 2;
+ aFrameRect.Bottom() -= nFrameOff;
+ }
+ else if ( nFrameWidth > nFrameHeight )
+ {
+ nFrameOff = nFrameWidth-nFrameHeight;
+ aFrameRect.Left() += nFrameOff/2;
+ nFrameOff %= 2;
+ aFrameRect.Right() -= nFrameOff;
+ }
+ DrawEllipse( aFrameRect );
+ }
+
+ // Evt. noch FocusRect
+ if ( bFocus && HasFocus() )
+ ShowFocus( aDateRect );
+
+ if( mbDropPos && maDropDate == Date( nDay, nMonth, nYear ) )
+ ImplInvertDropPos();
+
+ if ( bBoldFont )
+ SetFont( aOldFont );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplDraw( BOOL bPaint )
+{
+ ImplFormat();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Size aOutSize = GetOutputSizePixel();
+ long i;
+ long j;
+ long nX;
+ long nY;
+ long nDeltaX;
+ long nDeltaY;
+ long nDayX;
+ long nDayY;
+ ULONG nToday = Date().GetDate();
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ Date aDate = GetFirstMonth();
+ DayOfWeek eStartDay = ImplGetWeekStart();
+
+ HideFocus();
+
+ nY = 0;
+ for ( i = 0; i < mnLines; i++ )
+ {
+ // Titleleiste ausgeben
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ Rectangle aTitleRect( 0, nY, aOutSize.Width()-1, nY+mnDayHeight-DAY_OFFY+TITLE_BORDERY*2 );
+ if ( !bPaint )
+ {
+ Rectangle aTempRect( 1, aTitleRect.Top()+TITLE_BORDERY,
+ aOutSize.Width()-2,
+ aTitleRect.Bottom()-TITLE_BORDERY );
+ if ( !i )
+ {
+ aTempRect.Left() = maPrevRect.Right()+1;
+ aTempRect.Right() = maNextRect.Left()-1;
+ }
+ DrawRect( aTempRect );
+ }
+ else
+ {
+ DrawRect( aTitleRect );
+ Point aTopLeft1( aTitleRect.Left(), aTitleRect.Top() );
+ Point aTopLeft2( aTitleRect.Left(), aTitleRect.Top()+1 );
+ Point aBottomRight1( aTitleRect.Right(), aTitleRect.Bottom() );
+ Point aBottomRight2( aTitleRect.Right(), aTitleRect.Bottom()-1 );
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( aTopLeft1, Point( aBottomRight1.X(), aTopLeft1.Y() ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( aTopLeft2, Point( aBottomRight2.X(), aTopLeft2.Y() ) );
+ DrawLine( aTopLeft2, Point( aTopLeft2.X(), aBottomRight2.Y() ) );
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( aTopLeft2.X(), aBottomRight2.Y() ), aBottomRight2 );
+ DrawLine( Point( aBottomRight2.X(), aTopLeft2.Y() ), aBottomRight2 );
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( aTopLeft1.X(), aBottomRight1.Y() ), aBottomRight1 );
+ }
+ Point aSepPos1( 0, aTitleRect.Top()+TITLE_BORDERY );
+ Point aSepPos2( 0, aTitleRect.Bottom()-TITLE_BORDERY );
+ for ( j = 0; j < mnMonthPerLine-1; j++ )
+ {
+ aSepPos1.X() += mnMonthWidth-1;
+ aSepPos2.X() = aSepPos1.X();
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( aSepPos1, aSepPos2 );
+ aSepPos1.X()++;
+ aSepPos2.X() = aSepPos1.X();
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( aSepPos1, aSepPos2 );
+ }
+
+ nX = 0;
+ for ( j = 0; j < mnMonthPerLine; j++ )
+ {
+ nMonth = aDate.GetMonth();
+ nYear = aDate.GetYear();
+
+ // Monat in der Titleleiste ausgeben
+ nDeltaX = nX;
+ nDeltaY = nY+TITLE_BORDERY;
+ String aMonthText( maCalendarWrapper.getDisplayName(
+ i18n::CalendarDisplayIndex::MONTH, nMonth-1, 1));
+ aMonthText += ' ';
+ aMonthText += String::CreateFromInt64( nYear );
+ long nMonthTextWidth = GetTextWidth( aMonthText );
+ long nMonthOffX1 = 0;
+ long nMonthOffX2 = 0;
+ if ( i == 0 )
+ {
+ if ( j == 0 )
+ nMonthOffX1 = maPrevRect.Right()+1;
+ if ( j == mnMonthPerLine-1 )
+ nMonthOffX2 = aOutSize.Width()-maNextRect.Left()+1;
+ }
+ long nMaxMonthWidth = mnMonthWidth-nMonthOffX1-nMonthOffX2-4;
+ if ( nMonthTextWidth > nMaxMonthWidth )
+ {
+ // Abbreviated month name.
+ aMonthText = maCalendarWrapper.getDisplayName(
+ i18n::CalendarDisplayIndex::MONTH, nMonth-1, 0);
+ aMonthText += ' ';
+ aMonthText += String::CreateFromInt64( nYear );
+ nMonthTextWidth = GetTextWidth( aMonthText );
+ }
+ long nTempOff = (mnMonthWidth-nMonthTextWidth+1)/2;
+ if ( nTempOff < nMonthOffX1 )
+ nDeltaX += nMonthOffX1+1;
+ else
+ {
+ if ( nTempOff+nMonthTextWidth > mnMonthWidth-nMonthOffX2 )
+ nDeltaX += mnMonthWidth-nMonthOffX2-nMonthTextWidth;
+ else
+ nDeltaX += nTempOff;
+ }
+ SetTextColor( rStyleSettings.GetButtonTextColor() );
+ DrawText( Point( nDeltaX, nDeltaY ), aMonthText );
+ SetTextColor( rStyleSettings.GetWindowTextColor() );
+
+ // Weekleiste ausgeben
+ if ( bPaint )
+ {
+ nDayX = nX+mnDaysOffX;
+ nDayY = nY+mnWeekDayOffY;
+ nDeltaY = nDayY + mnDayHeight;
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ Point aStartPos( nDayX, nDeltaY );
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ aStartPos.X() -= WEEKNUMBER_OFFX-2;
+ DrawLine( aStartPos, Point( nDayX+(7*mnDayWidth), nDeltaY ) );
+ DrawTextArray( Point( nDayX+mnDayOfWeekAry[0], nDayY ), maDayOfWeekText, &(mnDayOfWeekAry[1]) );
+ }
+
+ // Week-Numbers ausgeben
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ {
+ nDayX = nX+mnDaysOffX;
+ nDayY = nY+mnWeekDayOffY;
+ nDeltaY = nDayY + mnDayHeight;
+ long nMonthHeight = mnDayHeight*6;
+ if ( bPaint )
+ DrawLine( Point( nDayX-WEEKNUMBER_OFFX+2, nDeltaY ), Point( nDayX-WEEKNUMBER_OFFX+2, nDeltaY+nMonthHeight ) );
+ else
+ Erase( Rectangle( nDayX-mnWeekWidth-WEEKNUMBER_OFFX, nDeltaY, nDayX-WEEKNUMBER_OFFX-1, nDeltaY+nMonthHeight ) );
+
+ Font aOldFont = GetFont();
+ Font aTempFont = aOldFont;
+ ImplGetWeekFont( aTempFont );
+ SetFont( aTempFont );
+ nDayX -= mnWeekWidth;
+ nDayY = nY+mnDaysOffY;
+ maCalendarWrapper.setGregorianDateTime( aDate);
+ for ( USHORT nWeekCount = 0; nWeekCount < 6; nWeekCount++ )
+ {
+ sal_Int16 nWeek = maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR);
+ String aWeekText( String::CreateFromInt32( nWeek));
+ long nOffX = (mnWeekWidth-WEEKNUMBER_OFFX)-GetTextWidth( aWeekText );
+ long nOffY = (mnDayHeight-GetTextHeight())/2;
+ DrawText( Point( nDayX+nOffX, nDayY+nOffY ), aWeekText );
+ nDayY += mnDayHeight;
+ maCalendarWrapper.addValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, 7);
+ }
+ SetFont( aOldFont );
+ }
+
+ // Tage ausgeben
+ USHORT nDaysInMonth = aDate.GetDaysInMonth();
+ nDayX = nX+mnDaysOffX;
+ nDayY = nY+mnDaysOffY;
+ if ( !bPaint )
+ {
+ Rectangle aClearRect( nDayX, nDayY,
+ nDayX+(7*mnDayWidth)-1, nDayY+(6*mnDayHeight)-1 );
+ Erase( aClearRect );
+ }
+ USHORT nDayIndex = (USHORT)aDate.GetDayOfWeek();
+ nDayIndex = (nDayIndex+(7-(USHORT)eStartDay)) % 7;
+ if ( (i == 0) && (j == 0) )
+ {
+ Date aTempDate = aDate;
+ aTempDate -= nDayIndex;
+ for ( nDay = 0; nDay < nDayIndex; nDay++ )
+ {
+ nDeltaX = nDayX + (nDay*mnDayWidth);
+ ImplDrawDate( nDeltaX, nDayY, nDay+aTempDate.GetDay(),
+ aTempDate.GetMonth(), aTempDate.GetYear(),
+ (DayOfWeek)((nDay+(USHORT)eStartDay)%7), FALSE, TRUE, nToday );
+ }
+ }
+ for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
+ {
+ nDeltaX = nDayX + (nDayIndex*mnDayWidth);
+ ImplDrawDate( nDeltaX, nDayY, nDay, nMonth, nYear,
+ (DayOfWeek)((nDayIndex+(USHORT)eStartDay)%7),
+ FALSE, FALSE, nToday );
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
+ {
+ USHORT nWeekDay = (USHORT)aDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ USHORT nDayCount = 42-nDaysInMonth-nWeekDay;
+ Date aTempDate = aDate;
+ aTempDate += nDaysInMonth;
+ for ( nDay = 1; nDay <= nDayCount; nDay++ )
+ {
+ nDeltaX = nDayX + (nDayIndex*mnDayWidth);
+ ImplDrawDate( nDeltaX, nDayY, nDay,
+ aTempDate.GetMonth(), aTempDate.GetYear(),
+ (DayOfWeek)((nDayIndex+(USHORT)eStartDay)%7),
+ FALSE, TRUE, nToday );
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ }
+
+ aDate += nDaysInMonth;
+ nX += mnMonthWidth;
+ }
+
+ nY += mnMonthHeight;
+ }
+
+ // Spin-Buttons zeichnen
+ if ( bPaint )
+ ImplDrawSpin();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplUpdateDate( const Date& rDate )
+{
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ Rectangle aDateRect( GetDateRect( rDate ) );
+ if ( !aDateRect.IsEmpty() )
+ {
+ BOOL bOther = (rDate < GetFirstMonth()) || (rDate > GetLastMonth());
+ ImplDrawDate( aDateRect.Left(), aDateRect.Top(),
+ rDate.GetDay(), rDate.GetMonth(), rDate.GetYear(),
+ rDate.GetDayOfWeek(), TRUE, bOther );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplUpdateSelection( Table* pOld )
+{
+ Table* pNew = mpSelectTable;
+ void* p;
+ ULONG nKey;
+
+ p = pOld->First();
+ while ( p )
+ {
+ nKey = pOld->GetCurKey();
+ if ( !pNew->Get( nKey ) )
+ {
+ Date aTempDate( nKey );
+ ImplUpdateDate( aTempDate );
+ }
+
+ p = pOld->Next();
+ }
+
+ p = pNew->First();
+ while ( p )
+ {
+ nKey = pNew->GetCurKey();
+ if ( !pOld->Get( nKey ) )
+ {
+ Date aTempDate( nKey );
+ ImplUpdateDate( aTempDate );
+ }
+
+ p = pNew->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplMouseSelect( const Date& rDate, USHORT nHitTest,
+ BOOL bMove, BOOL bExpand, BOOL bExtended )
+{
+ Table* pOldSel = new Table( *mpSelectTable );
+ Date aOldDate = maCurDate;
+ Date aTempDate = rDate;
+
+ if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
+ aTempDate--;
+
+ if ( mbMultiSelection )
+ {
+ maCurDate = aTempDate;
+ mbSelLeft = aTempDate < maAnchorDate;
+
+ if ( bMove )
+ {
+ if ( mbSelLeft )
+ {
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), aTempDate );
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, maAnchorDate, Date( 31, 12, 9999 ) );
+ }
+ else
+ {
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), maAnchorDate );
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, aTempDate, Date( 31, 12, 9999 ) );
+ }
+ ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, !mbUnSel );
+ }
+ else
+ {
+ if ( bExpand )
+ {
+ if ( !bExtended )
+ {
+ if ( mbSelLeft )
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aTempDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ else
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, aTempDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ }
+ ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, TRUE );
+ }
+ else if ( bExtended && !(mnWinStyle & WB_RANGESELECT) )
+ {
+ maAnchorDate = aTempDate;
+ if ( IsDateSelected( aTempDate ) )
+ {
+ mbUnSel = TRUE;
+ ImplCalendarSelectDate( mpSelectTable, aTempDate, FALSE );
+ }
+ else
+ {
+ ImplCalendarSelectDate( mpSelectTable, aTempDate, TRUE );
+ }
+ }
+ else
+ {
+ maAnchorDate = aTempDate;
+ ImplCalendarClearSelectDate( mpSelectTable );
+ ImplCalendarSelectDate( mpSelectTable, aTempDate, TRUE );
+ }
+
+ mpRestoreSelectTable = new Table( *mpSelectTable );
+ }
+ }
+ else
+ {
+ if ( aTempDate < maCurDate )
+ mbSelLeft = TRUE;
+ else
+ mbSelLeft = FALSE;
+ if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
+ aTempDate = maOldCurDate;
+ if ( !bMove )
+ maAnchorDate = aTempDate;
+ if ( aTempDate != maCurDate )
+ {
+ maCurDate = aTempDate;
+ ImplCalendarSelectDate( mpSelectTable, aOldDate, FALSE );
+ ImplCalendarSelectDate( mpSelectTable, maCurDate, TRUE );
+ }
+ }
+
+ BOOL bNewSel = *pOldSel != *mpSelectTable;
+ if ( (maCurDate != aOldDate) || bNewSel )
+ {
+ if ( bNewSel )
+ {
+ mbInSelChange = TRUE;
+ SelectionChanging();
+ mbInSelChange = FALSE;
+ }
+ HideFocus();
+ if ( bNewSel )
+ ImplUpdateSelection( pOldSel );
+ if ( !bNewSel || !pOldSel->Get( aOldDate.GetDate() ) )
+ ImplUpdateDate( aOldDate );
+ // Damit Focus-Rechteck auch wieder neu ausgegeben wird
+ if ( HasFocus() || !bNewSel || !mpSelectTable->Get( maCurDate.GetDate() ) )
+ ImplUpdateDate( maCurDate );
+ }
+ delete pOldSel;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplUpdate( BOOL bCalcNew )
+{
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( bCalcNew && !mbCalc )
+ Invalidate();
+ else if ( !mbFormat && !mbCalc )
+ {
+ if ( mbDirect )
+ {
+ mbFormat = TRUE;
+ ImplDraw( FALSE );
+ return;
+ }
+ else
+ Invalidate();
+ }
+ }
+
+ if ( bCalcNew )
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplInvertDropPos()
+{
+ Rectangle aRect = GetDateRect( maDropDate );//this is one Pixel to width and one to heigh
+ aRect.Bottom() = aRect.Top()+mnDayHeight-1;
+ aRect.Right() = aRect.Left()+mnDayWidth-1;
+ Invert( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplScroll( BOOL bPrev )
+{
+ Date aNewFirstMonth = GetFirstMonth();
+ if ( bPrev )
+ {
+ aNewFirstMonth--;
+ aNewFirstMonth -= aNewFirstMonth.GetDaysInMonth()-1;
+ }
+ else
+ aNewFirstMonth += aNewFirstMonth.GetDaysInMonth();
+ mbDirect = TRUE;
+ SetFirstDate( aNewFirstMonth );
+ mbDirect = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate )
+{
+ EndSelection();
+
+ Date aOldFirstDate = GetFirstMonth();
+ PopupMenu aPopupMenu;
+ PopupMenu* pYearPopupMenus[MENU_YEAR_COUNT];
+ USHORT nMonthOff;
+ USHORT nCurItemId;
+ USHORT nYear = rDate.GetYear()-1;
+ USHORT i;
+ USHORT j;
+ USHORT nYearIdCount = 1000;
+
+ nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12;
+ if ( aOldFirstDate.GetMonth() < rDate.GetMonth() )
+ nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth();
+ else
+ nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth();
+
+ // Menu aufbauen (Jahre mit verschiedenen Monaten aufnehmen)
+ for ( i = 0; i < MENU_YEAR_COUNT; i++ )
+ {
+ pYearPopupMenus[i] = new PopupMenu;
+ for ( j = 1; j <= 12; j++ )
+ pYearPopupMenus[i]->InsertItem( nYearIdCount+j,
+ maCalendarWrapper.getDisplayName(
+ i18n::CalendarDisplayIndex::MONTH, j-1, 1));
+ aPopupMenu.InsertItem( 10+i, UniString::CreateFromInt32( nYear+i ) );
+ aPopupMenu.SetPopupMenu( 10+i, pYearPopupMenus[i] );
+ nYearIdCount += 1000;
+ }
+
+ mbMenuDown = TRUE;
+ nCurItemId = aPopupMenu.Execute( this, rPos );
+ mbMenuDown = FALSE;
+
+ // Menu zerstoeren
+ aPopupMenu.SetPopupMenu( 2, NULL );
+ for ( i = 0; i < MENU_YEAR_COUNT; i++ )
+ {
+ aPopupMenu.SetPopupMenu( 10+i, NULL );
+ delete pYearPopupMenus[i];
+ }
+
+ if ( nCurItemId )
+ {
+ USHORT nTempMonthOff = nMonthOff % 12;
+ USHORT nTempYearOff = nMonthOff / 12;
+ USHORT nNewMonth = nCurItemId % 1000;
+ USHORT nNewYear = nYear+((nCurItemId-1000)/1000);
+ if ( nTempMonthOff < nNewMonth )
+ nNewMonth = nNewMonth - nTempMonthOff;
+ else
+ {
+ nNewYear--;
+ nNewMonth = 12-(nTempMonthOff-nNewMonth);
+ }
+ nNewYear = nNewYear - nTempYearOff;
+ SetFirstDate( Date( 1, nNewMonth, nNewYear ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplTracking( const Point& rPos, BOOL bRepeat )
+{
+ Date aTempDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rPos, aTempDate );
+
+ if ( mbSpinDown )
+ {
+ mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
+ mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
+
+ if ( bRepeat && (mbPrevIn || mbNextIn) )
+ {
+ mbScrollDateRange = TRUE;
+ ImplScroll( mbPrevIn );
+ mbScrollDateRange = FALSE;
+ }
+ }
+ else
+ ImplMouseSelect( aTempDate, nHitTest, TRUE, FALSE, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplEndTracking( BOOL bCancel )
+{
+ BOOL bSelection = mbSelection;
+ BOOL bSpinDown = mbSpinDown;
+
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbMultiSelection = FALSE;
+ mbUnSel = FALSE;
+ mbSpinDown = FALSE;
+ mbPrevIn = FALSE;
+ mbNextIn = FALSE;
+
+ if ( bCancel )
+ {
+ if ( maOldFirstDate != maFirstDate )
+ SetFirstDate( maOldFirstDate );
+
+ if ( !bSpinDown )
+ {
+ Table* pOldSel = new Table( *mpSelectTable );
+ Date aOldDate = maCurDate;
+ maCurDate = maOldCurDate;
+ *mpSelectTable = *mpOldSelectTable;
+ HideFocus();
+ ImplUpdateSelection( pOldSel );
+ if ( !pOldSel->Get( aOldDate.GetDate() ) )
+ ImplUpdateDate( aOldDate );
+ // Damit Focus-Rechteck auch wieder neu ausgegeben wird
+ if ( HasFocus() || !mpSelectTable->Get( maCurDate.GetDate() ) )
+ ImplUpdateDate( maCurDate );
+ delete pOldSel;
+ }
+ }
+
+ if ( !bSpinDown )
+ {
+ if ( !bCancel )
+ {
+ // Feststellen, ob wir sichtbaren Bereich scrollen sollen
+ ULONG nSelCount = mpSelectTable->Count();
+ if ( nSelCount )
+ {
+ Date aFirstSelDate( mpSelectTable->GetObjectKey( 0 ) );
+ Date aLastSelDate( mpSelectTable->GetObjectKey( nSelCount-1 ) );
+ if ( aLastSelDate < GetFirstMonth() )
+ ImplScroll( TRUE );
+ else if ( GetLastMonth() < aFirstSelDate )
+ ImplScroll( FALSE );
+ }
+ }
+
+ if ( mbAllSel ||
+ (!bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable))) )
+ Select();
+
+ if ( !bSelection && (mnWinStyle & WB_TABSTOP) && !bCancel )
+ GrabFocus();
+
+ delete mpOldSelectTable;
+ mpOldSelectTable = NULL;
+ delete mpRestoreSelectTable;
+ mpRestoreSelectTable = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_STATIC_LINK( Calendar, ScrollHdl, Timer*, EMPTYARG )
+{
+ BOOL bPrevIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_PREV) != 0;
+ BOOL bNextIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_NEXT) != 0;
+ if( bNextIn || bPrevIn )
+ {
+ pThis->mbScrollDateRange = TRUE;
+ pThis->ImplScroll( bPrevIn );
+ pThis->mbScrollDateRange = FALSE;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && !mbMenuDown )
+ {
+ Date aTempDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rMEvt.GetPosPixel(), aTempDate );
+ if ( nHitTest )
+ {
+ if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
+ ImplShowMenu( rMEvt.GetPosPixel(), aTempDate );
+ else
+ {
+ maOldFirstDate = maFirstDate;
+
+ mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
+ mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
+ if ( mbPrevIn || mbNextIn )
+ {
+ mbSpinDown = TRUE;
+ mbScrollDateRange = TRUE;
+ ImplScroll( mbPrevIn );
+ mbScrollDateRange = FALSE;
+ // Hier muss BUTTONREPEAT stehen, also nicht wieder
+ // auf SCROLLREPEAT aendern, sondern mit TH abklaeren,
+ // warum es evtl. anders sein sollte (71775)
+ StartTracking( STARTTRACK_BUTTONREPEAT );
+ }
+ else
+ {
+ if ( (rMEvt.GetClicks() == 2) && (nHitTest & CALENDAR_HITTEST_DAY) )
+ DoubleClick();
+ else
+ {
+ if ( mpOldSelectTable )
+ delete mpOldSelectTable;
+ maOldCurDate = maCurDate;
+ mpOldSelectTable = new Table( *mpSelectTable );
+
+ if ( !mbSelection )
+ {
+ mbDrag = TRUE;
+ StartTracking();
+ }
+
+ mbMultiSelection = (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT)) != 0;
+ if ( (nHitTest & CALENDAR_HITTEST_DAY) && mbMultiSelection )
+ mbWeekSel = TRUE;
+ else
+ mbWeekSel = FALSE;
+ ImplMouseSelect( aTempDate, nHitTest, FALSE, rMEvt.IsShift(), rMEvt.IsMod1() );
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ Control::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && mbSelection )
+ ImplEndTracking( FALSE );
+ else
+ Control::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( mbSelection && rMEvt.GetButtons() )
+ ImplTracking( rMEvt.GetPosPixel(), FALSE );
+ else
+ Control::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( rTEvt.IsTrackingEnded() )
+ ImplEndTracking( rTEvt.IsTrackingCanceled() );
+ else
+ ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::KeyInput( const KeyEvent& rKEvt )
+{
+ Date aNewDate = maCurDate;
+ BOOL bMultiSel = (mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) != 0;
+ BOOL bExpand = rKEvt.GetKeyCode().IsShift();
+ BOOL bExtended = rKEvt.GetKeyCode().IsMod1();
+
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_HOME:
+ aNewDate.SetDay( 1 );
+ break;
+
+ case KEY_END:
+ aNewDate.SetDay( aNewDate.GetDaysInMonth() );
+ break;
+
+ case KEY_LEFT:
+ aNewDate--;
+ break;
+
+ case KEY_RIGHT:
+ aNewDate++;
+ break;
+
+ case KEY_UP:
+ aNewDate -= 7;
+ break;
+
+ case KEY_DOWN:
+ aNewDate += 7;
+ break;
+
+ case KEY_PAGEUP:
+ {
+ Date aTempDate = aNewDate;
+ aTempDate -= aNewDate.GetDay()+1;
+ aNewDate -= aTempDate.GetDaysInMonth();
+ }
+ break;
+
+ case KEY_PAGEDOWN:
+ aNewDate += aNewDate.GetDaysInMonth();
+ break;
+
+ case KEY_SPACE:
+ if ( bMultiSel && !(mnWinStyle & WB_RANGESELECT) )
+ {
+ if ( !bExpand )
+ {
+ BOOL bDateSel = IsDateSelected( maCurDate );
+ SelectDate( maCurDate, !bDateSel );
+ mbSelLeft = FALSE;
+ SelectionChanging();
+ mbTravelSelect = TRUE;
+ Select();
+ mbTravelSelect = FALSE;
+ }
+ }
+ else
+ Control::KeyInput( rKEvt );
+ break;
+
+ default:
+ Control::KeyInput( rKEvt );
+ break;
+ }
+
+ if ( aNewDate != maCurDate )
+ {
+ if ( bMultiSel && bExpand )
+ {
+ Table* pOldSel = new Table( *mpSelectTable );
+ Date aOldAnchorDate = maAnchorDate;
+ mbSelLeft = aNewDate < maAnchorDate;
+ if ( !bExtended )
+ {
+ if ( mbSelLeft )
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aNewDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ else
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, aNewDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ }
+ ImplCalendarSelectDateRange( mpSelectTable, aNewDate, maAnchorDate, TRUE );
+ mbDirect = TRUE;
+ SetCurDate( aNewDate );
+ mbDirect = FALSE;
+ maAnchorDate = aOldAnchorDate;
+ mbInSelChange = TRUE;
+ SelectionChanging();
+ mbInSelChange = FALSE;
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+ else
+ {
+ if ( mnWinStyle & WB_RANGESELECT )
+ {
+ SetNoSelection();
+ SelectDate( aNewDate, TRUE );
+ }
+ mbDirect = TRUE;
+ SetCurDate( aNewDate );
+ mbDirect = FALSE;
+ }
+ mbTravelSelect = TRUE;
+ Select();
+ mbTravelSelect = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Paint( const Rectangle& )
+{
+ ImplDraw( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::GetFocus()
+{
+ ImplUpdateDate( maCurDate );
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::LoseFocus()
+{
+ HideFocus();
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Resize()
+{
+ ImplUpdate( TRUE );
+ Control::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ Date aDate = maCurDate;
+ if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) )
+ {
+ Rectangle aDateRect = GetDateRect( aDate );
+ Point aPt = OutputToScreenPixel( aDateRect.TopLeft() );
+ aDateRect.Left() = aPt.X();
+ aDateRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aDateRect.BottomRight() );
+ aDateRect.Right() = aPt.X();
+ aDateRect.Bottom() = aPt.Y();
+
+ if ( (rHEvt.GetMode() & HELPMODE_BALLOON) || (mnWinStyle & WB_QUICKHELPSHOWSDATEINFO) )
+ {
+ ImplDateInfo* pInfo;
+ if ( mpDateTable )
+ {
+ pInfo = mpDateTable->Get( aDate.GetDate() );
+ if ( !pInfo )
+ pInfo = mpDateTable->Get( Date( aDate.GetDay(), aDate.GetMonth(), 0 ).GetDate() );
+ }
+ else
+ pInfo = NULL;
+ if ( pInfo )
+ {
+ XubString aStr = pInfo->maText;
+ if ( aStr.Len() )
+ {
+ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aDateRect, aStr );
+ return;
+ }
+ }
+ }
+
+ if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ {
+ maCalendarWrapper.setGregorianDateTime( aDate);
+ USHORT nWeek = (USHORT) maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR);
+ USHORT nMonth = aDate.GetMonth();
+ XubString aStr( maDayText );
+ aStr.AppendAscii( ": " );
+ aStr.Append( XubString::CreateFromInt32( aDate.GetDayOfYear() ) );
+ aStr.AppendAscii( " / " );
+ aStr.Append( maWeekText );
+ aStr.AppendAscii( ": " );
+ aStr.Append( XubString::CreateFromInt32( nWeek ) );
+ // Evt. noch Jahr hinzufuegen, wenn es nicht das gleiche ist
+ if ( (nMonth == 12) && (nWeek == 1) )
+ {
+ aStr.AppendAscii( ", " );
+ aStr.Append( XubString::CreateFromInt32( aDate.GetYear()+1 ) );
+ }
+ else if ( (nMonth == 1) && (nWeek > 50) )
+ {
+ aStr.AppendAscii( ", " );
+ aStr.Append( XubString::CreateFromInt32( aDate.GetYear()-1 ) );
+ }
+ Help::ShowQuickHelp( this, aDateRect, aStr );
+ return;
+ }
+ }
+ }
+
+ Control::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ if ( !mbSelection && rCEvt.IsMouseEvent() )
+ {
+ Date aTempDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rCEvt.GetMousePosPixel(), aTempDate );
+ if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
+ {
+ ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate );
+ return;
+ }
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ long nNotchDelta = pData->GetNotchDelta();
+ if ( nNotchDelta < 0 )
+ {
+ while ( nNotchDelta < 0 )
+ {
+ ImplScroll( TRUE );
+ nNotchDelta++;
+ }
+ }
+ else
+ {
+ while ( nNotchDelta > 0 )
+ {
+ ImplScroll( FALSE );
+ nNotchDelta--;
+ }
+ }
+
+ return;
+ }
+ }
+
+ Control::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplFormat();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SelectionChanging()
+{
+ maSelectionChangingHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::DateRangeChanged()
+{
+ maDateRangeChangedHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::RequestDateInfo()
+{
+ maRequestDateInfoHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SelectDate( const Date& rDate, BOOL bSelect )
+{
+ if ( !rDate.IsValid() )
+ return;
+
+ Table* pOldSel;
+
+ if ( !mbInSelChange )
+ pOldSel = new Table( *mpSelectTable );
+ else
+ pOldSel = NULL;
+
+ ImplCalendarSelectDate( mpSelectTable, rDate, bSelect );
+
+ if ( pOldSel )
+ {
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SelectDateRange( const Date& rStartDate, const Date& rEndDate,
+ BOOL bSelect )
+{
+ if ( !rStartDate.IsValid() || !rEndDate.IsValid() )
+ return;
+
+ Table* pOldSel;
+
+ if ( !mbInSelChange )
+ pOldSel = new Table( *mpSelectTable );
+ else
+ pOldSel = NULL;
+
+ ImplCalendarSelectDateRange( mpSelectTable, rStartDate, rEndDate, bSelect );
+
+ if ( pOldSel )
+ {
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetNoSelection()
+{
+ Table* pOldSel;
+
+ if ( !mbInSelChange )
+ pOldSel = new Table( *mpSelectTable );
+ else
+ pOldSel = NULL;
+
+ ImplCalendarClearSelectDate( mpSelectTable );
+
+ if ( pOldSel )
+ {
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::IsDateSelected( const Date& rDate ) const
+{
+ return mpSelectTable->IsKeyValid( rDate.GetDate() );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Calendar::GetSelectDateCount() const
+{
+ return mpSelectTable->Count();
+}
+
+// -----------------------------------------------------------------------
+
+Date Calendar::GetSelectDate( ULONG nIndex ) const
+{
+ if ( nIndex < mpSelectTable->Count() )
+ return Date( mpSelectTable->GetObjectKey( nIndex ) );
+ else
+ {
+ Date aDate( 0, 0, 0 );
+ return aDate;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetCurDate( const Date& rNewDate )
+{
+ if ( !rNewDate.IsValid() )
+ return;
+
+ if ( maCurDate != rNewDate )
+ {
+ BOOL bUpdate = IsVisible() && IsUpdateMode();
+ Date aOldDate = maCurDate;
+ maCurDate = rNewDate;
+ maAnchorDate = maCurDate;
+
+ if ( !(mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) )
+ {
+ ImplCalendarSelectDate( mpSelectTable, aOldDate, FALSE );
+ ImplCalendarSelectDate( mpSelectTable, maCurDate, TRUE );
+ }
+ else if ( !HasFocus() )
+ bUpdate = FALSE;
+
+ // Aktuelles Datum noch in den sichtbaren Bereich verschieben
+ if ( mbFormat || (maCurDate < GetFirstMonth()) )
+ SetFirstDate( maCurDate );
+ else if ( maCurDate > GetLastMonth() )
+ {
+ Date aTempDate = GetLastMonth();
+ long nDateOff = maCurDate-aTempDate;
+ if ( nDateOff < 365 )
+ {
+ Date aFirstDate = GetFirstMonth();
+ aFirstDate += aFirstDate.GetDaysInMonth();
+ aTempDate++;
+ while ( nDateOff > aTempDate.GetDaysInMonth() )
+ {
+ aFirstDate += aFirstDate.GetDaysInMonth();
+ long nDaysInMonth = aTempDate.GetDaysInMonth();
+ aTempDate += nDaysInMonth;
+ nDateOff -= nDaysInMonth;
+ }
+ SetFirstDate( aFirstDate );
+ }
+ else
+ SetFirstDate( maCurDate );
+ }
+ else
+ {
+ if ( bUpdate )
+ {
+ HideFocus();
+ ImplUpdateDate( aOldDate );
+ ImplUpdateDate( maCurDate );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetFirstDate( const Date& rNewFirstDate )
+{
+ if ( maFirstDate != rNewFirstDate )
+ {
+ maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() );
+ mbDropPos = FALSE;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Date Calendar::GetFirstMonth() const
+{
+ if ( maFirstDate.GetDay() > 1 )
+ {
+ if ( maFirstDate.GetMonth() == 12 )
+ return Date( 1, 1, maFirstDate.GetYear()+1 );
+ else
+ return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() );
+ }
+ else
+ return maFirstDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date Calendar::GetLastMonth() const
+{
+ Date aDate = GetFirstMonth();
+ USHORT nMonthCount = GetMonthCount();
+ for ( USHORT i = 0; i < nMonthCount; i++ )
+ aDate += aDate.GetDaysInMonth();
+ aDate--;
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Calendar::GetMonthCount() const
+{
+ if ( mbFormat )
+ return 1;
+ else
+ return (USHORT)(mnMonthPerLine*mnLines);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::GetDropDate( Date& rDate ) const
+{
+ if( mbDropPos )
+ {
+ rDate = maDropDate;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::GetDate( const Point& rPos, Date& rDate ) const
+{
+ Date aDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rPos, aDate );
+ if ( nHitTest & CALENDAR_HITTEST_DAY )
+ {
+ rDate = aDate;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle Calendar::GetDateRect( const Date& rDate ) const
+{
+ Rectangle aRect;
+
+ if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) )
+ return aRect;
+
+ long nX;
+ long nY;
+ ULONG nDaysOff;
+ USHORT nDayIndex;
+ Date aDate = GetFirstMonth();
+
+ if ( rDate < aDate )
+ {
+ aRect = GetDateRect( aDate );
+ nDaysOff = aDate-rDate;
+ nX = (long)(nDaysOff*mnDayWidth);
+ aRect.Left() -= nX;
+ aRect.Right() -= nX;
+ return aRect;
+ }
+ else
+ {
+ Date aLastDate = GetLastMonth();
+ if ( rDate > aLastDate )
+ {
+ USHORT nWeekDay = (USHORT)aLastDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)ImplGetWeekStart())) % 7;
+ aLastDate -= nWeekDay;
+ aRect = GetDateRect( aLastDate );
+ nDaysOff = rDate-aLastDate;
+ nDayIndex = 0;
+ for ( USHORT i = 0; i <= nDaysOff; i++ )
+ {
+ if ( aLastDate == rDate )
+ {
+ aRect.Left() += nDayIndex*mnDayWidth;
+ aRect.Right() = aRect.Left()+mnDayWidth;
+ return aRect;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ aRect.Top() += mnDayHeight;
+ aRect.Bottom() += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ aLastDate++;
+ }
+ }
+ }
+
+ nY = 0;
+ for ( long i = 0; i < mnLines; i++ )
+ {
+ nX = 0;
+ for ( long j = 0; j < mnMonthPerLine; j++ )
+ {
+ USHORT nDaysInMonth = aDate.GetDaysInMonth();
+
+ // Monat gerufen
+ if ( (aDate.GetMonth() == rDate.GetMonth()) &&
+ (aDate.GetYear() == rDate.GetYear()) )
+ {
+ long nDayX = nX+mnDaysOffX;
+ long nDayY = nY+mnDaysOffY;
+ nDayIndex = (USHORT)aDate.GetDayOfWeek();
+ nDayIndex = (nDayIndex+(7-(USHORT)ImplGetWeekStart())) % 7;
+ for ( USHORT nDay = 1; nDay <= nDaysInMonth; nDay++ )
+ {
+ if ( nDay == rDate.GetDay() )
+ {
+ aRect.Left() = nDayX + (nDayIndex*mnDayWidth);
+ aRect.Top() = nDayY;
+ aRect.Right() = aRect.Left()+mnDayWidth;
+ aRect.Bottom() = aRect.Top()+mnDayHeight;
+ break;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ }
+
+ aDate += nDaysInMonth;
+ nX += mnMonthWidth;
+ }
+
+ nY += mnMonthHeight;
+ }
+
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetStandardColor( const Color& rColor )
+{
+ if ( mpStandardColor )
+ *mpStandardColor = rColor;
+ else
+ mpStandardColor = new Color( rColor );
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetSaturdayColor( const Color& rColor )
+{
+ if ( mpSaturdayColor )
+ *mpSaturdayColor = rColor;
+ else
+ mpSaturdayColor = new Color( rColor );
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetSundayColor( const Color& rColor )
+{
+ if ( mpSundayColor )
+ *mpSundayColor = rColor;
+ else
+ mpSundayColor = new Color( rColor );
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::AddDateInfo( const Date& rDate, const String& rText,
+ const Color* pTextColor, const Color* pFrameColor,
+ USHORT nFlags )
+{
+ if ( !mpDateTable )
+ mpDateTable = new ImplDateTable( 256, 256 );
+
+ BOOL bChanged = FALSE;
+ ULONG nKey = rDate.GetDate();
+ ImplDateInfo* pDateInfo = mpDateTable->Get( nKey );
+ if ( pDateInfo )
+ pDateInfo->maText = rText;
+ else
+ {
+ pDateInfo = new ImplDateInfo( rText );
+ mpDateTable->Insert( nKey, pDateInfo );
+ }
+ if ( pTextColor )
+ {
+ if ( pDateInfo->mpTextColor )
+ {
+ if ( *(pDateInfo->mpTextColor) != *pTextColor )
+ {
+ *(pDateInfo->mpTextColor) = *pTextColor;
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ pDateInfo->mpTextColor = new Color( *pTextColor );
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ if ( pDateInfo->mpTextColor )
+ {
+ delete pDateInfo->mpTextColor;
+ pDateInfo->mpTextColor = NULL;
+ bChanged = TRUE;
+ }
+ }
+ if ( pFrameColor )
+ {
+ if ( pDateInfo->mpFrameColor )
+ {
+ if ( *(pDateInfo->mpFrameColor) != *pFrameColor )
+ {
+ *(pDateInfo->mpFrameColor) = *pFrameColor;
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ pDateInfo->mpFrameColor = new Color( *pFrameColor );
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ if ( pDateInfo->mpFrameColor )
+ {
+ delete pDateInfo->mpFrameColor;
+ pDateInfo->mpFrameColor = NULL;
+ bChanged = TRUE;
+ }
+ }
+ if ( pDateInfo->mnFlags != nFlags )
+ {
+ pDateInfo->mnFlags = nFlags;
+ bChanged = TRUE;
+ }
+
+ if ( bChanged )
+ ImplUpdateDate( rDate );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::RemoveDateInfo( const Date& rDate )
+{
+ if ( mpDateTable )
+ {
+ ImplDateInfo* pDateInfo = mpDateTable->Remove( rDate.GetDate() );
+ if ( pDateInfo )
+ {
+ delete pDateInfo;
+ ImplUpdateDate( rDate );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ClearDateInfo()
+{
+ if ( mpDateTable )
+ {
+ ImplDateInfo* pDateInfo = mpDateTable->First();
+ while ( pDateInfo )
+ {
+ ULONG nKey = mpDateTable->GetCurKey();
+ mpDateTable->Remove( nKey );
+ Date aDate( nKey );
+ ImplUpdateDate( aDate );
+ delete pDateInfo;
+ pDateInfo = mpDateTable->First();
+ }
+ delete mpDateTable;
+ mpDateTable = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString Calendar::GetDateInfoText( const Date& rDate )
+{
+ XubString aRet;
+ if ( mpDateTable )
+ {
+ ULONG nKey = rDate.GetDate();
+ ImplDateInfo* pDateInfo = mpDateTable->Get( nKey );
+ if ( pDateInfo )
+ aRet = pDateInfo->maText;
+ }
+ return aRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::ShowDropPos( const Point& rPos, Date& rDate )
+{
+ Date aTempDate = maCurDate;
+ mnDragScrollHitTest = ImplHitTest( rPos, aTempDate );
+
+ if ( mnDragScrollHitTest )
+ {
+ if ( mnDragScrollHitTest & (CALENDAR_HITTEST_PREV | CALENDAR_HITTEST_NEXT) )
+ {
+ if ( !maDragScrollTimer.IsActive() )
+ maDragScrollTimer.Start();
+ }
+ else
+ {
+ maDragScrollTimer.Stop();
+ if ( mnDragScrollHitTest & CALENDAR_HITTEST_DAY )
+ {
+ if ( !mbDropPos || (aTempDate != maDropDate) )
+ {
+ if( mbDropPos )
+ ImplInvertDropPos();
+ maDropDate = aTempDate;
+ mbDropPos = TRUE;
+ ImplInvertDropPos();
+ }
+
+ rDate = maDropDate;
+ return TRUE;
+ }
+ }
+ }
+ else
+ maDragScrollTimer.Stop();
+
+ HideDropPos();
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::HideDropPos()
+{
+ if ( mbDropPos )
+ {
+ ImplInvertDropPos();
+ mbDropPos = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::StartSelection()
+{
+ if ( mpOldSelectTable )
+ delete mpOldSelectTable;
+ maOldCurDate = maCurDate;
+ mpOldSelectTable = new Table( *mpSelectTable );
+
+ mbSelection = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::EndSelection()
+{
+ if ( mbDrag || mbSpinDown || mbSelection )
+ {
+ if ( !mbSelection )
+ ReleaseMouse();
+
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbMultiSelection = FALSE;
+ mbSpinDown = FALSE;
+ mbPrevIn = FALSE;
+ mbNextIn = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size Calendar::CalcWindowSizePixel( long nCalcMonthPerLine,
+ long nCalcLines ) const
+{
+ XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
+ Font aOldFont = GetFont();
+
+ // Wochenanzeige beruecksichtigen
+ long nWeekWidth;
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ {
+ Font aTempFont = aOldFont;
+ ImplGetWeekFont( aTempFont );
+ ((Calendar*)this)->SetFont( aTempFont );
+ nWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
+ ((Calendar*)this)->SetFont( aOldFont );
+ }
+ else
+ nWeekWidth = 0;
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ {
+ Font aFont = aOldFont;
+ if ( aFont.GetWeight() < WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ ((Calendar*)this)->SetFont( aFont );
+ }
+
+ Size aSize;
+ long n99TextWidth = GetTextWidth( a99Text );
+ long nTextHeight = GetTextHeight();
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ ((Calendar*)this)->SetFont( aOldFont );
+
+ aSize.Width() += ((n99TextWidth+DAY_OFFX)*7) + nWeekWidth;
+ aSize.Width() += MONTH_BORDERX*2;
+ aSize.Width() *= nCalcMonthPerLine;
+
+ aSize.Height() = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
+ aSize.Height() += nTextHeight + WEEKDAY_OFFY;
+ aSize.Height() += ((nTextHeight+DAY_OFFY)*6);
+ aSize.Height() += MONTH_OFFY;
+ aSize.Height() *= nCalcLines;
+
+ return aSize;
+}
+
+// =======================================================================
+
+#define CALFIELD_EXTRA_BUTTON_WIDTH 14
+#define CALFIELD_EXTRA_BUTTON_HEIGHT 8
+#define CALFIELD_SEP_X 6
+#define CALFIELD_BORDERLINE_X 5
+#define CALFIELD_BORDER_YTOP 4
+#define CALFIELD_BORDER_Y 5
+
+// =======================================================================
+
+class ImplCFieldFloatWin : public FloatingWindow
+{
+private:
+ Calendar* mpCalendar;
+ PushButton* mpTodayBtn;
+ PushButton* mpNoneBtn;
+ FixedLine* mpFixedLine;
+
+public:
+ ImplCFieldFloatWin( Window* pParent );
+ ~ImplCFieldFloatWin();
+
+ void SetCalendar( Calendar* pCalendar )
+ { mpCalendar = pCalendar; }
+
+ PushButton* EnableTodayBtn( BOOL bEnable );
+ PushButton* EnableNoneBtn( BOOL bEnable );
+ void ArrangeButtons();
+
+ long Notify( NotifyEvent& rNEvt );
+};
+
+// -----------------------------------------------------------------------
+
+ImplCFieldFloatWin::ImplCFieldFloatWin( Window* pParent ) :
+ FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW )
+{
+ mpCalendar = NULL;
+ mpTodayBtn = NULL;
+ mpNoneBtn = NULL;
+ mpFixedLine = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplCFieldFloatWin::~ImplCFieldFloatWin()
+{
+ delete mpTodayBtn;
+ delete mpNoneBtn;
+ delete mpFixedLine;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton* ImplCFieldFloatWin::EnableTodayBtn( BOOL bEnable )
+{
+ if ( bEnable )
+ {
+ if ( !mpTodayBtn )
+ {
+ mpTodayBtn = new PushButton( this, WB_NOPOINTERFOCUS );
+ XubString aTodayText( SvtResId( STR_SVT_CALENDAR_TODAY ) );
+ mpTodayBtn->SetText( aTodayText );
+ Size aSize;
+ aSize.Width() = mpTodayBtn->GetCtrlTextWidth( mpTodayBtn->GetText() );
+ aSize.Height() = mpTodayBtn->GetTextHeight();
+ aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH;
+ aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
+ mpTodayBtn->SetSizePixel( aSize );
+ mpTodayBtn->Show();
+ }
+ }
+ else
+ {
+ if ( mpTodayBtn )
+ {
+ delete mpTodayBtn;
+ mpTodayBtn = NULL;
+ }
+ }
+
+ return mpTodayBtn;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton* ImplCFieldFloatWin::EnableNoneBtn( BOOL bEnable )
+{
+ if ( bEnable )
+ {
+ if ( !mpNoneBtn )
+ {
+ mpNoneBtn = new PushButton( this, WB_NOPOINTERFOCUS );
+ XubString aNoneText( SvtResId( STR_SVT_CALENDAR_NONE ) );
+ mpNoneBtn->SetText( aNoneText );
+ Size aSize;
+ aSize.Width() = mpNoneBtn->GetCtrlTextWidth( mpNoneBtn->GetText() );
+ aSize.Height() = mpNoneBtn->GetTextHeight();
+ aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH;
+ aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
+ mpNoneBtn->SetSizePixel( aSize );
+ mpNoneBtn->Show();
+ }
+ }
+ else
+ {
+ if ( mpNoneBtn )
+ {
+ delete mpNoneBtn;
+ mpNoneBtn = NULL;
+ }
+ }
+
+ return mpNoneBtn;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplCFieldFloatWin::ArrangeButtons()
+{
+ long nBtnHeight = 0;
+ long nBtnWidth = 0;
+ Size aOutSize = GetOutputSizePixel();
+ if ( mpTodayBtn && mpNoneBtn )
+ {
+ Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
+ Size aNoneBtnSize = mpNoneBtn->GetSizePixel();
+ if ( aTodayBtnSize.Width() < aNoneBtnSize.Width() )
+ aTodayBtnSize.Width() = aNoneBtnSize.Width();
+ else
+ aNoneBtnSize.Width() = aTodayBtnSize.Width();
+ if ( aTodayBtnSize.Height() < aNoneBtnSize.Height() )
+ aTodayBtnSize.Height() = aNoneBtnSize.Height();
+ else
+ aNoneBtnSize.Height() = aTodayBtnSize.Height();
+
+ nBtnWidth = aTodayBtnSize.Width() + aNoneBtnSize.Width() + CALFIELD_SEP_X;
+ nBtnHeight = aTodayBtnSize.Height();
+ long nX = (aOutSize.Width()-nBtnWidth)/2;
+ long nY = aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP;
+ mpTodayBtn->SetPosSizePixel( Point( nX, nY ), aTodayBtnSize );
+ nX += aTodayBtnSize.Width() + CALFIELD_SEP_X;
+ mpNoneBtn->SetPosSizePixel( Point( nX, nY ), aNoneBtnSize );
+ }
+ else if ( mpTodayBtn )
+ {
+ Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
+ nBtnWidth = aTodayBtnSize.Width();
+ nBtnHeight = aTodayBtnSize.Height();
+ mpTodayBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
+ }
+ else if ( mpNoneBtn )
+ {
+ Size aNoneBtnSize = mpNoneBtn->GetSizePixel();
+ nBtnWidth = aNoneBtnSize.Width();
+ nBtnHeight = aNoneBtnSize.Height();
+ mpNoneBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
+ }
+
+ if ( nBtnHeight )
+ {
+ if ( !mpFixedLine )
+ {
+ mpFixedLine = new FixedLine( this );
+ mpFixedLine->Show();
+ }
+ long nLineWidth = aOutSize.Width()-(CALFIELD_BORDERLINE_X*2);
+ mpFixedLine->SetPosSizePixel( (aOutSize.Width()-nLineWidth)/2, aOutSize.Height()+((CALFIELD_BORDER_YTOP-2)/2),
+ nLineWidth, 2, WINDOW_POSSIZE_POSSIZE );
+ aOutSize.Height() += nBtnHeight + (CALFIELD_BORDER_Y*2) + CALFIELD_BORDER_YTOP;
+ SetOutputSizePixel( aOutSize );
+ }
+ else
+ {
+ if ( mpFixedLine )
+ {
+ delete mpFixedLine;
+ mpFixedLine = NULL;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplCFieldFloatWin::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
+ mpCalendar->Select();
+ }
+
+ return FloatingWindow::Notify( rNEvt );
+}
+
+// =======================================================================
+
+CalendarField::CalendarField( Window* pParent, WinBits nWinStyle ) :
+ DateField( pParent, nWinStyle ),
+ maDefaultDate( 0, 0, 0 )
+{
+ mpFloatWin = NULL;
+ mpCalendar = NULL;
+ mnCalendarStyle = 0;
+ mbToday = FALSE;
+ mbNone = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+CalendarField::CalendarField( Window* pParent, const ResId& rResId ) :
+ DateField( pParent, rResId ),
+ maDefaultDate( 0, 0, 0 )
+{
+ mpFloatWin = NULL;
+ mpCalendar = NULL;
+ mnCalendarStyle = 0;
+ mbToday = FALSE;
+ mbNone = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+CalendarField::~CalendarField()
+{
+ if ( mpFloatWin )
+ {
+ delete mpCalendar;
+ delete mpFloatWin;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( CalendarField, ImplSelectHdl, Calendar*, pCalendar )
+{
+ if ( !pCalendar->IsTravelSelect() )
+ {
+ mpFloatWin->EndPopupMode();
+ EndDropDown();
+ GrabFocus();
+ Date aNewDate = mpCalendar->GetSelectDate( 0 );
+ if ( IsEmptyDate() || ( aNewDate != GetDate() ) )
+ {
+ SetDate( aNewDate );
+ SetModifyFlag();
+ Modify();
+ }
+ Select();
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( CalendarField, ImplClickHdl, PushButton*, pBtn )
+{
+ mpFloatWin->EndPopupMode();
+ EndDropDown();
+ GrabFocus();
+
+ if ( pBtn == mpTodayBtn )
+ {
+ Date aToday;
+ if ( (aToday != GetDate()) || IsEmptyDate() )
+ {
+ SetDate( aToday );
+ SetModifyFlag();
+ Modify();
+ }
+ }
+ else if ( pBtn == mpNoneBtn )
+ {
+ if ( !IsEmptyDate() )
+ {
+ SetEmptyDate();
+ SetModifyFlag();
+ Modify();
+ }
+ }
+ Select();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( CalendarField, ImplPopupModeEndHdl, FloatingWindow*, EMPTYARG )
+{
+ EndDropDown();
+ GrabFocus();
+ mpCalendar->EndSelection();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void CalendarField::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL CalendarField::ShowDropDown( BOOL bShow )
+{
+ if ( bShow )
+ {
+ Calendar* pCalendar = GetCalendar();
+
+ Date aDate = GetDate();
+ if ( IsEmptyDate() || !aDate.IsValid() )
+ {
+ if ( maDefaultDate.IsValid() )
+ aDate = maDefaultDate;
+ else
+ aDate = Date();
+ }
+ if ( pCalendar->GetStyle() & (WB_RANGESELECT | WB_MULTISELECT) )
+ {
+ pCalendar->SetNoSelection();
+ pCalendar->SelectDate( aDate );
+ }
+ pCalendar->SetCurDate( aDate );
+ Point aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
+ Rectangle aRect( aPos, GetSizePixel() );
+ aRect.Bottom() -= 1;
+ mpCalendar->SetOutputSizePixel( mpCalendar->CalcWindowSizePixel() );
+ mpFloatWin->SetOutputSizePixel( mpCalendar->GetSizePixel() );
+ mpFloatWin->SetCalendar( mpCalendar );
+ mpTodayBtn = mpFloatWin->EnableTodayBtn( mbToday );
+ mpNoneBtn = mpFloatWin->EnableNoneBtn( mbNone );
+ if ( mpTodayBtn )
+ mpTodayBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
+ if ( mpNoneBtn )
+ mpNoneBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
+ mpFloatWin->ArrangeButtons();
+ mpCalendar->EnableCallEverySelect();
+ mpCalendar->StartSelection();
+ mpCalendar->GrabFocus();
+ mpCalendar->Show();
+ mpFloatWin->StartPopupMode( aRect, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_DOWN );
+ }
+ else
+ {
+ mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+ mpCalendar->EndSelection();
+ EndDropDown();
+ }
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Calendar* CalendarField::CreateCalendar( Window* pParent )
+{
+ return new Calendar( pParent, mnCalendarStyle | WB_TABSTOP );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar* CalendarField::GetCalendar()
+{
+ if ( !mpFloatWin )
+ {
+ mpFloatWin = new ImplCFieldFloatWin( this );
+ mpFloatWin->SetPopupModeEndHdl( LINK( this, CalendarField, ImplPopupModeEndHdl ) );
+ mpCalendar = CreateCalendar( mpFloatWin );
+ mpCalendar->SetPosPixel( Point() );
+ mpCalendar->SetSelectHdl( LINK( this, CalendarField, ImplSelectHdl ) );
+ }
+
+ return mpCalendar;
+}
+
+// -----------------------------------------------------------------------
+
+void CalendarField::StateChanged( StateChangedType nStateChange )
+{
+ DateField::StateChanged( nStateChange );
+
+ if ( ( nStateChange == STATE_CHANGE_STYLE ) && GetSubEdit() )
+ {
+ WinBits nAllAlignmentBits = ( WB_LEFT | WB_CENTER | WB_RIGHT | WB_TOP | WB_VCENTER | WB_BOTTOM );
+ WinBits nMyAlignment = GetStyle() & nAllAlignmentBits;
+ GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits ) | nMyAlignment );
+ }
+}
+
diff --git a/svtools/source/control/calendar.src b/svtools/source/control/calendar.src
new file mode 100755
index 000000000000..4dd31765a5c1
--- /dev/null
+++ b/svtools/source/control/calendar.src
@@ -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.
+ *
+ ************************************************************************/
+
+#include <svtools/svtools.hrc>
+String STR_SVT_CALENDAR_DAY
+{
+ Text [ en-US ] = "Day" ;
+};
+String STR_SVT_CALENDAR_WEEK
+{
+ Text [ en-US ] = "Week" ;
+};
+String STR_SVT_CALENDAR_TODAY
+{
+ Text [ en-US ] = "Today" ;
+};
+String STR_SVT_CALENDAR_NONE
+{
+ Text [ en-US ] = "None" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/control/collatorres.cxx b/svtools/source/control/collatorres.cxx
new file mode 100755
index 000000000000..9988bfdadbb9
--- /dev/null
+++ b/svtools/source/control/collatorres.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_svtools.hxx"
+#include <svtools/svtdata.hxx>
+#include <svtools/svtools.hrc>
+
+
+#include <collatorres.hxx>
+
+// -------------------------------------------------------------------------
+//
+// wrapper for locale specific translations data of collator algorithm
+//
+// -------------------------------------------------------------------------
+
+class CollatorRessourceData
+{
+ friend class CollatorRessource;
+ private: /* data */
+ String ma_Name;
+ String ma_Translation;
+ private: /* member functions */
+ CollatorRessourceData () {}
+ public:
+ CollatorRessourceData ( const String &r_Algorithm, const String &r_Translation)
+ : ma_Name (r_Algorithm), ma_Translation (r_Translation) {}
+
+ const String& GetAlgorithm () const { return ma_Name; }
+
+ const String& GetTranslation () const { return ma_Translation; }
+
+ ~CollatorRessourceData () {}
+
+ CollatorRessourceData& operator= (const CollatorRessourceData& r_From)
+ {
+ ma_Name = r_From.GetAlgorithm();
+ ma_Translation = r_From.GetTranslation();
+ return *this;
+ }
+};
+
+// -------------------------------------------------------------------------
+//
+// implementation of the collator-algorithm-name translation
+//
+// -------------------------------------------------------------------------
+
+#define COLLATOR_RESSOURCE_COUNT (STR_SVT_COLLATE_END - STR_SVT_COLLATE_START + 1)
+
+CollatorRessource::CollatorRessource()
+{
+ mp_Data = new CollatorRessourceData[COLLATOR_RESSOURCE_COUNT];
+
+ #define ASCSTR(str) String(RTL_CONSTASCII_USTRINGPARAM(str))
+ #define RESSTR(rid) String(SvtResId(rid))
+
+
+ mp_Data[0] = CollatorRessourceData (ASCSTR("alphanumeric"), RESSTR(STR_SVT_COLLATE_ALPHANUMERIC));
+ mp_Data[1] = CollatorRessourceData (ASCSTR("charset"), RESSTR(STR_SVT_COLLATE_CHARSET));
+ mp_Data[2] = CollatorRessourceData (ASCSTR("dict"), RESSTR(STR_SVT_COLLATE_DICTIONARY));
+ mp_Data[3] = CollatorRessourceData (ASCSTR("normal"), RESSTR(STR_SVT_COLLATE_NORMAL));
+ mp_Data[4] = CollatorRessourceData (ASCSTR("pinyin"), RESSTR(STR_SVT_COLLATE_PINYIN));
+ mp_Data[5] = CollatorRessourceData (ASCSTR("radical"), RESSTR(STR_SVT_COLLATE_RADICAL));
+ mp_Data[6] = CollatorRessourceData (ASCSTR("stroke"), RESSTR(STR_SVT_COLLATE_STROKE));
+ mp_Data[7] = CollatorRessourceData (ASCSTR("unicode"), RESSTR(STR_SVT_COLLATE_UNICODE));
+ mp_Data[8] = CollatorRessourceData (ASCSTR("zhuyin"), RESSTR(STR_SVT_COLLATE_ZHUYIN));
+ mp_Data[9] = CollatorRessourceData (ASCSTR("phonebook"), RESSTR(STR_SVT_COLLATE_PHONEBOOK));
+ mp_Data[10] = CollatorRessourceData (ASCSTR("phonetic (alphanumeric first)"), RESSTR(STR_SVT_COLLATE_PHONETIC_F));
+ mp_Data[11] = CollatorRessourceData (ASCSTR("phonetic (alphanumeric last)"), RESSTR(STR_SVT_COLLATE_PHONETIC_L));
+}
+
+CollatorRessource::~CollatorRessource()
+{
+ delete[] mp_Data;
+}
+
+const String&
+CollatorRessource::GetTranslation (const String &r_Algorithm)
+{
+ xub_StrLen nIndex = r_Algorithm.Search('.');
+ String aLocaleFreeAlgorithm;
+
+ if (nIndex == STRING_NOTFOUND)
+ {
+ aLocaleFreeAlgorithm = r_Algorithm;
+ }
+ else
+ {
+ nIndex += 1;
+ aLocaleFreeAlgorithm = String(r_Algorithm, nIndex, r_Algorithm.Len() - nIndex);
+ }
+
+ for (sal_uInt32 i = 0; i < COLLATOR_RESSOURCE_COUNT; i++)
+ {
+ if (aLocaleFreeAlgorithm == mp_Data[i].GetAlgorithm())
+ return mp_Data[i].GetTranslation();
+ }
+
+ return r_Algorithm;
+}
+
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
new file mode 100755
index 000000000000..d44b18a29ae1
--- /dev/null
+++ b/svtools/source/control/ctrlbox.cxx
@@ -0,0 +1,1509 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _CTRLBOX_CXX
+#include <tools/debug.hxx>
+#ifndef _APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _FIELD_HXX
+#include <vcl/field.hxx>
+#endif
+#include <comphelper/processfactory.hxx>
+#include <unotools/charclass.hxx>
+
+#include <svtools/svtdata.hxx>
+#include <svtools/svtools.hrc>
+#include <ctrlbox.hxx>
+#include <ctrltool.hxx>
+
+#include <vcl/i18nhelp.hxx>
+
+#define IMGTEXTSPACE 2
+#define EXTRAFONTSIZE 5
+
+static sal_Unicode aImplSymbolFontText[] = {0xF021,0xF032,0xF043,0xF054,0xF065,0xF076,0xF0B7,0xF0C8,0};
+static sal_Unicode aImplStarSymbolText[] = {0x2706,0x2704,0x270D,0xE033,0x2211,0x2288,0};
+
+// ========================================================================
+// ColorListBox
+// ========================================================================
+
+// --------------------
+// - ImplColorListData -
+// --------------------
+
+struct ImplColorListData
+{
+ Color aColor;
+ BOOL bColor;
+
+ ImplColorListData() : aColor( COL_BLACK ) { bColor = FALSE; }
+ ImplColorListData( const Color& rColor ) : aColor( rColor ) { bColor = TRUE; }
+};
+
+DECLARE_LIST( ImpColorList, ImplColorListData* )
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::ImplInit()
+{
+ pColorList = new ImpColorList( 256, 64 );
+ aImageSize.Width() = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "xxx" ) ) );
+ aImageSize.Height() = GetTextHeight();
+ aImageSize.Height() -= 2;
+
+ EnableUserDraw( TRUE );
+ SetUserItemSize( aImageSize );
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::ImplDestroyColorEntries()
+{
+ for ( USHORT n = (USHORT) pColorList->Count(); n; )
+ {
+ ImplColorListData* pData = pColorList->GetObject( --n );
+ delete pData;
+ }
+ pColorList->Clear();
+}
+
+// -----------------------------------------------------------------------
+
+ColorListBox::ColorListBox( Window* pParent, WinBits nWinStyle ) :
+ ListBox( pParent, nWinStyle )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ColorListBox::ColorListBox( Window* pParent, const ResId& rResId ) :
+ ListBox( pParent, rResId )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ColorListBox::~ColorListBox()
+{
+ ImplDestroyColorEntries();
+ delete pColorList;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ColorListBox::InsertEntry( const XubString& rStr, USHORT nPos )
+{
+ nPos = ListBox::InsertEntry( rStr, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ {
+ ImplColorListData* pData = new ImplColorListData;
+ pColorList->Insert( pData, nPos );
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ColorListBox::InsertEntry( const Color& rColor, const XubString& rStr,
+ USHORT nPos )
+{
+ nPos = ListBox::InsertEntry( rStr, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ {
+ ImplColorListData* pData = new ImplColorListData( rColor );
+ pColorList->Insert( pData, nPos );
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::InsertAutomaticEntry()
+{
+ // insert the "Automatic"-entry always on the first position
+ InsertEntry( Color( COL_AUTO ), SvtResId( STR_SVT_AUTOMATIC_COLOR ), 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::RemoveEntry( USHORT nPos )
+{
+ ListBox::RemoveEntry( nPos );
+ delete pColorList->Remove( nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::Clear()
+{
+ ImplDestroyColorEntries();
+ ListBox::Clear();
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::CopyEntries( const ColorListBox& rBox )
+{
+ // Liste leeren
+ ImplDestroyColorEntries();
+
+ // Daten kopieren
+ USHORT nCount = (USHORT) rBox.pColorList->Count();
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ ImplColorListData* pData = rBox.pColorList->GetObject( n );
+ USHORT nPos = InsertEntry( rBox.GetEntry( n ), LISTBOX_APPEND );
+ if ( nPos != LISTBOX_ERROR )
+ pColorList->Insert( new ImplColorListData( *pData ), nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ColorListBox::GetEntryPos( const Color& rColor ) const
+{
+ for( USHORT n = (USHORT) pColorList->Count(); n; )
+ {
+ ImplColorListData* pData = pColorList->GetObject( --n );
+ if ( pData->bColor && ( pData->aColor == rColor ) )
+ return n;
+ }
+ return LISTBOX_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+Color ColorListBox::GetEntryColor( USHORT nPos ) const
+{
+ Color aColor;
+ ImplColorListData* pData = pColorList->GetObject( nPos );
+ if ( pData && pData->bColor )
+ aColor = pData->aColor;
+ return aColor;
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ ImplColorListData* pData = pColorList->GetObject( rUDEvt.GetItemId() );
+ if ( pData )
+ {
+ if ( pData->bColor )
+ {
+ Point aPos( rUDEvt.GetRect().TopLeft() );
+ aPos.X() += 2;
+ aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aImageSize.Height() ) / 2;
+ rUDEvt.GetDevice()->Push();
+ rUDEvt.GetDevice()->SetFillColor( pData->aColor );
+ rUDEvt.GetDevice()->SetLineColor( rUDEvt.GetDevice()->GetTextColor() );
+ rUDEvt.GetDevice()->DrawRect( Rectangle( aPos, aImageSize ) );
+ rUDEvt.GetDevice()->Pop();
+ ListBox::DrawEntry( rUDEvt, FALSE, TRUE, FALSE );
+ }
+ else
+ ListBox::DrawEntry( rUDEvt, FALSE, TRUE, TRUE );
+ }
+ else
+ ListBox::DrawEntry( rUDEvt, TRUE, TRUE, FALSE );
+}
+
+// =======================================================================
+// LineListBox
+// =======================================================================
+
+// -------------------
+// - ImpListListData -
+// -------------------
+
+struct ImpLineListData
+{
+ long nLine1;
+ long nLine2;
+ long nDistance;
+};
+
+DECLARE_LIST( ImpLineList, ImpLineListData* )
+
+// -----------------------------------------------------------------------
+
+inline const Color& LineListBox::GetPaintColor( void ) const
+{
+ return maPaintCol;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
+ Bitmap& rBmp, XubString& rStr )
+{
+ Size aSize = GetOutputSizePixel();
+ aSize.Width() -= 20;
+ aSize.Width() -= aTxtSize.Width();
+ aSize.Height() = aTxtSize.Height();
+
+ // SourceUnit nach Twips
+ if ( eSourceUnit == FUNIT_POINT )
+ {
+ nLine1 *= 20;
+ nLine2 *= 20;
+ nDistance *= 20;
+ }
+ else if ( eSourceUnit == FUNIT_MM )
+ {
+ nLine1 *= 14440;
+ nLine1 /= 254;
+ nLine2 *= 14440;
+ nLine2 /= 254;
+ nDistance *= 14440;
+ nDistance /= 254;
+ }
+
+ // Linien malen
+ aSize = aVirDev.PixelToLogic( aSize );
+ long nPix = aVirDev.PixelToLogic( Size( 0, 1 ) ).Height();
+ long n1 = nLine1 / 100;
+ long n2 = nLine2 / 100;
+ long nDist = nDistance / 100;
+ n1 += nPix-1;
+ n1 -= n1%nPix;
+ if ( n2 )
+ {
+ nDist += nPix-1;
+ nDist -= nDist%nPix;
+ n2 += nPix-1;
+ n2 -= n2%nPix;
+ }
+ long nVirHeight = n1+nDist+n2;
+ if ( nVirHeight > aSize.Height() )
+ aSize.Height() = nVirHeight;
+ // negative Breiten muss und darf man nicht painten
+ if ( aSize.Width() > 0 )
+ {
+ Size aVirSize = aVirDev.LogicToPixel( aSize );
+ if ( aVirDev.GetOutputSizePixel() != aVirSize )
+ aVirDev.SetOutputSizePixel( aVirSize );
+ aVirDev.SetFillColor( GetSettings().GetStyleSettings().GetFieldColor() );
+ aVirDev.DrawRect( Rectangle( Point(), aSize ) );
+
+ aVirDev.SetFillColor( GetPaintColor() );
+ aVirDev.DrawRect( Rectangle( 0, 0, aSize.Width(), n1-nPix ) );
+ if ( n2 )
+ {
+ aVirDev.DrawRect( Rectangle( 0, n1+nDist,
+ aSize.Width(), n1+nDist+n2-nPix ) );
+ }
+ rBmp = aVirDev.GetBitmap( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
+ }
+ // Twips nach Unit
+ if ( eUnit == FUNIT_POINT )
+ {
+ nLine1 /= 20;
+ nLine2 /= 20;
+ nDistance /= 20;
+ rStr.AssignAscii( " pt" );
+ }
+ else if ( eUnit == FUNIT_MM )
+ {
+ nLine1 *= 254;
+ nLine1 /= 14400;
+ nLine2 *= 254;
+ nLine2 /= 14400;
+ nDistance *= 254;
+ nDistance /= 14400;
+ rStr.AssignAscii( " mm" );
+ }
+
+ String aNum( GetSettings().GetLocaleI18nHelper().GetNum( nLine1+nLine2+nDistance, 2 ) );
+ rStr.Insert( aNum, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::ImplInit()
+{
+ aTxtSize.Width() = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "99,99 mm" ) ) );
+ aTxtSize.Height() = GetTextHeight();
+ pLineList = new ImpLineList;
+ eUnit = FUNIT_POINT;
+ eSourceUnit = FUNIT_POINT;
+
+ aVirDev.SetLineColor();
+ aVirDev.SetMapMode( MapMode( MAP_TWIP ) );
+
+ UpdatePaintLineColor();
+}
+
+// -----------------------------------------------------------------------
+
+LineListBox::LineListBox( Window* pParent, WinBits nWinStyle ) :
+ ListBox( pParent, nWinStyle ),
+ aColor( COL_BLACK ),
+ maPaintCol( COL_BLACK )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+LineListBox::LineListBox( Window* pParent, const ResId& rResId ) :
+ ListBox( pParent, rResId ),
+ aColor( COL_BLACK ),
+ maPaintCol( COL_BLACK )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+LineListBox::~LineListBox()
+{
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ delete pData;
+ n++;
+ }
+ delete pLineList;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LineListBox::InsertEntry( const XubString& rStr, USHORT nPos )
+{
+ nPos = ListBox::InsertEntry( rStr, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ pLineList->Insert( NULL, nPos );
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LineListBox::InsertEntry( long nLine1, long nLine2, long nDistance,
+ USHORT nPos )
+{
+ XubString aStr;
+ Bitmap aBmp;
+ ImpGetLine( nLine1, nLine2, nDistance, aBmp, aStr );
+ nPos = ListBox::InsertEntry( aStr, aBmp, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ {
+ ImpLineListData* pData = new ImpLineListData;
+ pData->nLine1 = nLine1;
+ pData->nLine2 = nLine2;
+ pData->nDistance = nDistance;
+ pLineList->Insert( pData, nPos );
+ }
+
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::RemoveEntry( USHORT nPos )
+{
+ ListBox::RemoveEntry( nPos );
+ ImpLineListData* pData = pLineList->Remove( nPos );
+ if ( pData )
+ delete pData;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::Clear()
+{
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ delete pData;
+ n++;
+ }
+
+ pLineList->Clear();
+ ListBox::Clear();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LineListBox::GetEntryPos( long nLine1, long nLine2,
+ long nDistance ) const
+{
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ {
+ if ( (pData->nLine1 == nLine1) &&
+ (pData->nLine2 == nLine2) &&
+ (pData->nDistance == nDistance) )
+ return (USHORT)n;
+ }
+
+ n++;
+ }
+
+ return LISTBOX_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+long LineListBox::GetEntryLine1( USHORT nPos ) const
+{
+ ImpLineListData* pData = pLineList->GetObject( nPos );
+ if ( pData )
+ return pData->nLine1;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long LineListBox::GetEntryLine2( USHORT nPos ) const
+{
+ ImpLineListData* pData = pLineList->GetObject( nPos );
+ if ( pData )
+ return pData->nLine2;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long LineListBox::GetEntryDistance( USHORT nPos ) const
+{
+ ImpLineListData* pData = pLineList->GetObject( nPos );
+ if ( pData )
+ return pData->nDistance;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::UpdateLineColors( void )
+{
+ if( UpdatePaintLineColor() )
+ {
+ ULONG nCount = pLineList->Count();
+ if( !nCount )
+ return;
+
+ XubString aStr;
+ Bitmap aBmp;
+
+ // exchange entries which containing lines
+ SetUpdateMode( FALSE );
+
+ USHORT nSelEntry = GetSelectEntryPos();
+ for( ULONG n = 0 ; n < nCount ; ++n )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if( pData )
+ {
+ // exchange listbox data
+ ListBox::RemoveEntry( USHORT( n ) );
+ ImpGetLine( pData->nLine1, pData->nLine2, pData->nDistance, aBmp, aStr );
+ ListBox::InsertEntry( aStr, aBmp, USHORT( n ) );
+ }
+ }
+
+ if( nSelEntry != LISTBOX_ENTRY_NOTFOUND )
+ SelectEntryPos( nSelEntry );
+
+ SetUpdateMode( TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL LineListBox::UpdatePaintLineColor( void )
+{
+ BOOL bRet = TRUE;
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+ Color aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
+
+ bRet = aNewCol != maPaintCol;
+
+ if( bRet )
+ maPaintCol = aNewCol;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ListBox::DataChanged( rDCEvt );
+
+ if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
+ UpdateLineColors();
+}
+
+// ===================================================================
+// FontNameBox
+// ===================================================================
+
+struct ImplFontNameListData
+{
+ FontInfo maInfo;
+ USHORT mnType;
+
+ ImplFontNameListData( const FontInfo& rInfo,
+ USHORT nType ) :
+ maInfo( rInfo ),
+ mnType( nType )
+ {}
+};
+
+DECLARE_LIST( ImplFontList, ImplFontNameListData* )
+
+// -------------------------------------------------------------------
+
+FontNameBox::FontNameBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ InitBitmaps();
+ mpFontList = NULL;
+ mbWYSIWYG = FALSE;
+ mbSymbols = FALSE;
+}
+
+// -------------------------------------------------------------------
+
+FontNameBox::FontNameBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( pParent, rResId )
+{
+ InitBitmaps();
+ mpFontList = NULL;
+ mbWYSIWYG = FALSE;
+ mbSymbols = FALSE;
+}
+
+// -------------------------------------------------------------------
+
+FontNameBox::~FontNameBox()
+{
+ ImplDestroyFontList();
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if( rDCEvt.GetType() == DATACHANGED_SETTINGS && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
+ InitBitmaps();
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::InitBitmaps( void )
+{
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ maImagePrinterFont = Image( SvtResId( bHC? RID_IMG_PRINTERFONT_HC : RID_IMG_PRINTERFONT ) );
+ maImageBitmapFont = Image( SvtResId( bHC? RID_IMG_BITMAPFONT_HC : RID_IMG_BITMAPFONT ) );
+ maImageScalableFont = Image( SvtResId( bHC? RID_IMG_SCALABLEFONT_HC : RID_IMG_SCALABLEFONT ) );
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::ImplDestroyFontList()
+{
+ if ( mpFontList )
+ {
+ ImplFontNameListData* pInfo = mpFontList->First();
+ while ( pInfo )
+ {
+ delete pInfo;
+ pInfo = mpFontList->Next();
+ }
+ delete mpFontList;
+ }
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::Fill( const FontList* pList )
+{
+ // store old text and clear box
+ XubString aOldText = GetText();
+ Clear();
+
+ ImplDestroyFontList();
+ mpFontList = new ImplFontList;
+
+ // insert fonts
+ USHORT nFontCount = pList->GetFontNameCount();
+ for ( USHORT i = 0; i < nFontCount; i++ )
+ {
+ const FontInfo& rFontInfo = pList->GetFontName( i );
+ ULONG nIndex = InsertEntry( rFontInfo.GetName() );
+ if ( nIndex != LISTBOX_ERROR )
+ {
+ USHORT nType = pList->GetFontNameType( i );
+ ImplFontNameListData* pData = new ImplFontNameListData( rFontInfo, nType );
+ mpFontList->Insert( pData, nIndex );
+ }
+ }
+
+ ImplCalcUserItemSize();
+
+ // restore text
+ if ( aOldText.Len() )
+ SetText( aOldText );
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::EnableWYSIWYG( BOOL bEnable )
+{
+ if ( bEnable != mbWYSIWYG )
+ {
+ mbWYSIWYG = bEnable;
+ EnableUserDraw( mbWYSIWYG | mbSymbols );
+ ImplCalcUserItemSize();
+ }
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::EnableSymbols( BOOL bEnable )
+{
+ if ( bEnable != mbSymbols )
+ {
+ mbSymbols = bEnable;
+ EnableUserDraw( mbWYSIWYG | mbSymbols );
+ ImplCalcUserItemSize();
+ }
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::ImplCalcUserItemSize()
+{
+ Size aUserItemSz;
+ if ( mbWYSIWYG && mpFontList )
+ {
+ USHORT nMaxLen = 0;
+ BOOL bSymbolFont = FALSE;
+ BOOL bStarSymbol = FALSE;
+ for ( USHORT n = GetEntryCount(); n; )
+ {
+ ImplFontNameListData* pData = mpFontList->GetObject( --n );
+ XubString aFontName = pData->maInfo.GetName();
+ if ( aFontName.Len() > nMaxLen )
+ nMaxLen = aFontName.Len();
+ if ( pData->maInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
+ bSymbolFont = TRUE;
+ // starsymbol is a unicode font, but gets WYSIWIG symbols
+ if( aFontName.EqualsIgnoreCaseAscii( "starsymbol" )
+ || aFontName.EqualsIgnoreCaseAscii( "opensymbol" ) )
+ bSymbolFont = bStarSymbol = TRUE;
+ }
+
+ // guess maximimum width
+ Size aOneCharSz( GetTextWidth( String( 'X' ) ), GetTextHeight() );
+ Size aSz( aOneCharSz );
+ aSz.Width() *= nMaxLen;
+ // only XX% of width, because ListBox calculates the normal width...
+ aSz.Width() *= 1;
+ aSz.Width() /= 10;
+ if ( bSymbolFont )
+ {
+ int nLength = sizeof(aImplSymbolFontText)/sizeof(aImplSymbolFontText[0]) - 1;
+ int nLength2 = sizeof(aImplStarSymbolText)/sizeof(aImplStarSymbolText[0]) - 1;
+ if( bStarSymbol && (nLength < nLength2) )
+ nLength = nLength2;
+ aSz.Width() += aOneCharSz.Width() * nLength;
+ }
+ aSz.Height() *= 14;
+ aSz.Height() /= 10;
+ aUserItemSz = aSz;
+ }
+ if ( mbSymbols )
+ {
+ Size aSz = maImageScalableFont.GetSizePixel();
+ aUserItemSz.Width() += aSz.Width() + IMGTEXTSPACE;
+ if ( aSz.Height() > aUserItemSz.Height() )
+ aUserItemSz.Height() = aSz.Height();
+ }
+ SetUserItemSize( aUserItemSz );
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ ImplFontNameListData* pData = mpFontList->GetObject( rUDEvt.GetItemId() );
+ const FontInfo& rInfo = pData->maInfo;
+ USHORT nType = pData->mnType;
+ Point aTopLeft = rUDEvt.GetRect().TopLeft();
+ long nX = aTopLeft.X();
+ long nH = rUDEvt.GetRect().GetHeight();
+
+ if ( mbSymbols )
+ {
+ nX += IMGTEXTSPACE;
+ Image* pImg = NULL;
+ if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
+ pImg = &maImagePrinterFont;
+ else if ( nType & FONTLIST_FONTNAMETYPE_SCALABLE )
+ pImg = &maImageScalableFont;
+ else
+ pImg = &maImageBitmapFont;
+
+ if ( pImg )
+ {
+ Point aPos( nX, aTopLeft.Y() + (nH-pImg->GetSizePixel().Height())/2 );
+ rUDEvt.GetDevice()->DrawImage( aPos, *pImg );
+ }
+
+ // X immer um gleiche Breite aendern, auch wenn kein Image ausgegeben.
+ nX += maImagePrinterFont.GetSizePixel().Width();
+ }
+
+ if ( mbWYSIWYG && mpFontList )
+ {
+ nX += IMGTEXTSPACE;
+
+ bool bSymbolFont = (rInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL);
+ // starsymbol is a unicode font, but cannot display its own name
+ const bool bOpenSymbol = rInfo.GetName().EqualsIgnoreCaseAscii( "starsymbol" )
+ || rInfo.GetName().EqualsIgnoreCaseAscii( "opensymbol" );
+ bSymbolFont |= bOpenSymbol;
+
+ if( bSymbolFont )
+ {
+ String aText( rInfo.GetName() );
+ aText.AppendAscii( " " );
+ Point aPos( nX, aTopLeft.Y() + (nH-rUDEvt.GetDevice()->GetTextHeight())/2 );
+ rUDEvt.GetDevice()->DrawText( aPos, aText );
+ nX += rUDEvt.GetDevice()->GetTextWidth( aText );
+ }
+
+ Color aTextColor = rUDEvt.GetDevice()->GetTextColor();
+ Font aOldFont( rUDEvt.GetDevice()->GetFont() );
+ Size aSize( aOldFont.GetSize() );
+ aSize.Height() += EXTRAFONTSIZE;
+ Font aFont( rInfo );
+ aFont.SetSize( aSize );
+ rUDEvt.GetDevice()->SetFont( aFont );
+ rUDEvt.GetDevice()->SetTextColor( aTextColor );
+
+ FontCharMap aFontCharMap;
+ bool bHasCharMap = rUDEvt.GetDevice()->GetFontCharMap( aFontCharMap );
+
+ String aString;
+ if( !bSymbolFont )
+ {
+ // preview the font name
+ aString = rInfo.GetName();
+
+ // reset font if the name cannot be display in the preview font
+ if( STRING_LEN != rUDEvt.GetDevice()->HasGlyphs( aFont, aString ) )
+ rUDEvt.GetDevice()->SetFont( aOldFont );
+ }
+ else if( bHasCharMap )
+ {
+ // use some sample characters available in the font
+ sal_Unicode aText[8];
+
+ // start just above the PUA used by most symbol fonts
+ sal_uInt32 cNewChar = 0xFF00;
+#ifdef QUARTZ
+ // on MacOSX there are too many non-presentable symbols above the codepoint 0x0192
+ if( !bOpenSymbol )
+ cNewChar = 0x0192;
+#endif
+ const int nMaxCount = sizeof(aText)/sizeof(*aText) - 1;
+ int nSkip = aFontCharMap.GetCharCount() / nMaxCount;
+ if( nSkip > 10 )
+ nSkip = 10;
+ else if( nSkip <= 0 )
+ nSkip = 1;
+ for( int i = 0; i < nMaxCount; ++i )
+ {
+ sal_uInt32 cOldChar = cNewChar;
+ for( int j = nSkip; --j >= 0; )
+ cNewChar = aFontCharMap.GetPrevChar( cNewChar );
+ if( cOldChar == cNewChar )
+ break;
+ aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples
+ aText[ i+1 ] = 0;
+ }
+
+ aString = String( aText );
+ }
+ else
+ {
+ const sal_Unicode* pText = aImplSymbolFontText;
+ if( bOpenSymbol )
+ pText = aImplStarSymbolText;
+
+ aString = String( pText );
+ }
+
+ long nTextHeight = rUDEvt.GetDevice()->GetTextHeight();
+ Point aPos( nX, aTopLeft.Y() + (nH-nTextHeight)/2 );
+ rUDEvt.GetDevice()->DrawText( aPos, aString );
+
+ rUDEvt.GetDevice()->SetFont( aOldFont );
+ DrawEntry( rUDEvt, FALSE, FALSE); // draw seperator
+ }
+ else
+ {
+ DrawEntry( rUDEvt, TRUE, TRUE );
+ }
+}
+
+// ===================================================================
+// FontStyleBox
+// ===================================================================
+
+FontStyleBox::FontStyleBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+}
+
+// -------------------------------------------------------------------
+
+FontStyleBox::FontStyleBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( pParent, rResId )
+{
+ aLastStyle = GetText();
+}
+
+// -------------------------------------------------------------------
+
+FontStyleBox::~FontStyleBox()
+{
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::Select()
+{
+ // keep text over fill operation
+ aLastStyle = GetText();
+ ComboBox::Select();
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::LoseFocus()
+{
+ // keep text over fill operation
+ aLastStyle = GetText();
+ ComboBox::LoseFocus();
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::Modify()
+{
+ CharClass aChrCls( ::comphelper::getProcessServiceFactory(),
+ GetSettings().GetLocale() );
+ XubString aStr = GetText();
+ USHORT nEntryCount = GetEntryCount();
+
+ if ( GetEntryPos( aStr ) == COMBOBOX_ENTRY_NOTFOUND )
+ {
+ aChrCls.toUpper( aStr );
+ for ( USHORT i = 0; i < nEntryCount; i++ )
+ {
+ XubString aEntryText = GetEntry( i );
+ aChrCls.toUpper( aEntryText );
+
+ if ( aStr == aEntryText )
+ {
+ SetText( GetEntry( i ) );
+ break;
+ }
+ }
+ }
+
+ ComboBox::Modify();
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::Fill( const XubString& rName, const FontList* pList )
+{
+ // note: this method must call ComboBox::SetText(),
+ // else aLastStyle will overwritten
+ // store prior selection position and clear box
+ XubString aOldText = GetText();
+ USHORT nPos = GetEntryPos( aOldText );
+ Clear();
+
+ // does a font with this name already exist?
+ sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
+ if ( hFontInfo )
+ {
+ XubString aStyleText;
+ FontWeight eLastWeight = WEIGHT_DONTKNOW;
+ FontItalic eLastItalic = ITALIC_NONE;
+ FontWidth eLastWidth = WIDTH_DONTKNOW;
+ BOOL bNormal = FALSE;
+ BOOL bItalic = FALSE;
+ BOOL bBold = FALSE;
+ BOOL bBoldItalic = FALSE;
+ BOOL bInsert = FALSE;
+ FontInfo aInfo;
+ while ( hFontInfo )
+ {
+ aInfo = pList->GetFontInfo( hFontInfo );
+
+ FontWeight eWeight = aInfo.GetWeight();
+ FontItalic eItalic = aInfo.GetItalic();
+ FontWidth eWidth = aInfo.GetWidthType();
+ // Only if the attributes are different, we insert the
+ // Font to avoid double Entries in different languages
+ if ( (eWeight != eLastWeight) || (eItalic != eLastItalic) ||
+ (eWidth != eLastWidth) )
+ {
+ if ( bInsert )
+ InsertEntry( aStyleText );
+
+ if ( eWeight <= WEIGHT_NORMAL )
+ {
+ if ( eItalic != ITALIC_NONE )
+ bItalic = TRUE;
+ else
+ bNormal = TRUE;
+ }
+ else
+ {
+ if ( eItalic != ITALIC_NONE )
+ bBoldItalic = TRUE;
+ else
+ bBold = TRUE;
+ }
+
+ // For wrong StyleNames we replace this with the correct once
+ aStyleText = pList->GetStyleName( aInfo );
+ bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
+ if ( !bInsert )
+ {
+ aStyleText = pList->GetStyleName( eWeight, eItalic );
+ bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
+ }
+
+ eLastWeight = eWeight;
+ eLastItalic = eItalic;
+ eLastWidth = eWidth;
+ }
+ else
+ {
+ if ( bInsert )
+ {
+ // If we have two names for the same attributes
+ // we prefer the translated standard names
+ const XubString& rAttrStyleText = pList->GetStyleName( eWeight, eItalic );
+ if ( rAttrStyleText != aStyleText )
+ {
+ XubString aTempStyleText = pList->GetStyleName( aInfo );
+ if ( rAttrStyleText == aTempStyleText )
+ aStyleText = rAttrStyleText;
+ bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
+ }
+ }
+ }
+
+ if ( !bItalic && (aStyleText == pList->GetItalicStr()) )
+ bItalic = TRUE;
+ else if ( !bBold && (aStyleText == pList->GetBoldStr()) )
+ bBold = TRUE;
+ else if ( !bBoldItalic && (aStyleText == pList->GetBoldItalicStr()) )
+ bBoldItalic = TRUE;
+
+ hFontInfo = pList->GetNextFontInfo( hFontInfo );
+ }
+
+ if ( bInsert )
+ InsertEntry( aStyleText );
+
+ // Bestimmte Styles als Nachbildung
+ if ( bNormal )
+ {
+ if ( !bItalic )
+ InsertEntry( pList->GetItalicStr() );
+ if ( !bBold )
+ InsertEntry( pList->GetBoldStr() );
+ }
+ if ( !bBoldItalic )
+ {
+ if ( bNormal || bItalic || bBold )
+ InsertEntry( pList->GetBoldItalicStr() );
+ }
+ if ( aOldText.Len() )
+ {
+ if ( GetEntryPos( aLastStyle ) != LISTBOX_ENTRY_NOTFOUND )
+ ComboBox::SetText( aLastStyle );
+ else
+ {
+ if ( nPos >= GetEntryCount() )
+ ComboBox::SetText( GetEntry( 0 ) );
+ else
+ ComboBox::SetText( GetEntry( nPos ) );
+ }
+ }
+ }
+ else
+ {
+ // Wenn Font nicht, dann Standard-Styles einfuegen
+ InsertEntry( pList->GetNormalStr() );
+ InsertEntry( pList->GetItalicStr() );
+ InsertEntry( pList->GetBoldStr() );
+ InsertEntry( pList->GetBoldItalicStr() );
+ if ( aOldText.Len() )
+ {
+ if ( nPos > GetEntryCount() )
+ ComboBox::SetText( GetEntry( 0 ) );
+ else
+ ComboBox::SetText( GetEntry( nPos ) );
+ }
+ }
+}
+
+// ===================================================================
+// FontSizeBox
+// ===================================================================
+
+FontSizeBox::FontSizeBox( Window* pParent, WinBits nWinSize ) :
+ MetricBox( pParent, nWinSize )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+FontSizeBox::FontSizeBox( Window* pParent, const ResId& rResId ) :
+ MetricBox( pParent, rResId )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+FontSizeBox::~FontSizeBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::ImplInit()
+{
+ EnableAutocomplete( FALSE );
+
+ bRelativeMode = FALSE;
+ bPtRelative = FALSE;
+ bRelative = FALSE;
+ bStdSize = FALSE;
+ pFontList = NULL;
+
+ SetShowTrailingZeros( FALSE );
+ SetDecimalDigits( 1 );
+ SetMin( 20 );
+ SetMax( 9999 );
+ SetProminentEntryType( PROMINENT_MIDDLE );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::Reformat()
+{
+ FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
+ if ( !bRelativeMode || !aFontSizeNames.IsEmpty() )
+ {
+ long nNewValue = aFontSizeNames.Name2Size( GetText() );
+ if ( nNewValue)
+ {
+ mnLastValue = nNewValue;
+ return;
+ }
+ }
+
+ MetricBox::Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::Modify()
+{
+ MetricBox::Modify();
+
+ if ( bRelativeMode )
+ {
+ XubString aStr = GetText();
+ aStr.EraseLeadingChars();
+
+ BOOL bNewMode = bRelative;
+ BOOL bOldPtRelMode = bPtRelative;
+
+ if ( bRelative )
+ {
+ bPtRelative = FALSE;
+ const xub_Unicode* pStr = aStr.GetBuffer();
+ while ( *pStr )
+ {
+ if ( ((*pStr < '0') || (*pStr > '9')) && (*pStr != '%') )
+ {
+ if ( ('-' == *pStr || '+' == *pStr) && !bPtRelative )
+ bPtRelative = TRUE;
+ else if ( bPtRelative && 'p' == *pStr && 't' == *++pStr )
+ ;
+ else
+ {
+ bNewMode = FALSE;
+ break;
+ }
+ }
+ pStr++;
+ }
+ }
+ else
+ {
+ if ( STRING_NOTFOUND != aStr.Search( '%' ) )
+ {
+ bNewMode = TRUE;
+ bPtRelative = FALSE;
+ }
+
+ if ( '-' == aStr.GetChar( 0 ) || '+' == aStr.GetChar( 0 ) )
+ {
+ bNewMode = TRUE;
+ bPtRelative = TRUE;
+ }
+ }
+
+ if ( bNewMode != bRelative || bPtRelative != bOldPtRelMode )
+ SetRelative( bNewMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::Fill( const FontInfo* pInfo, const FontList* pList )
+{
+ // remember for relative mode
+ pFontList = pList;
+
+ // no font sizes need to be set for relative mode
+ if ( bRelative )
+ return;
+
+ // query font sizes
+ const long* pTempAry;
+ const long* pAry = 0;
+
+ if( pInfo )
+ {
+ aFontInfo = *pInfo;
+ pAry = pList->GetSizeAry( *pInfo );
+ }
+ else
+ {
+ pAry = pList->GetStdSizeAry();
+ }
+
+ // first insert font size names (for simplified/traditional chinese)
+ FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
+ if ( pAry == pList->GetStdSizeAry() )
+ {
+ // for standard sizes we don't need to bother
+ if ( bStdSize && GetEntryCount() && aFontSizeNames.IsEmpty() )
+ return;
+ bStdSize = TRUE;
+ }
+ else
+ bStdSize = FALSE;
+
+ Selection aSelection = GetSelection();
+ XubString aStr = GetText();
+
+ Clear();
+ USHORT nPos = 0;
+
+ if ( !aFontSizeNames.IsEmpty() )
+ {
+ if ( pAry == pList->GetStdSizeAry() )
+ {
+ // for scalable fonts all font size names
+ ULONG nCount = aFontSizeNames.Count();
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ String aSizeName = aFontSizeNames.GetIndexName( i );
+ long nSize = aFontSizeNames.GetIndexSize( i );
+ ComboBox::InsertEntry( aSizeName, nPos );
+ ComboBox::SetEntryData( nPos, (void*)(-nSize) ); // mark as special
+ nPos++;
+ }
+ }
+ else
+ {
+ // for fixed size fonts only selectable font size names
+ pTempAry = pAry;
+ while ( *pTempAry )
+ {
+ String aSizeName = aFontSizeNames.Size2Name( *pTempAry );
+ if ( aSizeName.Len() )
+ {
+ ComboBox::InsertEntry( aSizeName, nPos );
+ ComboBox::SetEntryData( nPos, (void*)(-(*pTempAry)) ); // mark as special
+ nPos++;
+ }
+ pTempAry++;
+ }
+ }
+ }
+
+ // then insert numerical font size values
+ pTempAry = pAry;
+ while ( *pTempAry )
+ {
+ InsertValue( *pTempAry, FUNIT_NONE, nPos );
+ ComboBox::SetEntryData( nPos, (void*)(*pTempAry) );
+ nPos++;
+ pTempAry++;
+ }
+
+ SetText( aStr );
+ SetSelection( aSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::EnableRelativeMode( USHORT nMin, USHORT nMax, USHORT nStep )
+{
+ bRelativeMode = TRUE;
+ nRelMin = nMin;
+ nRelMax = nMax;
+ nRelStep = nStep;
+ SetUnit( FUNIT_POINT );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::EnablePtRelativeMode( short nMin, short nMax, short nStep )
+{
+ bRelativeMode = TRUE;
+ nPtRelMin = nMin;
+ nPtRelMax = nMax;
+ nPtRelStep = nStep;
+ SetUnit( FUNIT_POINT );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::SetRelative( BOOL bNewRelative )
+{
+ if ( bRelativeMode )
+ {
+ Selection aSelection = GetSelection();
+ XubString aStr = GetText();
+ aStr.EraseLeadingChars();
+
+ if ( bNewRelative )
+ {
+ bRelative = TRUE;
+ bStdSize = FALSE;
+
+ if ( bPtRelative )
+ {
+ SetDecimalDigits( 1 );
+ SetMin( nPtRelMin );
+ SetMax( nPtRelMax );
+ SetUnit( FUNIT_POINT );
+
+ Clear();
+
+ short i = nPtRelMin, n = 0;
+ // JP 30.06.98: more than 100 values are not useful
+ while ( i <= nPtRelMax && n++ < 100 )
+ {
+ InsertValue( i );
+ i = i + nPtRelStep;
+ }
+ }
+ else
+ {
+ SetDecimalDigits( 0 );
+ SetMin( nRelMin );
+ SetMax( nRelMax );
+ SetCustomUnitText( '%' );
+ SetUnit( FUNIT_CUSTOM );
+
+ Clear();
+ USHORT i = nRelMin;
+ while ( i <= nRelMax )
+ {
+ InsertValue( i );
+ i = i + nRelStep;
+ }
+ }
+ }
+ else
+ {
+ bRelative = bPtRelative = FALSE;
+ SetDecimalDigits( 1 );
+ SetMin( 20 );
+ SetMax( 9999 );
+ SetUnit( FUNIT_POINT );
+ if ( pFontList )
+ Fill( &aFontInfo, pFontList );
+ }
+
+ SetText( aStr );
+ SetSelection( aSelection );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString FontSizeBox::CreateFieldText( sal_Int64 nValue ) const
+{
+ XubString sRet( MetricBox::CreateFieldText( nValue ) );
+ if ( bRelativeMode && bPtRelative && (0 <= nValue) && sRet.Len() )
+ sRet.Insert( '+', 0 );
+ return sRet;
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
+{
+ if ( !bRelative )
+ {
+ sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
+ FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
+ // conversion loses precision; however font sizes should
+ // never have a problem with that
+ String aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
+ if ( aName.Len() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
+ {
+ mnLastValue = nTempValue;
+ SetText( aName );
+ mnFieldValue = mnLastValue;
+ SetEmptyFieldValueData( FALSE );
+ return;
+ }
+ }
+
+ MetricBox::SetValue( nNewValue, eInUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::SetValue( sal_Int64 nNewValue )
+{
+ SetValue( nNewValue, FUNIT_NONE );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 FontSizeBox::GetValue( USHORT nPos, FieldUnit eOutUnit ) const
+{
+ if ( !bRelative )
+ {
+ sal_Int64 nComboVal = static_cast<sal_Int64>(reinterpret_cast<long>(ComboBox::GetEntryData( nPos )));
+ if ( nComboVal < 0 ) // marked as special?
+ {
+ return MetricField::ConvertValue( -nComboVal, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+ }
+ }
+
+ // do normal font size processing
+ sal_Int64 nRetValue = MetricBox::GetValue( nPos, eOutUnit );
+ return nRetValue;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 FontSizeBox::GetValue( FieldUnit eOutUnit ) const
+{
+ if ( !bRelative )
+ {
+ FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
+ sal_Int64 nValue = aFontSizeNames.Name2Size( GetText() );
+ if ( nValue)
+ return MetricField::ConvertValue( nValue, GetBaseValue(), GetDecimalDigits(), GetUnit(), eOutUnit );
+ }
+
+ return MetricBox::GetValue( eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 FontSizeBox::GetValue() const
+{
+ // implementation not inline, because it is a virtual function
+ return GetValue( FUNIT_NONE );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
+{
+ if ( !bRelative )
+ {
+ sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
+ FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
+ // conversion loses precision
+ // however font sizes should never have a problem with that
+ String aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
+ if ( aName.Len() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
+ {
+ mnLastValue = nTempValue;
+ SetText( aName );
+ return;
+ }
+ }
+
+ MetricBox::SetUserValue( nNewValue, eInUnit );
+}
+
diff --git a/svtools/source/control/ctrlbox.src b/svtools/source/control/ctrlbox.src
new file mode 100755
index 000000000000..95440c905d89
--- /dev/null
+++ b/svtools/source/control/ctrlbox.src
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <svtools/svtools.hrc>
+
+#ifndef IMAGE_STDBTN_COLOR
+#define IMAGE_STDBTN_COLOR Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; }
+#endif
+
+
+IMAGE RID_IMG_SCALABLEFONT
+{
+ ImageBitmap = Bitmap { File = "scalfont.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_SCALABLEFONT_HC
+{
+ ImageBitmap = Bitmap { File = "scalfont_h.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_PRINTERFONT
+{
+ ImageBitmap = Bitmap { File = "prnfont.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_PRINTERFONT_HC
+{
+ ImageBitmap = Bitmap { File = "prnfont_h.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_BITMAPFONT
+{
+ ImageBitmap = Bitmap { File = "bmpfont.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_BITMAPFONT_HC
+{
+ ImageBitmap = Bitmap { File = "bmpfont_h.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+String STR_SVT_AUTOMATIC_COLOR
+{
+ Text [ en-US ] = "Automatic";
+};
+
+/*
+ * ressources for CollatorRessource / CollatorRessourceData resp.
+ */
+
+String STR_SVT_COLLATE_ALPHANUMERIC
+{
+ /* alphanumeric sorting algorithm */
+ Text [ en-US ] = "Alphanumeric";
+};
+
+String STR_SVT_COLLATE_NORMAL
+{
+ /* default or normal sorting algorithm */
+ Text [ en-US ] = "Normal";
+};
+
+String STR_SVT_COLLATE_CHARSET
+{
+ /* default or normal sorting algorithm */
+ Text [ en-US ] = "Character set";
+};
+
+String STR_SVT_COLLATE_DICTIONARY
+{
+ /* german dictionary word order / sorting */
+ Text [ en-US ] = "Dictionary";
+};
+
+String STR_SVT_COLLATE_PINYIN
+{
+ /* chinese sorting algorithm */
+ Text [ en-US ] = "Pinyin";
+};
+
+String STR_SVT_COLLATE_STROKE
+{
+ /* chinese sorting algorithm */
+ Text [ en-US ] = "Stroke";
+};
+
+String STR_SVT_COLLATE_RADICAL
+{
+ /* chinese sorting algorithm */
+ Text [ en-US ] = "Radical";
+};
+
+String STR_SVT_COLLATE_UNICODE
+{
+ /* sorting according to the unicode code point of the character */
+ Text [ en-US ] = "Unicode";
+};
+
+String STR_SVT_COLLATE_ZHUYIN
+{
+ /* chinese sorting algorithm */
+ Text [ en-US ] = "Zhuyin";
+};
+
+String STR_SVT_COLLATE_PHONEBOOK
+{
+ /* phone book sorting algorithm. e.g. German */
+ Text [ en-US ] = "Phone book";
+};
+
+String STR_SVT_COLLATE_PHONETIC_F
+{
+ Text [ en-US ] = "Phonetic (alphanumeric first)";
+};
+
+String STR_SVT_COLLATE_PHONETIC_L
+{
+ Text [ en-US ] = "Phonetic (alphanumeric last)";
+};
+
+String STR_SVT_INDEXENTRY_ALPHANUMERIC
+{
+ /* alphanumeric indexentry algorithm */
+ Text [ en-US ] = "Alphanumeric";
+};
+
+String STR_SVT_INDEXENTRY_DICTIONARY
+{
+ /* korean dictionary indexentry algorithm */
+ Text [ en-US ] = "Dictionary";
+};
+
+String STR_SVT_INDEXENTRY_PINYIN
+{
+ /* chinese sorting algorithm */
+ Text [ en-US ] = "Pinyin";
+};
+
+String STR_SVT_INDEXENTRY_RADICAL
+{
+ /* chinese indexentry algorithm */
+ Text [ en-US ] = "Radical";
+};
+
+String STR_SVT_INDEXENTRY_STROKE
+{
+ /* chinese indexentry algorithm */
+ Text [ en-US ] = "Stroke";
+};
+
+String STR_SVT_INDEXENTRY_ZHUYIN
+{
+ /* chinese indexentry algorithm */
+ Text [ en-US ] = "Zhuyin";
+};
+
+String STR_SVT_INDEXENTRY_PHONETIC_FS
+{
+ Text [ en-US ] = "Phonetic (alphanumeric first, grouped by syllables)";
+};
+
+String STR_SVT_INDEXENTRY_PHONETIC_FC
+{
+ Text [ en-US ] = "Phonetic (alphanumeric first, grouped by consonants)";
+};
+
+String STR_SVT_INDEXENTRY_PHONETIC_LS
+{
+ Text [ en-US ] = "Phonetic (alphanumeric last, grouped by syllables)";
+};
+
+String STR_SVT_INDEXENTRY_PHONETIC_LC
+{
+ Text [ en-US ] = "Phonetic (alphanumeric last, grouped by consonants)";
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/control/ctrldll.cxx b/svtools/source/control/ctrldll.cxx
new file mode 100644
index 000000000000..2f3ff037be31
--- /dev/null
+++ b/svtools/source/control/ctrldll.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_svtools.hxx"
+
+#ifdef WIN
+#include <svwin.h>
+
+#ifndef _SYSDEP_HXX
+#include <sysdep.hxx>
+#endif
+
+// Statische DLL-Verwaltungs-Variablen
+static HINSTANCE hDLLInst = 0; // HANDLE der DLL
+
+/***************************************************************************
+|*
+|* LibMain()
+|*
+|* Beschreibung Initialisierungsfunktion der DLL
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
+{
+#ifndef WNT
+ if ( nHeap )
+ UnlockData( 0 );
+#endif
+
+ hDLLInst = hDLL;
+
+ return TRUE;
+}
+
+/***************************************************************************
+|*
+|* WEP()
+|*
+|* Beschreibung DLL-Deinitialisierung
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+#endif
diff --git a/svtools/source/control/ctrltool.cxx b/svtools/source/control/ctrltool.cxx
new file mode 100755
index 000000000000..bd965aca66a6
--- /dev/null
+++ b/svtools/source/control/ctrltool.cxx
@@ -0,0 +1,1016 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define CTRLTOOL_CXX
+
+#include <string.h>
+
+#ifndef TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#include <i18npool/mslangid.hxx>
+#ifndef _VCL_WINDOW_HXX
+#include <vcl/window.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include <svtools/svtools.hrc>
+#include <svtools/svtdata.hxx>
+#include <ctrltool.hxx>
+
+// =======================================================================
+
+// Standard Fontgroessen fuer scalierbare Fonts
+static long aStdSizeAry[] =
+{
+ 60,
+ 70,
+ 80,
+ 90,
+ 100,
+ 105,
+ 110,
+ 120,
+ 130,
+ 140,
+ 150,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 320,
+ 360,
+ 400,
+ 440,
+ 480,
+ 540,
+ 600,
+ 660,
+ 720,
+ 800,
+ 880,
+ 960,
+ 0
+};
+
+// =======================================================================
+
+// -----------------------------
+// - class ImplFontListFonInfo -
+// -----------------------------
+
+class ImplFontListFontInfo : public FontInfo
+{
+ friend class FontList;
+
+private:
+ OutputDevice* mpDevice;
+ ImplFontListFontInfo* mpNext;
+
+public:
+ ImplFontListFontInfo( const FontInfo& rInfo,
+ OutputDevice* pDev ) :
+ FontInfo( rInfo )
+ {
+ mpDevice = pDev;
+ }
+
+ OutputDevice* GetDevice() const { return mpDevice; }
+};
+
+// ------------------------------
+// - class ImplFontListNameInfo -
+// ------------------------------
+
+class ImplFontListNameInfo
+{
+ friend class FontList;
+
+private:
+ XubString maSearchName;
+ ImplFontListFontInfo* mpFirst;
+ USHORT mnType;
+
+ ImplFontListNameInfo( const XubString& rSearchName ) :
+ maSearchName( rSearchName )
+ {}
+
+ const XubString& GetSearchName() const { return maSearchName; }
+};
+
+// =======================================================================
+
+static StringCompare ImplCompareFontInfo( ImplFontListFontInfo* pInfo1,
+ ImplFontListFontInfo* pInfo2 )
+{
+ if ( pInfo1->GetWeight() < pInfo2->GetWeight() )
+ return COMPARE_LESS;
+ else if ( pInfo1->GetWeight() > pInfo2->GetWeight() )
+ return COMPARE_GREATER;
+
+ if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
+ return COMPARE_LESS;
+ else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
+ return COMPARE_GREATER;
+
+ return pInfo1->GetStyleName().CompareTo( pInfo2->GetStyleName() );
+}
+
+// =======================================================================
+
+static void ImplMakeSearchString( XubString& rStr )
+{
+ rStr.ToLowerAscii();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplMakeSearchStringFromName( XubString& rStr )
+{
+ // check for features before alternate font separator
+ if (rStr.Search(':') < rStr.Search(';'))
+ rStr = rStr.GetToken( 0, ':' );
+ else
+ rStr = rStr.GetToken( 0, ';' );
+ ImplMakeSearchString( rStr );
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontListNameInfo* FontList::ImplFind( const XubString& rSearchName, ULONG* pIndex ) const
+{
+ // Wenn kein Eintrag in der Liste oder der Eintrag groesser ist als
+ // der Letzte, dann hinten dranhaengen. Wir vergleichen erst mit dem
+ // letzten Eintrag, da die Liste von VCL auch sortiert zurueckkommt
+ // und somit die Wahrscheinlichkeit das hinten angehaengt werden muss
+ // sehr gross ist.
+ StringCompare eComp;
+ ULONG nCnt = Count();
+ if ( !nCnt )
+ {
+ if ( pIndex )
+ *pIndex = LIST_APPEND;
+ return NULL;
+ }
+ else
+ {
+ ImplFontListNameInfo* pCmpData = (ImplFontListNameInfo*)List::GetObject( nCnt-1 );
+ eComp = rSearchName.CompareTo( pCmpData->maSearchName );
+ if ( eComp == COMPARE_GREATER )
+ {
+ if ( pIndex )
+ *pIndex = LIST_APPEND;
+ return NULL;
+ }
+ else if ( eComp == COMPARE_EQUAL )
+ return pCmpData;
+ }
+
+ // Fonts in der Liste suchen
+ ImplFontListNameInfo* pCompareData;
+ ImplFontListNameInfo* pFoundData = NULL;
+ ULONG nLow = 0;
+ ULONG nHigh = nCnt-1;
+ ULONG nMid;
+
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ pCompareData = (ImplFontListNameInfo*)List::GetObject( nMid );
+ eComp = rSearchName.CompareTo( pCompareData->maSearchName );
+ if ( eComp == COMPARE_LESS )
+ {
+ if ( !nMid )
+ break;
+ nHigh = nMid-1;
+ }
+ else
+ {
+ if ( eComp == COMPARE_GREATER )
+ nLow = nMid + 1;
+ else
+ {
+ pFoundData = pCompareData;
+ break;
+ }
+ }
+ }
+ while ( nLow <= nHigh );
+
+ if ( pIndex )
+ {
+ eComp = rSearchName.CompareTo( pCompareData->maSearchName );
+ if ( eComp == COMPARE_GREATER )
+ *pIndex = (nMid+1);
+ else
+ *pIndex = nMid;
+ }
+
+ return pFoundData;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontListNameInfo* FontList::ImplFindByName( const XubString& rStr ) const
+{
+ XubString aSearchName = rStr;
+ ImplMakeSearchStringFromName( aSearchName );
+ return ImplFind( aSearchName, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void FontList::ImplInsertFonts( OutputDevice* pDevice, BOOL bAll,
+ BOOL bInsertData )
+{
+ rtl_TextEncoding eSystemEncoding = gsl_getSystemTextEncoding();
+
+ USHORT nType;
+ if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
+ nType = FONTLIST_FONTNAMETYPE_SCREEN;
+ else
+ nType = FONTLIST_FONTNAMETYPE_PRINTER;
+
+ // Alle Fonts vom Device abfragen
+ int n = pDevice->GetDevFontCount();
+ USHORT i;
+ for( i = 0; i < n; i++ )
+ {
+ FontInfo aFontInfo = pDevice->GetDevFont( i );
+
+ // Wenn keine Raster-Schriften angezeigt werden sollen,
+ // dann diese ignorieren
+ if ( !bAll && (aFontInfo.GetType() == TYPE_RASTER) )
+ continue;
+
+ XubString aSearchName = aFontInfo.GetName();
+ ImplFontListNameInfo* pData;
+ ULONG nIndex;
+ ImplMakeSearchString( aSearchName );
+ pData = ImplFind( aSearchName, &nIndex );
+
+ if ( !pData )
+ {
+ if ( bInsertData )
+ {
+ ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
+ pData = new ImplFontListNameInfo( aSearchName );
+ pData->mpFirst = pNewInfo;
+ pNewInfo->mpNext = NULL;
+ pData->mnType = 0;
+ Insert( (void*)pData, nIndex );
+ }
+ }
+ else
+ {
+ if ( bInsertData )
+ {
+ BOOL bInsert = TRUE;
+ ImplFontListFontInfo* pPrev = NULL;
+ ImplFontListFontInfo* pTemp = pData->mpFirst;
+ ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
+ while ( pTemp )
+ {
+ StringCompare eComp = ImplCompareFontInfo( pNewInfo, pTemp );
+ if ( (eComp == COMPARE_LESS) || (eComp == COMPARE_EQUAL) )
+ {
+ if ( eComp == COMPARE_EQUAL )
+ {
+ // Overwrite charset, because charset should match
+ // with the system charset
+ if ( (pTemp->GetCharSet() != eSystemEncoding) &&
+ (pNewInfo->GetCharSet() == eSystemEncoding) )
+ {
+ ImplFontListFontInfo* pTemp2 = pTemp->mpNext;
+ *((FontInfo*)pTemp) = *((FontInfo*)pNewInfo);
+ pTemp->mpNext = pTemp2;
+ }
+ delete pNewInfo;
+ bInsert = FALSE;
+ }
+
+ break;
+ }
+
+ pPrev = pTemp;
+ pTemp = pTemp->mpNext;
+ }
+
+ if ( bInsert )
+ {
+ pNewInfo->mpNext = pTemp;
+ if ( pPrev )
+ pPrev->mpNext = pNewInfo;
+ else
+ pData->mpFirst = pNewInfo;
+ }
+ }
+ }
+
+ if ( pData )
+ {
+ pData->mnType |= nType;
+ if ( aFontInfo.GetType() != TYPE_RASTER )
+ pData->mnType |= FONTLIST_FONTNAMETYPE_SCALABLE;
+ }
+ }
+}
+
+// =======================================================================
+
+FontList::FontList( OutputDevice* pDevice, OutputDevice* pDevice2, BOOL bAll ) :
+ List( 4096, sal::static_int_cast< USHORT >(pDevice->GetDevFontCount()), 32 )
+{
+ // Variablen initialisieren
+ mpDev = pDevice;
+ mpDev2 = pDevice2;
+ mpSizeAry = NULL;
+
+ // Stylenamen festlegen
+ maLight = XubString( SvtResId( STR_SVT_STYLE_LIGHT ) );
+ maLightItalic = XubString( SvtResId( STR_SVT_STYLE_LIGHT_ITALIC ) );
+ maNormal = XubString( SvtResId( STR_SVT_STYLE_NORMAL ) );
+ maNormalItalic = XubString( SvtResId( STR_SVT_STYLE_NORMAL_ITALIC ) );
+ maBold = XubString( SvtResId( STR_SVT_STYLE_BOLD ) );
+ maBoldItalic = XubString( SvtResId( STR_SVT_STYLE_BOLD_ITALIC ) );
+ maBlack = XubString( SvtResId( STR_SVT_STYLE_BLACK ) );
+ maBlackItalic = XubString( SvtResId( STR_SVT_STYLE_BLACK_ITALIC ) );
+
+ ImplInsertFonts( pDevice, bAll, TRUE );
+
+ // Gegebenenfalls muessen wir mit den Bildschirmfonts vergleichen,
+ // damit dort die eigentlich doppelten auf Equal mappen koennen
+ BOOL bCompareWindow = FALSE;
+ if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
+ {
+ bCompareWindow = TRUE;
+ pDevice2 = Application::GetDefaultDevice();
+ }
+
+ if ( pDevice2 &&
+ (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
+ ImplInsertFonts( pDevice2, bAll, !bCompareWindow );
+}
+
+// -----------------------------------------------------------------------
+
+FontList::~FontList()
+{
+ // Gegebenenfalls SizeArray loeschen
+ if ( mpSizeAry )
+ delete[] mpSizeAry;
+
+ // FontInfos loeschen
+ ImplFontListNameInfo* pData = (ImplFontListNameInfo*)First();
+ while ( pData )
+ {
+ ImplFontListFontInfo* pTemp;
+ ImplFontListFontInfo* pInfo = pData->mpFirst;
+ while ( pInfo )
+ {
+ pTemp = pInfo->mpNext;
+ delete pInfo;
+ pInfo = pTemp;
+ }
+ ImplFontListNameInfo* pNext = (ImplFontListNameInfo*)Next();
+ delete pData;
+ pData = pNext;
+ }
+}
+// -----------------------------------------------------------------------
+FontList* FontList::Clone() const
+{
+ FontList* pReturn = new FontList(
+ mpDev, mpDev2, GetFontNameCount() == mpDev->GetDevFontCount());
+ return pReturn;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& FontList::GetStyleName( FontWeight eWeight, FontItalic eItalic ) const
+{
+ if ( eWeight > WEIGHT_BOLD )
+ {
+ if ( eItalic > ITALIC_NONE )
+ return maBlackItalic;
+ else
+ return maBlack;
+ }
+ else if ( eWeight > WEIGHT_MEDIUM )
+ {
+ if ( eItalic > ITALIC_NONE )
+ return maBoldItalic;
+ else
+ return maBold;
+ }
+ else if ( eWeight > WEIGHT_LIGHT )
+ {
+ if ( eItalic > ITALIC_NONE )
+ return maNormalItalic;
+ else
+ return maNormal;
+ }
+ else if ( eWeight != WEIGHT_DONTKNOW )
+ {
+ if ( eItalic > ITALIC_NONE )
+ return maLightItalic;
+ else
+ return maLight;
+ }
+ else
+ {
+ if ( eItalic > ITALIC_NONE )
+ return maNormalItalic;
+ else
+ return maNormal;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString FontList::GetStyleName( const FontInfo& rInfo ) const
+{
+ XubString aStyleName = rInfo.GetStyleName();
+ FontWeight eWeight = rInfo.GetWeight();
+ FontItalic eItalic = rInfo.GetItalic();
+
+ // Nur wenn kein StyleName gesetzt ist, geben wir einen syntetischen
+ // Namen zurueck
+ if ( !aStyleName.Len() )
+ aStyleName = GetStyleName( eWeight, eItalic );
+ else
+ {
+ // Translate StyleName to localized name
+ XubString aCompareStyleName = aStyleName;
+ aCompareStyleName.ToLowerAscii();
+ aCompareStyleName.EraseAllChars( ' ' );
+ if ( aCompareStyleName.EqualsAscii( "bold" ) )
+ aStyleName = maBold;
+ else if ( aCompareStyleName.EqualsAscii( "bolditalic" ) )
+ aStyleName = maBoldItalic;
+ else if ( aCompareStyleName.EqualsAscii( "italic" ) )
+ aStyleName = maNormalItalic;
+ else if ( aCompareStyleName.EqualsAscii( "standard" ) )
+ aStyleName = maNormal;
+ else if ( aCompareStyleName.EqualsAscii( "regular" ) )
+ aStyleName = maNormal;
+ else if ( aCompareStyleName.EqualsAscii( "medium" ) )
+ aStyleName = maNormal;
+ else if ( aCompareStyleName.EqualsAscii( "light" ) )
+ aStyleName = maLight;
+ else if ( aCompareStyleName.EqualsAscii( "lightitalic" ) )
+ aStyleName = maLightItalic;
+ else if ( aCompareStyleName.EqualsAscii( "black" ) )
+ aStyleName = maBlack;
+ else if ( aCompareStyleName.EqualsAscii( "blackitalic" ) )
+ aStyleName = maBlackItalic;
+
+ // fix up StyleName, because the PS Printer driver from
+ // W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
+ // for Helvetica)
+ if ( eItalic > ITALIC_NONE )
+ {
+ if ( (aStyleName == maNormal) ||
+ (aStyleName == maBold) ||
+ (aStyleName == maLight) ||
+ (aStyleName == maBlack) )
+ aStyleName = GetStyleName( eWeight, eItalic );
+ }
+ }
+
+ return aStyleName;
+}
+
+// -----------------------------------------------------------------------
+
+XubString FontList::GetFontMapText( const FontInfo& rInfo ) const
+{
+ if ( !rInfo.GetName().Len() )
+ {
+ XubString aEmptryStr;
+ return aEmptryStr;
+ }
+
+ // Search Fontname
+ ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
+ if ( !pData )
+ {
+ if ( !maMapNotAvailable.Len() )
+ ((FontList*)this)->maMapNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_NOTAVAILABLE ) );
+ return maMapNotAvailable;
+ }
+
+ // search for synthetic style
+ USHORT nType = pData->mnType;
+ const XubString& rStyleName = rInfo.GetStyleName();
+ if ( rStyleName.Len() )
+ {
+ BOOL bNotSynthetic = FALSE;
+ BOOL bNoneAvailable = FALSE;
+ FontWeight eWeight = rInfo.GetWeight();
+ FontItalic eItalic = rInfo.GetItalic();
+ ImplFontListFontInfo* pFontInfo = pData->mpFirst;
+ while ( pFontInfo )
+ {
+ if ( (eWeight == pFontInfo->GetWeight()) &&
+ (eItalic == pFontInfo->GetItalic()) )
+ {
+ bNotSynthetic = TRUE;
+ break;
+ }
+
+ pFontInfo = pFontInfo->mpNext;
+ }
+
+ if ( bNoneAvailable )
+ {
+ XubString aEmptryStr;
+ return aEmptryStr;
+ }
+ else if ( !bNotSynthetic )
+ {
+ if ( !maMapStyleNotAvailable.Len() )
+ ((FontList*)this)->maMapStyleNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_STYLENOTAVAILABLE ) );
+ return maMapStyleNotAvailable;
+ }
+ }
+
+ /* Size not available not implemented yet
+ if ( !(nType & FONTLIST_FONTNAMETYPE_SCALABLE) )
+ {
+ ...
+ {
+ if ( !maMapSizeNotAvailable.Len() )
+ ((FontList*)this)->maMapSizeNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_SIZENOTAVAILABLE ) );
+ return maMapSizeNotAvailable;
+ }
+ }
+ */
+
+ // Only Printer-Font?
+ if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
+ {
+ if ( !maMapPrinterOnly.Len() )
+ ((FontList*)this)->maMapPrinterOnly = XubString( SvtResId( STR_SVT_FONTMAP_PRINTERONLY ) );
+ return maMapPrinterOnly;
+ }
+ // Only Screen-Font?
+ else if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_SCREEN
+ && rInfo.GetType() == TYPE_RASTER )
+ {
+ if ( !maMapScreenOnly.Len() )
+ ((FontList*)this)->maMapScreenOnly = XubString( SvtResId( STR_SVT_FONTMAP_SCREENONLY ) );
+ return maMapScreenOnly;
+ }
+ else
+ {
+ if ( !maMapBoth.Len() )
+ ((FontList*)this)->maMapBoth = XubString( SvtResId( STR_SVT_FONTMAP_BOTH ) );
+ return maMapBoth;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT FontList::GetFontNameType( const XubString& rFontName ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rFontName );
+ if ( pData )
+ return pData->mnType;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo FontList::Get( const XubString& rName, const XubString& rStyleName ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rName );
+ ImplFontListFontInfo* pFontInfo = NULL;
+ ImplFontListFontInfo* pFontNameInfo = NULL;
+ if ( pData )
+ {
+ ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
+ pFontNameInfo = pSearchInfo;
+ pSearchInfo = pData->mpFirst;
+ while ( pSearchInfo )
+ {
+ if ( rStyleName.EqualsIgnoreCaseAscii( GetStyleName( *pSearchInfo ) ) )
+ {
+ pFontInfo = pSearchInfo;
+ break;
+ }
+
+ pSearchInfo = pSearchInfo->mpNext;
+ }
+ }
+
+ // Konnten die Daten nicht gefunden werden, dann muessen bestimmte
+ // Attribute nachgebildet werden
+ FontInfo aInfo;
+ if ( !pFontInfo )
+ {
+ if ( pFontNameInfo )
+ aInfo = *pFontNameInfo;
+
+ if ( rStyleName == maNormal )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_NORMAL );
+ }
+ else if ( rStyleName == maNormalItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_NORMAL );
+ }
+ else if ( rStyleName == maBold )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_BOLD );
+ }
+ else if ( rStyleName == maBoldItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_BOLD );
+ }
+ else if ( rStyleName == maLight )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_LIGHT );
+ }
+ else if ( rStyleName == maLightItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_LIGHT );
+ }
+ else if ( rStyleName == maBlack )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_BLACK );
+ }
+ else if ( rStyleName == maBlackItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_BLACK );
+ }
+ else
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_DONTKNOW );
+ }
+ }
+ else
+ aInfo = *pFontInfo;
+
+ // set Fontname to keep FontAlias
+ aInfo.SetName( rName );
+ aInfo.SetStyleName( rStyleName );
+
+ return aInfo;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo FontList::Get( const XubString& rName,
+ FontWeight eWeight, FontItalic eItalic ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rName );
+ ImplFontListFontInfo* pFontInfo = NULL;
+ ImplFontListFontInfo* pFontNameInfo = NULL;
+ if ( pData )
+ {
+ ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
+ pFontNameInfo = pSearchInfo;
+ while ( pSearchInfo )
+ {
+ if ( (eWeight == pSearchInfo->GetWeight()) &&
+ (eItalic == pSearchInfo->GetItalic()) )
+ {
+ pFontInfo = pSearchInfo;
+ break;
+ }
+
+ pSearchInfo = pSearchInfo->mpNext;
+ }
+ }
+
+ // Konnten die Daten nicht gefunden werden, dann muessen bestimmte
+ // Attribute nachgebildet werden
+ FontInfo aInfo;
+ if ( !pFontInfo )
+ {
+ // Falls der Fontname stimmt, uebernehmen wir soviel wie moeglich
+ if ( pFontNameInfo )
+ {
+ aInfo = *pFontNameInfo;
+ aInfo.SetStyleName( XubString() );
+ }
+
+ aInfo.SetWeight( eWeight );
+ aInfo.SetItalic( eItalic );
+ }
+ else
+ aInfo = *pFontInfo;
+
+ // set Fontname to keep FontAlias
+ aInfo.SetName( rName );
+
+ return aInfo;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontList::IsAvailable( const XubString& rName ) const
+{
+ return (ImplFindByName( rName ) != 0);
+}
+
+// -----------------------------------------------------------------------
+
+const FontInfo& FontList::GetFontName( USHORT nFont ) const
+{
+ DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
+
+ ImplFontListNameInfo* pData = (ImplFontListNameInfo*)List::GetObject( nFont );
+ return *(pData->mpFirst);
+}
+
+// -----------------------------------------------------------------------
+
+USHORT FontList::GetFontNameType( USHORT nFont ) const
+{
+ DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontNameType(): nFont >= Count" );
+
+ ImplFontListNameInfo* pData = (ImplFontListNameInfo*)List::GetObject( nFont );
+ return pData->mnType;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Handle FontList::GetFirstFontInfo( const XubString& rName ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rName );
+ if ( !pData )
+ return (sal_Handle)NULL;
+ else
+ return (sal_Handle)pData->mpFirst;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Handle FontList::GetNextFontInfo( sal_Handle hFontInfo ) const
+{
+ ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
+ return (sal_Handle)(pInfo->mpNext);
+}
+
+// -----------------------------------------------------------------------
+
+const FontInfo& FontList::GetFontInfo( sal_Handle hFontInfo ) const
+{
+ ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
+ return *pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+const long* FontList::GetSizeAry( const FontInfo& rInfo ) const
+{
+ // Size-Array vorher loeschen
+ if ( mpSizeAry )
+ {
+ delete[] ((FontList*)this)->mpSizeAry;
+ ((FontList*)this)->mpSizeAry = NULL;
+ }
+
+ // Falls kein Name, dann Standardgroessen
+ if ( !rInfo.GetName().Len() )
+ return aStdSizeAry;
+
+ // Zuerst nach dem Fontnamen suchen um das Device dann von dem
+ // entsprechenden Font zu nehmen
+ OutputDevice* pDevice = mpDev;
+ ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
+ if ( pData )
+ pDevice = pData->mpFirst->GetDevice();
+
+ int nDevSizeCount = pDevice->GetDevFontSizeCount( rInfo );
+ if ( !nDevSizeCount ||
+ (pDevice->GetDevFontSize( rInfo, 0 ).Height() == 0) )
+ return aStdSizeAry;
+
+ MapMode aOldMapMode = pDevice->GetMapMode();
+ MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
+ pDevice->SetMapMode( aMap );
+
+ USHORT i;
+ USHORT nRealCount = 0;
+ long nOldHeight = 0;
+ ((FontList*)this)->mpSizeAry = new long[nDevSizeCount+1];
+ for ( i = 0; i < nDevSizeCount; i++ )
+ {
+ Size aSize = pDevice->GetDevFontSize( rInfo, i );
+ if ( aSize.Height() != nOldHeight )
+ {
+ nOldHeight = aSize.Height();
+ ((FontList*)this)->mpSizeAry[nRealCount] = nOldHeight;
+ nRealCount++;
+ }
+ }
+ ((FontList*)this)->mpSizeAry[nRealCount] = 0;
+
+ pDevice->SetMapMode( aOldMapMode );
+ return mpSizeAry;
+}
+
+// -----------------------------------------------------------------------
+
+const long* FontList::GetStdSizeAry()
+{
+ return aStdSizeAry;
+}
+
+// =======================================================================
+
+// ---------------------------------
+// - FontSizeNames & FsizeNameItem -
+// ---------------------------------
+
+struct ImplFSNameItem
+{
+ long mnSize;
+ const char* mszUtf8Name;
+};
+
+//------------------------------------------------------------------------
+
+static ImplFSNameItem aImplSimplifiedChinese[] =
+{
+ { 50, "\xe5\x85\xab\xe5\x8f\xb7" },
+ { 55, "\xe4\xb8\x83\xe5\x8f\xb7" },
+ { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
+ { 75, "\xe5\x85\xad\xe5\x8f\xb7" },
+ { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
+ { 105, "\xe4\xba\x94\xe5\x8f\xb7" },
+ { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
+ { 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
+ { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
+ { 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
+ { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
+ { 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
+ { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
+ { 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
+ { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
+ { 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
+};
+
+// -----------------------------------------------------------------------
+
+#if 0 // #i89077# disabled by popular request
+static ImplFSNameItem aImplTraditionalChinese[] =
+{
+ { 50, "\xe5\x85\xab\xe8\x99\x9f" },
+ { 55, "\xe4\xb8\x83\xe8\x99\x9f" },
+ { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
+ { 75, "\xe5\x85\xad\xe8\x99\x9f" },
+ { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
+ { 105, "\xe4\xba\x94\xe8\x99\x9f" },
+ { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
+ { 140, "\xe5\x9b\x9b\xe8\x99\x9f" },
+ { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
+ { 160, "\xe4\xb8\x89\xe8\x99\x9f" },
+ { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
+ { 220, "\xe4\xba\x8c\xe8\x99\x9f" },
+ { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
+ { 260, "\xe4\xb8\x80\xe8\x99\x9f" },
+ { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
+ { 420, "\xe5\x88\x9d\xe8\x99\x9f" }
+};
+#endif
+
+//------------------------------------------------------------------------
+
+FontSizeNames::FontSizeNames( LanguageType eLanguage )
+{
+ if ( eLanguage == LANGUAGE_DONTKNOW )
+ eLanguage = Application::GetSettings().GetUILanguage();
+ if ( eLanguage == LANGUAGE_SYSTEM )
+ eLanguage = MsLangId::getSystemUILanguage();
+
+ switch( eLanguage )
+ {
+ case LANGUAGE_CHINESE:
+ case LANGUAGE_CHINESE_SIMPLIFIED:
+ mpArray = aImplSimplifiedChinese;
+ mnElem = sizeof(aImplSimplifiedChinese) / sizeof(aImplSimplifiedChinese[0]);
+ break;
+
+#if 0 // #i89077# disabled by popular request
+ case LANGUAGE_CHINESE_HONGKONG:
+ case LANGUAGE_CHINESE_SINGAPORE:
+ case LANGUAGE_CHINESE_MACAU:
+ case LANGUAGE_CHINESE_TRADITIONAL:
+ mpArray = aImplTraditionalChinese;
+ mnElem = sizeof(aImplTraditionalChinese) / sizeof(aImplTraditionalChinese[0]);
+ break;
+#endif
+
+ default:
+ mpArray = NULL;
+ mnElem = 0;
+ break;
+ };
+}
+
+//------------------------------------------------------------------------
+
+long FontSizeNames::Name2Size( const String& rName ) const
+{
+ if ( mnElem )
+ {
+ ByteString aName( rName, RTL_TEXTENCODING_UTF8 );
+
+ // linear search is sufficient for this rare case
+ for( long i = mnElem; --i >= 0; )
+ if ( aName == mpArray[i].mszUtf8Name )
+ return mpArray[i].mnSize;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+String FontSizeNames::Size2Name( long nValue ) const
+{
+ String aStr;
+
+ // binary search
+ for( long lower = 0, upper = mnElem - 1; lower <= upper; )
+ {
+ long mid = (upper + lower) >> 1;
+ if ( nValue == mpArray[mid].mnSize )
+ {
+ aStr = String( mpArray[mid].mszUtf8Name, RTL_TEXTENCODING_UTF8 );
+ break;
+ }
+ else if ( nValue < mpArray[mid].mnSize )
+ upper = mid - 1;
+ else /* ( nValue > mpArray[mid].mnSize ) */
+ lower = mid + 1;
+ }
+
+ return aStr;
+}
+
+//------------------------------------------------------------------------
+
+String FontSizeNames::GetIndexName( ULONG nIndex ) const
+{
+ String aStr;
+
+ if ( nIndex < mnElem )
+ aStr = String( mpArray[nIndex].mszUtf8Name, RTL_TEXTENCODING_UTF8 );
+
+ return aStr;
+}
+
+//------------------------------------------------------------------------
+
+long FontSizeNames::GetIndexSize( ULONG nIndex ) const
+{
+ if ( nIndex >= mnElem )
+ return 0;
+ return mpArray[nIndex].mnSize;
+}
diff --git a/svtools/source/control/ctrltool.src b/svtools/source/control/ctrltool.src
new file mode 100755
index 000000000000..72420af4908e
--- /dev/null
+++ b/svtools/source/control/ctrltool.src
@@ -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.
+ *
+ ************************************************************************/
+#include <svtools/svtools.hrc>
+
+String STR_SVT_STYLE_LIGHT
+{
+ Text [ en-US ] = "Light" ;
+};
+
+String STR_SVT_STYLE_LIGHT_ITALIC
+{
+ Text [ en-US ] = "Light Italic" ;
+};
+
+String STR_SVT_STYLE_NORMAL
+{
+ Text [ en-US ] = "Regular" ;
+};
+
+String STR_SVT_STYLE_NORMAL_ITALIC
+{
+ Text [ en-US ] = "Italic" ;
+};
+
+String STR_SVT_STYLE_BOLD
+{
+ Text [ en-US ] = "Bold" ;
+};
+
+String STR_SVT_STYLE_BOLD_ITALIC
+{
+ Text [ en-US ] = "Bold Italic" ;
+};
+
+String STR_SVT_STYLE_BLACK
+{
+ Text [ en-US ] = "Black" ;
+};
+
+String STR_SVT_STYLE_BLACK_ITALIC
+{
+ Text [ en-US ] = "Black Italic" ;
+};
+
+/*
+Finnische Texte:
+ "Light",
+ "Light Kursivoitu",
+ "Normaali",
+ "Kursivoitu",
+ "Lihavoitu",
+ "Lihavoitu Kursivoitu",
+ "Black",
+ "Black Kursivoitu"
+*/
+
+String STR_SVT_FONTMAP_BOTH
+{
+ Text [ en-US ] = "The same font will be used on both your printer and your screen." ;
+};
+
+String STR_SVT_FONTMAP_PRINTERONLY
+{
+ Text [ en-US ] = "This is a printer font. The screen image may differ." ;
+};
+
+String STR_SVT_FONTMAP_SCREENONLY
+{
+ Text [ en-US ] = "This is a screen font. The printer image may differ." ;
+};
+
+String STR_SVT_FONTMAP_SIZENOTAVAILABLE
+{
+ Text [ en-US ] = "This font size has not been installed. The closest available size will be used.";
+};
+
+String STR_SVT_FONTMAP_STYLENOTAVAILABLE
+{
+ Text [ en-US ] = "This font style will be simulated or the closest matching style will be used.";
+};
+
+String STR_SVT_FONTMAP_NOTAVAILABLE
+{
+ Text [ en-US ] = "This font has not been installed. The closest available font will be used.";
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/control/filectrl.cxx b/svtools/source/control/filectrl.cxx
new file mode 100644
index 000000000000..14c0478f5327
--- /dev/null
+++ b/svtools/source/control/filectrl.cxx
@@ -0,0 +1,236 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SV_FIELCTRL_CXX
+#include <tools/urlobj.hxx>
+#include <svtools/svtdata.hxx>
+#include <filectrl.hxx>
+#ifndef _SV_FILECTRL_HRC
+#include <filectrl.hrc>
+#endif
+
+#ifndef GCC
+#endif
+
+// =======================================================================
+
+FileControl::FileControl( Window* pParent, WinBits nStyle, FileControlMode nFlags ) :
+ Window( pParent, nStyle|WB_DIALOGCONTROL ),
+ maEdit( this, (nStyle&(~WB_BORDER))|WB_NOTABSTOP ),
+ maButton( this, (nStyle&(~WB_BORDER))|WB_NOLIGHTBORDER|WB_NOPOINTERFOCUS|WB_NOTABSTOP ),
+ maButtonText( SvtResId( STR_FILECTRL_BUTTONTEXT ) ),
+ mnFlags( nFlags ),
+ mnInternalFlags( FILECTRL_ORIGINALBUTTONTEXT )
+{
+ maButton.SetClickHdl( LINK( this, FileControl, ButtonHdl ) );
+ mbOpenDlg = TRUE;
+
+ maButton.Show();
+ maEdit.Show();
+
+ SetCompoundControl( TRUE );
+
+ SetStyle( ImplInitStyle( GetStyle() ) );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FileControl::ImplInitStyle( WinBits nStyle )
+{
+ if ( !( nStyle & WB_NOTABSTOP ) )
+ {
+ maEdit.SetStyle( (maEdit.GetStyle()|WB_TABSTOP)&(~WB_NOTABSTOP) );
+ maButton.SetStyle( (maButton.GetStyle()|WB_TABSTOP)&(~WB_NOTABSTOP) );
+ }
+ else
+ {
+ maEdit.SetStyle( (maEdit.GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
+ maButton.SetStyle( (maButton.GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
+ }
+
+ const WinBits nAlignmentStyle = ( WB_TOP | WB_VCENTER | WB_BOTTOM );
+ maEdit.SetStyle( ( maEdit.GetStyle() & ~nAlignmentStyle ) | ( nStyle & nAlignmentStyle ) );
+
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+
+ if ( !(nStyle & WB_NOBORDER ) )
+ nStyle |= WB_BORDER;
+
+ nStyle &= ~WB_TABSTOP;
+
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+FileControl::~FileControl()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::SetText( const XubString& rStr )
+{
+ maEdit.SetText( rStr );
+ if ( mnFlags & FILECTRL_RESIZEBUTTONBYPATHLEN )
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+XubString FileControl::GetText() const
+{
+ return maEdit.GetText();
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_ENABLE )
+ {
+ maEdit.Enable( IsEnabled() );
+ maButton.Enable( IsEnabled() );
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ GetEdit().SetZoom( GetZoom() );
+ GetButton().SetZoom( GetZoom() );
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ GetEdit().SetControlFont( GetControlFont() );
+ // Fuer den Button nur die Hoehe uebernehmen, weil in
+ // HTML immer Courier eingestellt wird.
+ Font aFont = GetButton().GetControlFont();
+ aFont.SetSize( GetControlFont().GetSize() );
+ GetButton().SetControlFont( aFont );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ GetEdit().SetControlForeground( GetControlForeground() );
+ GetButton().SetControlForeground( GetControlForeground() );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ GetEdit().SetControlBackground( GetControlBackground() );
+ GetButton().SetControlBackground( GetControlBackground() );
+ }
+ Window::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::Resize()
+{
+ static long ButtonBorder = 10;
+
+ if( mnInternalFlags & FILECTRL_INRESIZE )
+ return;
+ mnInternalFlags |= FILECTRL_INRESIZE;//InResize = TRUE
+
+ Size aOutSz = GetOutputSizePixel();
+ long nButtonTextWidth = maButton.GetTextWidth( maButtonText );
+ if ( ((mnInternalFlags & FILECTRL_ORIGINALBUTTONTEXT) == 0) ||
+ ( nButtonTextWidth < aOutSz.Width()/3 &&
+ ( mnFlags & FILECTRL_RESIZEBUTTONBYPATHLEN
+ ? ( maEdit.GetTextWidth( maEdit.GetText() )
+ <= aOutSz.Width() - nButtonTextWidth - ButtonBorder )
+ : TRUE ) )
+ )
+ {
+ maButton.SetText( maButtonText );
+ }
+ else
+ {
+ XubString aSmallText( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
+ maButton.SetText( aSmallText );
+ nButtonTextWidth = maButton.GetTextWidth( aSmallText );
+ }
+
+ long nButtonWidth = nButtonTextWidth+ButtonBorder;
+ maEdit.SetPosSizePixel( 0, 0, aOutSz.Width()-nButtonWidth, aOutSz.Height() );
+ maButton.SetPosSizePixel( aOutSz.Width()-nButtonWidth, 0, nButtonWidth, aOutSz.Height() );
+
+ mnInternalFlags &= ~FILECTRL_INRESIZE; //InResize = FALSE
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FileControl, ButtonHdl, PushButton*, EMPTYARG )
+{
+ ImplBrowseFile( );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::GetFocus()
+{
+ maEdit.GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ WinBits nOldEditStyle = GetEdit().GetStyle();
+ if ( GetStyle() & WB_BORDER )
+ GetEdit().SetStyle( nOldEditStyle|WB_BORDER );
+ GetEdit().Draw( pDev, rPos, rSize, nFlags );
+ if ( GetStyle() & WB_BORDER )
+ GetEdit().SetStyle( nOldEditStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::SetButtonText( const XubString& rStr )
+{
+ mnInternalFlags &= ~FILECTRL_ORIGINALBUTTONTEXT;
+ maButtonText = rStr;
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::ResetButtonText()
+{
+ mnInternalFlags |= FILECTRL_ORIGINALBUTTONTEXT;
+ maButtonText = XubString( SvtResId( STR_FILECTRL_BUTTONTEXT ) );
+ Resize();
+}
+
+
diff --git a/svtools/source/control/filectrl.src b/svtools/source/control/filectrl.src
new file mode 100644
index 000000000000..dc8bbb5905d6
--- /dev/null
+++ b/svtools/source/control/filectrl.src
@@ -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 "filectrl.hrc"
+String STR_FILECTRL_BUTTONTEXT
+{
+ Text [ en-US ] = "Browse..." ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/control/filectrl2.cxx b/svtools/source/control/filectrl2.cxx
new file mode 100644
index 000000000000..2a75c5d3d7e8
--- /dev/null
+++ b/svtools/source/control/filectrl2.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+// this file contains code from filectrl.cxx which needs to be compiled with enabled exception hanling
+#include <filectrl.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <vcl/unohelp.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/file.h>
+#include <vcl/stdtext.hxx>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui;
+
+void FileControl::ImplBrowseFile( )
+{
+ try
+ {
+ XubString aNewText;
+
+ const ::rtl::OUString sServiceName = ::rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.FilePicker" );
+
+ Reference< XMultiServiceFactory > xMSF = vcl::unohelper::GetMultiServiceFactory();
+ Reference < dialogs::XFilePicker > xFilePicker( xMSF->createInstance( sServiceName ), UNO_QUERY );
+ if ( xFilePicker.is() )
+ {
+ // transform the system notation text into a file URL
+ ::rtl::OUString sSystemNotation = GetText(), sFileURL;
+ oslFileError nError = osl_getFileURLFromSystemPath( sSystemNotation.pData, &sFileURL.pData );
+ if ( nError == osl_File_E_INVAL )
+ sFileURL = GetText(); // #97709# Maybe URL is already a file URL...
+
+ //#90430# Check if URL is really a file URL
+ ::rtl::OUString aTmp;
+ if ( osl_getSystemPathFromFileURL( sFileURL.pData, &aTmp.pData ) == osl_File_E_None )
+ {
+ // initially set this directory
+ xFilePicker->setDisplayDirectory( sFileURL );
+ }
+
+ if ( xFilePicker.is() && xFilePicker->execute() )
+ {
+ Sequence < rtl::OUString > aPathSeq = xFilePicker->getFiles();
+
+ if ( aPathSeq.getLength() )
+ {
+ aNewText = aPathSeq[0];
+ INetURLObject aObj( aNewText );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ aNewText = aObj.PathToFileName();
+ SetText( aNewText );
+ maEdit.GetModifyHdl().Call( &maEdit );
+ }
+ }
+ }
+ else
+ ShowServiceNotAvailableError( this, sServiceName, sal_True );
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "FileControl::ImplBrowseFile: caught an exception while executing the file picker!" );
+ }
+}
+
diff --git a/svtools/source/control/fileurlbox.cxx b/svtools/source/control/fileurlbox.cxx
new file mode 100644
index 000000000000..476b2864a117
--- /dev/null
+++ b/svtools/source/control/fileurlbox.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/fileurlbox.hxx>
+#include <osl/file.h>
+#include "svl/filenotation.hxx"
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ //=====================================================================
+ //= FileURLBox
+ //=====================================================================
+ //---------------------------------------------------------------------
+ FileURLBox::FileURLBox(Window* _pParent)
+ :SvtURLBox(_pParent, INET_PROT_FILE)
+ {
+ DisableHistory();
+ }
+
+ //---------------------------------------------------------------------
+ FileURLBox::FileURLBox( Window* _pParent, WinBits _nStyle )
+ :SvtURLBox( _pParent, _nStyle, INET_PROT_FILE )
+ {
+ DisableHistory();
+ }
+
+ //---------------------------------------------------------------------
+ FileURLBox::FileURLBox(Window* _pParent, const ResId& _rId)
+ :SvtURLBox(_pParent, _rId, INET_PROT_FILE)
+ {
+ DisableHistory();
+ }
+
+ //---------------------------------------------------------------------
+ void FileURLBox::DisplayURL( const String& _rURL )
+ {
+ String sOldText = GetText();
+
+ OFileNotation aTransformer( _rURL, OFileNotation::N_URL );
+ String sNewText = aTransformer.get( OFileNotation::N_SYSTEM );
+ SetText( sNewText );
+
+ if ( sOldText != sNewText )
+ Modify();
+
+ UpdatePickList();
+ }
+
+ //---------------------------------------------------------------------
+ long FileURLBox::PreNotify( NotifyEvent& _rNEvt )
+ {
+ switch ( _rNEvt.GetType() )
+ {
+ case EVENT_KEYINPUT:
+ if ( ( GetSubEdit() == _rNEvt.GetWindow() )
+ && ( KEY_RETURN == _rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
+ && ( IsInDropDown() )
+ )
+ m_sPreservedText = GetURL();
+ break;
+
+ case EVENT_LOSEFOCUS:
+ if ( IsWindowOrChild( _rNEvt.GetWindow() ) )
+ DisplayURL( GetText() );
+ break;
+ }
+
+ return SvtURLBox::PreNotify(_rNEvt);
+ }
+
+ //---------------------------------------------------------------------
+ long FileURLBox::Notify( NotifyEvent& _rNEvt )
+ {
+ switch ( _rNEvt.GetType() )
+ {
+ case EVENT_KEYINPUT:
+ if ( ( GetSubEdit() == _rNEvt.GetWindow() )
+ && ( KEY_RETURN == _rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
+ && ( IsInDropDown() )
+ )
+ {
+ long nReturn = SvtURLBox::Notify(_rNEvt);
+ DisplayURL( m_sPreservedText );
+ return nReturn;
+ }
+ break;
+ }
+
+ return SvtURLBox::Notify(_rNEvt);
+ }
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
+
diff --git a/svtools/source/control/fixedhyper.cxx b/svtools/source/control/fixedhyper.cxx
new file mode 100644
index 000000000000..a8877d240d4e
--- /dev/null
+++ b/svtools/source/control/fixedhyper.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/fixedhyper.hxx>
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+// class FixedHyperlink --------------------------------------------------
+
+FixedHyperlink::FixedHyperlink( Window* pParent, const ResId& rResId ) :
+ ::toolkit::FixedHyperlinkBase( pParent, rResId ),
+ m_nTextLen(0)
+{
+ Initialize();
+}
+
+FixedHyperlink::FixedHyperlink( Window* pParent, WinBits nWinStyle ) :
+ ::toolkit::FixedHyperlinkBase( pParent, nWinStyle ),
+ m_nTextLen(0)
+{
+ Initialize();
+}
+
+FixedHyperlink::~FixedHyperlink()
+{
+}
+
+void FixedHyperlink::Initialize()
+{
+ // saves the old pointer
+ m_aOldPointer = GetPointer();
+ // changes the font
+ Font aFont = GetControlFont( );
+ // to underline
+ aFont.SetUnderline( UNDERLINE_SINGLE );
+ SetControlFont( aFont );
+ // changes the color to light blue
+ SetTextColor( Color( COL_LIGHTBLUE ) );
+ // calculates text len
+ m_nTextLen = GetCtrlTextWidth( GetText() );
+}
+
+void FixedHyperlink::MouseMove( const MouseEvent& rMEvt )
+{
+ // changes the pointer if the control is enabled and the mouse is over the text.
+ if ( !rMEvt.IsLeaveWindow() && IsEnabled() && GetPointerPosPixel().X() < m_nTextLen )
+ SetPointer( POINTER_REFHAND );
+ else
+ SetPointer( m_aOldPointer );
+}
+
+void FixedHyperlink::MouseButtonUp( const MouseEvent& )
+{
+ // calls the link if the control is enabled and the mouse is over the text.
+ if ( IsEnabled() && GetPointerPosPixel().X() < m_nTextLen )
+ ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, m_aClickHdl, this );
+}
+
+void FixedHyperlink::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( IsEnabled() && GetPointerPosPixel().X() < m_nTextLen )
+ FixedText::RequestHelp( rHEvt );
+}
+
+void FixedHyperlink::GetFocus()
+{
+ SetTextColor( Color( COL_LIGHTRED ) );
+ Paint( Rectangle( Point(), GetSizePixel() ) );
+ ShowFocus( Rectangle( Point( 1, 1 ), Size( m_nTextLen + 4, GetSizePixel().Height() - 2 ) ) );
+}
+
+void FixedHyperlink::LoseFocus()
+{
+ SetTextColor( Color( COL_LIGHTBLUE ) );
+ Paint( Rectangle( Point(), GetSizePixel() ) );
+ HideFocus();
+}
+
+void FixedHyperlink::KeyInput( const KeyEvent& rKEvt )
+{
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_SPACE:
+ case KEY_RETURN:
+ m_aClickHdl.Call( this );
+ break;
+
+ default:
+ FixedText::KeyInput( rKEvt );
+ }
+}
+
+void FixedHyperlink::SetURL( const String& rNewURL )
+{
+ m_sURL = rNewURL;
+ SetQuickHelpText( m_sURL );
+}
+
+String FixedHyperlink::GetURL() const
+{
+ return m_sURL;
+}
+
+void FixedHyperlink::SetDescription( const String& rNewDescription )
+{
+ SetText( rNewDescription );
+ m_nTextLen = GetCtrlTextWidth( GetText() );
+}
+
+// class FixedHyperlinkImage ---------------------------------------------
+
+FixedHyperlinkImage::FixedHyperlinkImage( Window* pParent, const ResId& rResId ) :
+ FixedImage( pParent, rResId )
+{
+ Initialize();
+}
+
+FixedHyperlinkImage::FixedHyperlinkImage( Window* pParent, WinBits nWinStyle ) :
+ FixedImage( pParent, nWinStyle )
+{
+ Initialize();
+}
+
+FixedHyperlinkImage::~FixedHyperlinkImage()
+{
+}
+
+void FixedHyperlinkImage::Initialize()
+{
+ // saves the old pointer
+ m_aOldPointer = GetPointer();
+}
+
+void FixedHyperlinkImage::MouseMove( const MouseEvent& rMEvt )
+{
+ // changes the pointer if the control is enabled and the mouse is over the text.
+ if ( !rMEvt.IsLeaveWindow() && IsEnabled() )
+ SetPointer( POINTER_REFHAND );
+ else
+ SetPointer( m_aOldPointer );
+}
+
+void FixedHyperlinkImage::MouseButtonUp( const MouseEvent& )
+{
+ // calls the link if the control is enabled and the mouse is over the text.
+ if ( IsEnabled() )
+ ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, m_aClickHdl, this );
+
+ Size aSize = GetSizePixel();
+ Size aImgSz = GetImage().GetSizePixel();
+ if ( aSize.Width() < aImgSz.Width() )
+ {
+ DBG_ERRORFILE("xxx");
+ }
+}
+
+void FixedHyperlinkImage::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( IsEnabled() )
+ FixedImage::RequestHelp( rHEvt );
+}
+
+void FixedHyperlinkImage::GetFocus()
+{
+ Paint( Rectangle( Point(), GetSizePixel() ) );
+ ShowFocus( Rectangle( Point( 1, 1 ), Size( GetSizePixel().Width() - 2, GetSizePixel().Height() - 2 ) ) );
+}
+
+void FixedHyperlinkImage::LoseFocus()
+{
+ Paint( Rectangle( Point(), GetSizePixel() ) );
+ HideFocus();
+}
+
+void FixedHyperlinkImage::KeyInput( const KeyEvent& rKEvt )
+{
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_SPACE:
+ case KEY_RETURN:
+ m_aClickHdl.Call( this );
+ break;
+
+ default:
+ FixedImage::KeyInput( rKEvt );
+ }
+}
+
+void FixedHyperlinkImage::SetURL( const String& rNewURL )
+{
+ m_sURL = rNewURL;
+ SetQuickHelpText( m_sURL );
+}
+
+String FixedHyperlinkImage::GetURL() const
+{
+ return m_sURL;
+}
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
+
diff --git a/svtools/source/control/fmtfield.cxx b/svtools/source/control/fmtfield.cxx
new file mode 100644
index 000000000000..5b986dc10f9d
--- /dev/null
+++ b/svtools/source/control/fmtfield.cxx
@@ -0,0 +1,1398 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <stdio.h>
+#include <tools/debug.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/zformat.hxx>
+#include <svtools/fmtfield.hxx>
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/util/SearchOptions.hpp>
+#include <com/sun/star/util/SearchAlgorithms.hpp>
+#include <com/sun/star/util/SearchResult.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <unotools/syslocale.hxx>
+
+#ifndef REGEXP_SUPPORT
+#include <map>
+#endif
+
+#if !defined INCLUDED_RTL_MATH_HXX
+#include <rtl/math.hxx>
+#endif
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+
+
+#ifdef REGEXP_SUPPORT
+
+//==============================================================================
+// regular expression to validate complete numbers, plus every fragment which can occur during the input
+// of a complete number
+// [+/-][{digit}*.]*{digit}*[,{digit}*][e[+/-]{digit}*]
+const char __FAR_DATA szNumericInput[] = "_[-+]?([0-9]*\\,)*[0-9]*(\\.[0-9]*)?(e[-+]?[0-9]*)?_";
+ // (the two _ are for normalizing it: With this, we can ensure that a to-be-checked text is always
+ // matched as a _whole_)
+#else
+
+// hmm. No support for regular expression. Well, I always (not really :) wanted to write a finite automat
+// so here comes a finite automat ...
+
+namespace validation
+{
+ // the states of our automat.
+ enum State
+ {
+ START, // at the very start of the string
+ NUM_START, // the very start of the number
+
+ DIGIT_PRE_COMMA, // some pre-comma digits are read, perhaps including some thousand separators
+
+ DIGIT_POST_COMMA, // reading digits after the comma
+ EXPONENT_START, // at the very start of the exponent value
+ // (means: not including the "e" which denotes the exponent)
+ EXPONENT_DIGIT, // currently reading the digits of the exponent
+
+ END // reached the end of the string
+ };
+
+ // a row in the transition table (means the set of states to be reached from a given state)
+ typedef ::std::map< sal_Unicode, State > StateTransitions;
+
+ // a single transition
+ typedef StateTransitions::value_type Transition;
+
+ // the complete transition table
+ typedef ::std::map< State, StateTransitions > TransitionTable;
+
+ // the validator class
+ class NumberValidator
+ {
+ private:
+ TransitionTable m_aTransitions;
+ const sal_Unicode m_cThSep;
+ const sal_Unicode m_cDecSep;
+
+ public:
+ NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep );
+
+ sal_Bool isValidNumericFragment( const String& _rText );
+
+ private:
+ sal_Bool implValidateNormalized( const String& _rText );
+ };
+
+ //--------------------------------------------------------------------------
+ //..........................................................................
+ static void lcl_insertStopTransition( StateTransitions& _rRow )
+ {
+ _rRow.insert( Transition( '_', END ) );
+ }
+
+ //..........................................................................
+ static void lcl_insertStartExponentTransition( StateTransitions& _rRow )
+ {
+ _rRow.insert( Transition( 'e', EXPONENT_START ) );
+ }
+
+ //..........................................................................
+ static void lcl_insertSignTransitions( StateTransitions& _rRow, const State eNextState )
+ {
+ _rRow.insert( Transition( '-', eNextState ) );
+ _rRow.insert( Transition( '+', eNextState ) );
+ }
+
+ //..........................................................................
+ static void lcl_insertDigitTransitions( StateTransitions& _rRow, const State eNextState )
+ {
+ for ( sal_Unicode aChar = '0'; aChar <= '9'; ++aChar )
+ _rRow.insert( Transition( aChar, eNextState ) );
+ }
+
+ //..........................................................................
+ static void lcl_insertCommonPreCommaTransitions( StateTransitions& _rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep )
+ {
+ // digits are allowed
+ lcl_insertDigitTransitions( _rRow, DIGIT_PRE_COMMA );
+
+ // the thousand separator is allowed
+ _rRow.insert( Transition( _cThSep, DIGIT_PRE_COMMA ) );
+
+ // a comma is allowed
+ _rRow.insert( Transition( _cDecSep, DIGIT_POST_COMMA ) );
+ }
+
+ //--------------------------------------------------------------------------
+ NumberValidator::NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep )
+ :m_cThSep( _cThSep )
+ ,m_cDecSep( _cDecSep )
+ {
+ // build up our transition table
+
+ // how to procede from START
+ {
+ StateTransitions& rRow = m_aTransitions[ START ];
+ rRow.insert( Transition( '_', NUM_START ) );
+ // if we encounter the normalizing character, we want to procede with the number
+ }
+
+ // how to procede from NUM_START
+ {
+ StateTransitions& rRow = m_aTransitions[ NUM_START ];
+
+ // a sign is allowed
+ lcl_insertSignTransitions( rRow, DIGIT_PRE_COMMA );
+
+ // common transitions for the two pre-comma states
+ lcl_insertCommonPreCommaTransitions( rRow, m_cThSep, m_cDecSep );
+
+ // the exponent may start here
+ // (this would mean string like "_+e10_", but this is a valid fragment, though no valid number)
+ lcl_insertStartExponentTransition( rRow );
+ }
+
+ // how to procede from DIGIT_PRE_COMMA
+ {
+ StateTransitions& rRow = m_aTransitions[ DIGIT_PRE_COMMA ];
+
+ // common transitions for the two pre-comma states
+ lcl_insertCommonPreCommaTransitions( rRow, m_cThSep, m_cDecSep );
+
+ // the exponent may start here
+ lcl_insertStartExponentTransition( rRow );
+
+ // the final transition indicating the end of the string
+ // (if there is no comma and no post-comma, then the string may end here)
+ lcl_insertStopTransition( rRow );
+ }
+
+ // how to procede from DIGIT_POST_COMMA
+ {
+ StateTransitions& rRow = m_aTransitions[ DIGIT_POST_COMMA ];
+
+ // there might be digits, which would keep the state at DIGIT_POST_COMMA
+ lcl_insertDigitTransitions( rRow, DIGIT_POST_COMMA );
+
+ // the exponent may start here
+ lcl_insertStartExponentTransition( rRow );
+
+ // the string may end here
+ lcl_insertStopTransition( rRow );
+ }
+
+ // how to procede from EXPONENT_START
+ {
+ StateTransitions& rRow = m_aTransitions[ EXPONENT_START ];
+
+ // there may be a sign
+ lcl_insertSignTransitions( rRow, EXPONENT_DIGIT );
+
+ // there may be digits
+ lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT );
+
+ // the string may end here
+ lcl_insertStopTransition( rRow );
+ }
+
+ // how to procede from EXPONENT_DIGIT
+ {
+ StateTransitions& rRow = m_aTransitions[ EXPONENT_DIGIT ];
+
+ // there may be digits
+ lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT );
+
+ // the string may end here
+ lcl_insertStopTransition( rRow );
+ }
+
+ // how to procede from END
+ {
+ /*StateTransitions& rRow =*/ m_aTransitions[ EXPONENT_DIGIT ];
+ // no valid transition to leave this state
+ // (note that we, for consistency, nevertheless want to have a row in the table)
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ sal_Bool NumberValidator::implValidateNormalized( const String& _rText )
+ {
+ const sal_Unicode* pCheckPos = _rText.GetBuffer();
+ State eCurrentState = START;
+
+ while ( END != eCurrentState )
+ {
+ // look up the transition row for the current state
+ TransitionTable::const_iterator aRow = m_aTransitions.find( eCurrentState );
+ DBG_ASSERT( m_aTransitions.end() != aRow,
+ "NumberValidator::implValidateNormalized: invalid transition table (row not found)!" );
+
+ if ( m_aTransitions.end() != aRow )
+ {
+ // look up the current character in this row
+ StateTransitions::const_iterator aTransition = aRow->second.find( *pCheckPos );
+ if ( aRow->second.end() != aTransition )
+ {
+ // there is a valid transition for this character
+ eCurrentState = aTransition->second;
+ ++pCheckPos;
+ continue;
+ }
+ }
+
+ // if we're here, there is no valid transition
+ break;
+ }
+
+ DBG_ASSERT( ( END != eCurrentState ) || ( 0 == *pCheckPos ),
+ "NumberValidator::implValidateNormalized: inconsistency!" );
+ // if we're at END, then the string should be done, too - the string should be normalized, means ending
+ // a "_" and not containing any other "_" (except at the start), and "_" is the only possibility
+ // to reach the END state
+
+ // the string is valid if and only if we reached the final state
+ return ( END == eCurrentState );
+ }
+
+ //--------------------------------------------------------------------------
+ sal_Bool NumberValidator::isValidNumericFragment( const String& _rText )
+ {
+ if ( !_rText.Len() )
+ // empty strings are always allowed
+ return sal_True;
+
+ // normalize the string
+ String sNormalized( RTL_CONSTASCII_STRINGPARAM( "_") );
+ sNormalized.Append( _rText );
+ sNormalized.AppendAscii( "_" );
+
+ return implValidateNormalized( sNormalized );
+ }
+}
+
+#endif
+
+//==============================================================================
+SvNumberFormatter* FormattedField::StaticFormatter::s_cFormatter = NULL;
+ULONG FormattedField::StaticFormatter::s_nReferences = 0;
+
+//------------------------------------------------------------------------------
+SvNumberFormatter* FormattedField::StaticFormatter::GetFormatter()
+{
+ if (!s_cFormatter)
+ {
+ // get the Office's locale and translate
+ LanguageType eSysLanguage = MsLangId::convertLocaleToLanguage(
+ SvtSysLocale().GetLocaleData().getLocale() );
+ s_cFormatter = new SvNumberFormatter(
+ ::comphelper::getProcessServiceFactory(),
+ eSysLanguage);
+ }
+ return s_cFormatter;
+}
+
+//------------------------------------------------------------------------------
+FormattedField::StaticFormatter::StaticFormatter()
+{
+ ++s_nReferences;
+}
+
+//------------------------------------------------------------------------------
+FormattedField::StaticFormatter::~StaticFormatter()
+{
+ if (--s_nReferences == 0)
+ {
+ delete s_cFormatter;
+ s_cFormatter = NULL;
+ }
+}
+
+//==============================================================================
+DBG_NAME(FormattedField);
+
+#define INIT_MEMBERS() \
+ m_aLastSelection(0,0) \
+ ,m_dMinValue(0) \
+ ,m_dMaxValue(0) \
+ ,m_bHasMin(FALSE) \
+ ,m_bHasMax(FALSE) \
+ ,m_bStrictFormat(TRUE) \
+ ,m_bValueDirty(TRUE) \
+ ,m_bEnableEmptyField(TRUE) \
+ ,m_bAutoColor(FALSE) \
+ ,m_bEnableNaN(FALSE) \
+ ,m_dCurrentValue(0) \
+ ,m_dDefaultValue(0) \
+ ,m_nFormatKey(0) \
+ ,m_pFormatter(NULL) \
+ ,m_dSpinSize(1) \
+ ,m_dSpinFirst(-1000000) \
+ ,m_dSpinLast(1000000) \
+ ,m_bTreatAsNumber(TRUE) \
+ ,m_pLastOutputColor(NULL) \
+ ,m_bUseInputStringForFormatting(false)
+
+//------------------------------------------------------------------------------
+FormattedField::FormattedField(Window* pParent, WinBits nStyle, SvNumberFormatter* pInitialFormatter, INT32 nFormatKey)
+ :SpinField(pParent, nStyle)
+ ,INIT_MEMBERS()
+{
+ DBG_CTOR(FormattedField, NULL);
+
+ if (pInitialFormatter)
+ {
+ m_pFormatter = pInitialFormatter;
+ m_nFormatKey = nFormatKey;
+ }
+}
+
+//------------------------------------------------------------------------------
+FormattedField::FormattedField(Window* pParent, const ResId& rResId, SvNumberFormatter* pInitialFormatter, INT32 nFormatKey)
+ :SpinField(pParent, rResId)
+ ,INIT_MEMBERS()
+{
+ DBG_CTOR(FormattedField, NULL);
+
+ if (pInitialFormatter)
+ {
+ m_pFormatter = pInitialFormatter;
+ m_nFormatKey = nFormatKey;
+ }
+}
+
+//------------------------------------------------------------------------------
+FormattedField::~FormattedField()
+{
+ DBG_DTOR(FormattedField, NULL);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetValidateText(const XubString& rText, const String* pErrorText)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (CheckText(rText))
+ SetText(rText);
+ else
+ if (pErrorText)
+ ImplSetTextImpl(*pErrorText, NULL);
+ else
+ ImplSetValue(m_dDefaultValue, TRUE);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetText(const XubString& rStr)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ SpinField::SetText(rStr);
+ m_bValueDirty = TRUE;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetText( const XubString& rStr, const Selection& rNewSelection )
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ SpinField::SetText( rStr, rNewSelection );
+ m_bValueDirty = TRUE;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetTextFormatted(const XubString& rStr)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+#if defined DBG_UTIL
+ if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ DBG_WARNING("FormattedField::SetTextFormatted : valid only with text formats !");
+#endif
+
+ m_sCurrentTextValue = rStr;
+
+ String sFormatted;
+ double dNumber = 0.0;
+ // IsNumberFormat changes the format key parameter
+ sal_uInt32 nTempFormatKey = static_cast< sal_uInt32 >( m_nFormatKey );
+ if( IsUsingInputStringForFormatting() &&
+ ImplGetFormatter()->IsNumberFormat(m_sCurrentTextValue, nTempFormatKey, dNumber) )
+ ImplGetFormatter()->GetInputLineString(dNumber, m_nFormatKey, sFormatted);
+ else
+ ImplGetFormatter()->GetOutputString(m_sCurrentTextValue, m_nFormatKey, sFormatted, &m_pLastOutputColor);
+
+ // calculate the new selection
+ Selection aSel(GetSelection());
+ Selection aNewSel(aSel);
+ aNewSel.Justify();
+ USHORT nNewLen = sFormatted.Len();
+ USHORT nCurrentLen = GetText().Len();
+ if ((nNewLen > nCurrentLen) && (aNewSel.Max() == nCurrentLen))
+ { // the new text is longer and the cursor was behind the last char (of the old text)
+ if (aNewSel.Min() == 0)
+ { // the whole text was selected -> select the new text on the whole, too
+ aNewSel.Max() = nNewLen;
+ if (!nCurrentLen)
+ { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
+ ULONG nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
+ if (nSelOptions & SELECTION_OPTION_SHOWFIRST)
+ { // selection should be from right to left -> swap min and max
+ aNewSel.Min() = aNewSel.Max();
+ aNewSel.Max() = 0;
+ }
+ }
+ }
+ else if (aNewSel.Max() == aNewSel.Min())
+ { // there was no selection -> set the cursor behind the new last char
+ aNewSel.Max() = nNewLen;
+ aNewSel.Min() = nNewLen;
+ }
+ }
+ else if (aNewSel.Max() > nNewLen)
+ aNewSel.Max() = nNewLen;
+ else
+ aNewSel = aSel; // don't use the justified version
+ SpinField::SetText(sFormatted, aNewSel);
+ m_bValueDirty = FALSE;
+}
+
+//------------------------------------------------------------------------------
+String FormattedField::GetTextValue() const
+{
+ if (m_bValueDirty)
+ {
+ ((FormattedField*)this)->m_sCurrentTextValue = GetText();
+ ((FormattedField*)this)->m_bValueDirty = FALSE;
+ }
+ return m_sCurrentTextValue;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::EnableNotANumber( BOOL _bEnable )
+{
+ if ( m_bEnableNaN == _bEnable )
+ return;
+
+ m_bEnableNaN = _bEnable;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetAutoColor(BOOL _bAutomatic)
+{
+ if (_bAutomatic == m_bAutoColor)
+ return;
+
+ m_bAutoColor = _bAutomatic;
+ if (m_bAutoColor)
+ { // if auto color is switched on, adjust the current text color, too
+ if (m_pLastOutputColor)
+ SetControlForeground(*m_pLastOutputColor);
+ else
+ SetControlForeground();
+ }
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Modify()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (!IsStrictFormat())
+ {
+ m_bValueDirty = TRUE;
+ SpinField::Modify();
+ return;
+ }
+
+ String sCheck = GetText();
+ if (CheckText(sCheck))
+ {
+ m_sLastValidText = sCheck;
+ m_aLastSelection = GetSelection();
+ m_bValueDirty = TRUE;
+ }
+ else
+ {
+ ImplSetTextImpl(m_sLastValidText, &m_aLastSelection);
+ }
+
+ SpinField::Modify();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ImplSetTextImpl(const XubString& rNew, Selection* pNewSel)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (m_bAutoColor)
+ {
+ if (m_pLastOutputColor)
+ SetControlForeground(*m_pLastOutputColor);
+ else
+ SetControlForeground();
+ }
+
+ if (pNewSel)
+ SpinField::SetText(rNew, *pNewSel);
+ else
+ {
+ Selection aSel(GetSelection());
+ aSel.Justify();
+
+ USHORT nNewLen = rNew.Len();
+ USHORT nCurrentLen = GetText().Len();
+
+ if ((nNewLen > nCurrentLen) && (aSel.Max() == nCurrentLen))
+ { // new new text is longer and the cursor is behind the last char
+ if (aSel.Min() == 0)
+ { // the whole text was selected -> select the new text on the whole, too
+ aSel.Max() = nNewLen;
+ if (!nCurrentLen)
+ { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
+ ULONG nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
+ if (nSelOptions & SELECTION_OPTION_SHOWFIRST)
+ { // selection should be from right to left -> swap min and max
+ aSel.Min() = aSel.Max();
+ aSel.Max() = 0;
+ }
+ }
+ }
+ else if (aSel.Max() == aSel.Min())
+ { // there was no selection -> set the cursor behind the new last char
+ aSel.Max() = nNewLen;
+ aSel.Min() = nNewLen;
+ }
+ }
+ else if (aSel.Max() > nNewLen)
+ aSel.Max() = nNewLen;
+ SpinField::SetText(rNew, aSel);
+ }
+
+ m_bValueDirty = TRUE;
+ // muss nicht stimmen, aber sicherheitshalber ...
+}
+
+//------------------------------------------------------------------------------
+long FormattedField::PreNotify(NotifyEvent& rNEvt)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (rNEvt.GetType() == EVENT_KEYINPUT)
+ m_aLastSelection = GetSelection();
+ return SpinField::PreNotify(rNEvt);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ImplSetFormatKey(ULONG nFormatKey)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ m_nFormatKey = nFormatKey;
+ BOOL bNeedFormatter = (m_pFormatter == NULL) && (nFormatKey != 0);
+ if (bNeedFormatter)
+ {
+ ImplGetFormatter(); // damit wird ein Standard-Formatter angelegt
+
+ m_nFormatKey = nFormatKey;
+ // kann sein, dass das in dem Standard-Formatter keinen Sinn macht, aber der nimmt dann ein Default-Format an.
+ // Auf diese Weise kann ich einfach einen der - formatteruebergreifended gleichen - Standard-Keys setzen.
+ DBG_ASSERT(m_pFormatter->GetEntry(nFormatKey) != NULL, "FormattedField::ImplSetFormatKey : invalid format key !");
+ // Wenn SetFormatKey aufgerufen wird, ohne dass ein Formatter existiert, muss der Key einer der Standard-Werte
+ // sein, der in allen Formattern (also auch in meinem neu angelegten) vorhanden ist.
+ }
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetFormatKey(ULONG nFormatKey)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ BOOL bNoFormatter = (m_pFormatter == NULL);
+ ImplSetFormatKey(nFormatKey);
+ FormatChanged((bNoFormatter && (m_pFormatter != NULL)) ? FCT_FORMATTER : FCT_KEYONLY);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, BOOL bResetFormat)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (bResetFormat)
+ {
+ m_pFormatter = pFormatter;
+
+ // calc the default format key from the Office's UI locale
+ if ( m_pFormatter )
+ {
+ // get the Office's locale and translate
+ LanguageType eSysLanguage = MsLangId::convertLocaleToLanguage(
+ SvtSysLocale().GetLocaleData().getLocale() );
+ // get the standard numeric format for this language
+ m_nFormatKey = m_pFormatter->GetStandardFormat( NUMBERFORMAT_NUMBER, eSysLanguage );
+ }
+ else
+ m_nFormatKey = 0;
+ }
+ else
+ {
+ XubString sOldFormat;
+ LanguageType aOldLang;
+ GetFormat(sOldFormat, aOldLang);
+
+ sal_uInt32 nDestKey = pFormatter->TestNewString(sOldFormat);
+ if (nDestKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ // die Sprache des neuen Formatters
+ const SvNumberformat* pDefaultEntry = pFormatter->GetEntry(0);
+ LanguageType aNewLang = pDefaultEntry ? pDefaultEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+
+ // den alten Format-String in die neue Sprache konvertieren
+ USHORT nCheckPos;
+ short nType;
+ pFormatter->PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang);
+ m_nFormatKey = nDestKey;
+ }
+ m_pFormatter = pFormatter;
+ }
+
+ FormatChanged(FCT_FORMATTER);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::GetFormat(XubString& rFormatString, LanguageType& eLang) const
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
+ DBG_ASSERT(pFormatEntry != NULL, "FormattedField::GetFormat: no number format for the given format key.");
+ rFormatString = pFormatEntry ? pFormatEntry->GetFormatstring() : XubString();
+ eLang = pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+}
+
+//------------------------------------------------------------------------------
+BOOL FormattedField::SetFormat(const XubString& rFormatString, LanguageType eLang)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ sal_uInt32 nNewKey = ImplGetFormatter()->TestNewString(rFormatString, eLang);
+ if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ USHORT nCheckPos;
+ short nType;
+ XubString rFormat(rFormatString);
+ if (!ImplGetFormatter()->PutEntry(rFormat, nCheckPos, nType, nNewKey, eLang))
+ return FALSE;
+ DBG_ASSERT(nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "FormattedField::SetFormatString : PutEntry returned an invalid key !");
+ }
+
+ if (nNewKey != m_nFormatKey)
+ SetFormatKey(nNewKey);
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+BOOL FormattedField::GetThousandsSep() const
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::GetThousandsSep : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+
+ return bThousand;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetThousandsSep(BOOL _bUseSeparator)
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::SetThousandsSep : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ // get the current settings
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+ if (bThousand == _bUseSeparator)
+ return;
+
+ // we need the language for the following
+ LanguageType eLang;
+ String sFmtDescription;
+ GetFormat(sFmtDescription, eLang);
+
+ // generate a new format ...
+ ImplGetFormatter()->GenerateFormat(sFmtDescription, m_nFormatKey, eLang, _bUseSeparator, IsRed, nPrecision, nAnzLeading);
+ // ... and introduce it to the formatter
+ USHORT nCheckPos;
+ sal_uInt32 nNewKey;
+ short nType;
+ ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
+
+ // set the new key
+ ImplSetFormatKey(nNewKey);
+ FormatChanged(FCT_THOUSANDSSEP);
+}
+
+//------------------------------------------------------------------------------
+USHORT FormattedField::GetDecimalDigits() const
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::GetDecimalDigits : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+
+ return nPrecision;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetDecimalDigits(USHORT _nPrecision)
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::SetDecimalDigits : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ // get the current settings
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+ if (nPrecision == _nPrecision)
+ return;
+
+ // we need the language for the following
+ LanguageType eLang;
+ String sFmtDescription;
+ GetFormat(sFmtDescription, eLang);
+
+ // generate a new format ...
+ ImplGetFormatter()->GenerateFormat(sFmtDescription, m_nFormatKey, eLang, bThousand, IsRed, _nPrecision, nAnzLeading);
+ // ... and introduce it to the formatter
+ USHORT nCheckPos;
+ sal_uInt32 nNewKey;
+ short nType;
+ ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
+
+ // set the new key
+ ImplSetFormatKey(nNewKey);
+ FormatChanged(FCT_PRECISION);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::FormatChanged( FORMAT_CHANGE_TYPE _nWhat )
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ m_pLastOutputColor = NULL;
+
+ if ( ( 0 != ( _nWhat & FCT_FORMATTER ) ) && m_pFormatter )
+ m_pFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT );
+ // 95845 - 03.04.2002 - fs@openoffice.org
+
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Commit()
+{
+ // remember the old text
+ String sOld( GetText() );
+
+ // do the reformat
+ ReFormat();
+
+ // did the text change?
+ if ( GetText() != sOld )
+ { // consider the field as modified
+ Modify();
+ // but we have the most recent value now
+ m_bValueDirty = FALSE;
+ }
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ReFormat()
+{
+ if (!IsEmptyFieldEnabled() || GetText().Len())
+ {
+ if (TreatingAsNumber())
+ {
+ double dValue = GetValue();
+ if ( m_bEnableNaN && ::rtl::math::isNan( dValue ) )
+ return;
+ ImplSetValue( dValue, TRUE );
+ }
+ else
+ SetTextFormatted(GetTextValue());
+ }
+}
+
+//------------------------------------------------------------------------------
+long FormattedField::Notify(NotifyEvent& rNEvt)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if ((rNEvt.GetType() == EVENT_KEYINPUT) && !IsReadOnly())
+ {
+ const KeyEvent& rKEvt = *rNEvt.GetKeyEvent();
+ USHORT nMod = rKEvt.GetKeyCode().GetModifier();
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ {
+ // the base class would translate this into calls to Up/Down/First/Last,
+ // but we don't want this if we are text-formatted
+ return 1;
+ }
+ }
+ }
+
+ if ((rNEvt.GetType() == EVENT_COMMAND) && !IsReadOnly())
+ {
+ const CommandEvent* pCommand = rNEvt.GetCommandEvent();
+ if (pCommand->GetCommand() == COMMAND_WHEEL)
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ((pData->GetMode() == COMMAND_WHEEL_SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ {
+ // same as above : prevent the base class from doing Up/Down-calls
+ // (normally I should put this test into the Up/Down methods itself, shouldn't I ?)
+ // FS - 71553 - 19.01.00
+ return 1;
+ }
+ }
+ }
+
+ if (rNEvt.GetType() == EVENT_LOSEFOCUS)
+ {
+ // Sonderbehandlung fuer leere Texte
+ if (GetText().Len() == 0)
+ {
+ if (!IsEmptyFieldEnabled())
+ {
+ if (TreatingAsNumber())
+ {
+ ImplSetValue(m_dCurrentValue, TRUE);
+ Modify();
+ }
+ else
+ {
+ String sNew = GetTextValue();
+ if (sNew.Len())
+ SetTextFormatted(sNew);
+ else
+ SetTextFormatted(m_sDefaultText);
+ }
+ m_bValueDirty = FALSE;
+ }
+ }
+ else
+ {
+ Commit();
+ }
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetMinValue(double dMin)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !");
+
+ m_dMinValue = dMin;
+ m_bHasMin = TRUE;
+ // fuer die Ueberpruefung des aktuellen Wertes an der neuen Grenze -> ImplSetValue
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetMaxValue(double dMax)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMaxValue : only to be used in numeric mode !");
+
+ m_dMaxValue = dMax;
+ m_bHasMax = TRUE;
+ // fuer die Ueberpruefung des aktuellen Wertes an der neuen Grenze -> ImplSetValue
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetTextValue(const XubString& rText)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ SetText(rText);
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::EnableEmptyField(BOOL bEnable)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (bEnable == m_bEnableEmptyField)
+ return;
+
+ m_bEnableEmptyField = bEnable;
+ if (!m_bEnableEmptyField && GetText().Len()==0)
+ ImplSetValue(m_dCurrentValue, TRUE);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ImplSetValue(double dVal, BOOL bForce)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (m_bHasMin && (dVal<m_dMinValue))
+ dVal = m_dMinValue;
+ if (m_bHasMax && (dVal>m_dMaxValue))
+ dVal = m_dMaxValue;
+ if (!bForce && (dVal == GetValue()))
+ return;
+
+ DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplSetValue : can't set a value without a formatter !");
+
+ m_bValueDirty = FALSE;
+ m_dCurrentValue = dVal;
+
+ String sNewText;
+ if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ {
+ // zuerst die Zahl als String im Standard-Format
+ String sTemp;
+ ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor);
+ // dann den String entsprechend dem Text-Format
+ ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor);
+ }
+ else
+ {
+ if( IsUsingInputStringForFormatting())
+ ImplGetFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText);
+ else
+ ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor);
+ }
+
+ ImplSetTextImpl(sNewText, NULL);
+ m_bValueDirty = FALSE;
+ DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
+}
+
+//------------------------------------------------------------------------------
+BOOL FormattedField::ImplGetValue(double& dNewVal)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ dNewVal = m_dCurrentValue;
+ if (!m_bValueDirty)
+ return TRUE;
+
+ dNewVal = m_dDefaultValue;
+ String sText(GetText());
+ if (!sText.Len())
+ return TRUE;
+
+ DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplGetValue : can't give you a current value without a formatter !");
+
+ sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat veraendert den FormatKey ...
+
+ if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
+ // damit wir in einem als Text formatierten Feld trotzdem eine Eingabe wie '1,1' erkennen ...
+ nFormatKey = 0;
+
+ // Sonderbehandlung fuer %-Formatierung
+ if (ImplGetFormatter()->GetType(m_nFormatKey) == NUMBERFORMAT_PERCENT)
+ {
+ // the language of our format
+ LanguageType eLanguage = m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage();
+ // the default number format for this language
+ ULONG nStandardNumericFormat = m_pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER, eLanguage);
+
+ sal_uInt32 nTempFormat = nStandardNumericFormat;
+ double dTemp;
+ if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) &&
+ NUMBERFORMAT_NUMBER == m_pFormatter->GetType(nTempFormat))
+ // der String entspricht einer Number-Formatierung, hat also nur kein %
+ // -> append it
+ sText += '%';
+ // (with this, a input of '3' becomes '3%', which then by the formatter is translated
+ // into 0.03. Without this, the formatter would give us the double 3 for an input '3',
+ // which equals 300 percent.
+ }
+ if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal))
+ return FALSE;
+
+
+ if (m_bHasMin && (dNewVal<m_dMinValue))
+ dNewVal = m_dMinValue;
+ if (m_bHasMax && (dNewVal>m_dMaxValue))
+ dNewVal = m_dMaxValue;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetValue(double dVal)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ ImplSetValue(dVal, m_bValueDirty);
+}
+
+//------------------------------------------------------------------------------
+double FormattedField::GetValue()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if ( !ImplGetValue( m_dCurrentValue ) )
+ {
+ if ( m_bEnableNaN )
+ ::rtl::math::setNan( &m_dCurrentValue );
+ else
+ m_dCurrentValue = m_dDefaultValue;
+ }
+
+ m_bValueDirty = FALSE;
+ return m_dCurrentValue;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Up()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ SetValue(GetValue() + m_dSpinSize);
+ // das setValue handelt Bereichsueberschreitungen (min/max) automatisch
+ SetModifyFlag();
+ Modify();
+
+ SpinField::Up();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Down()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ SetValue(GetValue() - m_dSpinSize);
+ SetModifyFlag();
+ Modify();
+
+ SpinField::Down();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::First()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (m_bHasMin)
+ {
+ SetValue(m_dMinValue);
+ SetModifyFlag();
+ Modify();
+ }
+
+ SpinField::First();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Last()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (m_bHasMax)
+ {
+ SetValue(m_dMaxValue);
+ SetModifyFlag();
+ Modify();
+ }
+
+ SpinField::Last();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::UseInputStringForFormatting( bool bUseInputStr /* = true */ )
+{
+ m_bUseInputStringForFormatting = bUseInputStr;
+}
+
+//------------------------------------------------------------------------------
+bool FormattedField::IsUsingInputStringForFormatting() const
+{
+ return m_bUseInputStringForFormatting;
+}
+
+
+//==============================================================================
+//------------------------------------------------------------------------------
+DoubleNumericField::~DoubleNumericField()
+{
+#ifdef REGEXP_SUPPORT
+ delete m_pConformanceTester;
+#else
+ delete m_pNumberValidator;
+#endif
+}
+
+//------------------------------------------------------------------------------
+void DoubleNumericField::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
+{
+ ResetConformanceTester();
+ FormattedField::FormatChanged(nWhat);
+}
+
+//------------------------------------------------------------------------------
+BOOL DoubleNumericField::CheckText(const XubString& sText) const
+{
+ // We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't
+ // recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10")
+ // Thus, the roundabout way via a regular expression
+
+#ifdef REGEXP_SUPPORT
+ if (!sText.Len())
+ return TRUE;
+
+ String sForceComplete = '_';
+ sForceComplete += sText;
+ sForceComplete += '_';
+
+ USHORT nStart = 0, nEnd = sForceComplete.Len();
+ BOOL bFound = m_pConformanceTester->SearchFrwrd(sForceComplete, &nStart, &nEnd);
+
+ if (bFound && (nStart == 0) && (nEnd == sForceComplete.Len()))
+ return TRUE;
+
+ return FALSE;
+#else
+ return m_pNumberValidator->isValidNumericFragment( sText );
+#endif
+}
+
+//------------------------------------------------------------------------------
+void DoubleNumericField::ResetConformanceTester()
+{
+ // the thousands and the decimal separator are language dependent
+ const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
+
+ sal_Unicode cSeparatorThousand = ',';
+ sal_Unicode cSeparatorDecimal = '.';
+ if (pFormatEntry)
+ {
+ Locale aLocale;
+ MsLangId::convertLanguageToLocale( pFormatEntry->GetLanguage(), aLocale );
+ LocaleDataWrapper aLocaleInfo(::comphelper::getProcessServiceFactory(), aLocale);
+
+ String sSeparator = aLocaleInfo.getNumThousandSep();
+ if (sSeparator.Len())
+ cSeparatorThousand = sSeparator.GetBuffer()[0];
+
+ sSeparator = aLocaleInfo.getNumDecimalSep();
+ if (sSeparator.Len())
+ cSeparatorDecimal = sSeparator.GetBuffer()[0];
+ }
+
+#ifdef REGEXP_SUPPORT
+ String sDescription = String::CreateFromAscii(szNumericInput);
+
+ String sReplaceWith((sal_Unicode)'\\');
+ sReplaceWith += cSeparatorThousand;
+ sDescription.SearchAndReplaceAscii("\\,", sReplaceWith);
+
+ sReplaceWith = (sal_Unicode)'\\';
+ sReplaceWith += cSeparatorDecimal;
+ sDescription.SearchAndReplaceAscii("\\.", sReplaceWith);
+
+ delete m_pConformanceTester;
+
+ SearchOptions aParam;
+ aParam.algorithmType = SearchAlgorithms_REGEXP;
+ aParam.searchFlag = SearchFlags::ALL_IGNORE_CASE;
+ aParam.searchString = sDescription;
+ aParam.transliterateFlags = 0;
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames( pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_ENGLISH_US, sLanguage, sCountry );
+ aParam.Locale.Language = sLanguage;
+ aParam.Locale.Country = sCountry;
+
+ m_pConformanceTester = new ::utl::TextSearch(aParam);
+#else
+ delete m_pNumberValidator;
+ m_pNumberValidator = new validation::NumberValidator( cSeparatorThousand, cSeparatorDecimal );
+#endif
+}
+
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+DoubleCurrencyField::DoubleCurrencyField(Window* pParent, WinBits nStyle)
+ :FormattedField(pParent, nStyle)
+ ,m_bChangingFormat(FALSE)
+{
+ m_bPrependCurrSym = FALSE;
+
+ // initialize with a system currency format
+ m_sCurrencySymbol = SvtSysLocale().GetLocaleData().getCurrSymbol();
+ UpdateCurrencyFormat();
+}
+
+//------------------------------------------------------------------------------
+DoubleCurrencyField::DoubleCurrencyField(Window* pParent, const ResId& rResId)
+ :FormattedField(pParent, rResId)
+ ,m_bChangingFormat(FALSE)
+{
+ m_bPrependCurrSym = FALSE;
+
+ // initialize with a system currency format
+ m_sCurrencySymbol = SvtSysLocale().GetLocaleData().getCurrSymbol();
+ UpdateCurrencyFormat();
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
+{
+ if (m_bChangingFormat)
+ {
+ FormattedField::FormatChanged(nWhat);
+ return;
+ }
+
+ switch (nWhat)
+ {
+ case FCT_FORMATTER:
+ case FCT_PRECISION:
+ case FCT_THOUSANDSSEP:
+ // the aspects which changed don't take our currency settings into account (in fact, they most probably
+ // destroyed them)
+ UpdateCurrencyFormat();
+ break;
+ case FCT_KEYONLY:
+ DBG_ERROR("DoubleCurrencyField::FormatChanged : somebody modified my key !");
+ // We always build our own format from the settings we get via special methods (setCurrencySymbol etc.).
+ // Nobody but ourself should modifiy the format key directly !
+ break;
+ }
+
+ FormattedField::FormatChanged(nWhat);
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::setCurrencySymbol(const String& _sSymbol)
+{
+ if (m_sCurrencySymbol == _sSymbol)
+ return;
+
+ m_sCurrencySymbol = _sSymbol;
+ UpdateCurrencyFormat();
+ FormatChanged(FCT_CURRENCY_SYMBOL);
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::setPrependCurrSym(BOOL _bPrepend)
+{
+ if (m_bPrependCurrSym == _bPrepend)
+ return;
+
+ m_bPrependCurrSym = _bPrepend;
+ UpdateCurrencyFormat();
+ FormatChanged(FCT_CURRSYM_POSITION);
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::UpdateCurrencyFormat()
+{
+ // the old settings
+ XubString sOldFormat;
+ LanguageType eLanguage;
+ GetFormat(sOldFormat, eLanguage);
+ BOOL bThSep = GetThousandsSep();
+ USHORT nDigits = GetDecimalDigits();
+
+ // build a new format string with the base class' and my own settings
+ Locale aLocale;
+ MsLangId::convertLanguageToLocale( eLanguage, aLocale );
+ LocaleDataWrapper aLocaleInfo(::comphelper::getProcessServiceFactory(), aLocale);
+
+ XubString sNewFormat;
+ if (bThSep)
+ {
+ sNewFormat = '#';
+ sNewFormat += aLocaleInfo.getNumThousandSep();
+ sNewFormat.AppendAscii("##0");
+ }
+ else
+ sNewFormat = '0';
+
+ if (nDigits)
+ {
+ sNewFormat += aLocaleInfo.getNumDecimalSep();
+
+ XubString sTemp;
+ sTemp.Fill(nDigits, '0');
+ sNewFormat += sTemp;
+ }
+
+ if (getPrependCurrSym())
+ {
+ XubString sSymbol = getCurrencySymbol();
+ sSymbol.EraseLeadingChars(' ');
+ sSymbol.EraseTrailingChars(' ');
+
+ XubString sTemp = String::CreateFromAscii("[$");
+ sTemp += sSymbol;
+ sTemp.AppendAscii("] ");
+ sTemp += sNewFormat;
+
+ // for negative values : $ -0.00, not -$ 0.00 ...
+ // (the real solution would be a possibility to choose a "positive currency format" and a "negative currency format" ...
+ // But not now ... (and hey, you could take a formatted field for this ....))
+ // FS - 31.03.00 74642
+ sTemp.AppendAscii(";[$");
+ sTemp += sSymbol;
+ sTemp.AppendAscii("] -");
+ sTemp += sNewFormat;
+
+ sNewFormat = sTemp;
+ }
+ else
+ {
+ XubString sTemp = getCurrencySymbol();
+ sTemp.EraseLeadingChars(' ');
+ sTemp.EraseTrailingChars(' ');
+
+ sNewFormat += String::CreateFromAscii(" [$");
+ sNewFormat += sTemp;
+ sNewFormat += ']';
+ }
+
+ // set this new basic format
+ m_bChangingFormat = TRUE;
+ SetFormat(sNewFormat, eLanguage);
+ m_bChangingFormat = FALSE;
+}
+
diff --git a/svtools/source/control/headbar.cxx b/svtools/source/control/headbar.cxx
new file mode 100644
index 000000000000..1ae223bebf06
--- /dev/null
+++ b/svtools/source/control/headbar.cxx
@@ -0,0 +1,1653 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SV_HEADBAR_CXX
+#include <svtools/headbar.hxx>
+#include <tools/debug.hxx>
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+
+#ifndef _VCL_APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _VCL_HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _VCL_IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+// =======================================================================
+
+struct ImplHeadItem
+{
+ USHORT mnId;
+ HeaderBarItemBits mnBits;
+ long mnSize;
+ ULONG mnHelpId;
+ Image maImage;
+ XubString maOutText;
+ XubString maText;
+ XubString maHelpText;
+ void* mpUserData;
+};
+
+DECLARE_LIST( ImplHeadItemList, ImplHeadItem* )
+
+// =======================================================================
+
+#define HEAD_ARROWSIZE1 4
+#define HEAD_ARROWSIZE2 7
+
+#define HEADERBAR_TEXTOFF 2
+#define HEADERBAR_ARROWOFF 5
+#define HEADERBAR_SPLITOFF 3
+
+#define HEADERBAR_DRAGOFF 4
+#define HEADERBAR_DRAGOUTOFF 15
+
+#define HEAD_HITTEST_ITEM ((USHORT)0x0001)
+#define HEAD_HITTEST_DIVIDER ((USHORT)0x0002)
+
+// =======================================================================
+
+void HeaderBar::ImplInit( WinBits nWinStyle )
+{
+ mpItemList = new ImplHeadItemList;
+ mnBorderOff1 = 0;
+ mnBorderOff2 = 0;
+ mnOffset = 0;
+ mnDX = 0;
+ mnDY = 0;
+ mnDragSize = 0;
+ mnStartPos = 0;
+ mnDragPos = 0;
+ mnMouseOff = 0;
+ mnCurItemId = 0;
+ mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
+ mbDrag = FALSE;
+ mbItemDrag = FALSE;
+ mbOutDrag = FALSE;
+ mbItemMode = FALSE;
+
+ // StyleBits auswerten
+ if ( nWinStyle & WB_DRAG )
+ mbDragable = TRUE;
+ else
+ mbDragable = FALSE;
+ if ( nWinStyle & WB_BUTTONSTYLE )
+ mbButtonStyle = TRUE;
+ else
+ mbButtonStyle = FALSE;
+ if ( nWinStyle & WB_BORDER )
+ {
+ mnBorderOff1 = 1;
+ mnBorderOff2 = 1;
+ }
+ else
+ {
+ if ( nWinStyle & WB_BOTTOMBORDER )
+ mnBorderOff2 = 1;
+ }
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBar::HeaderBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle & WB_3DLOOK )
+{
+ ImplInit( nWinStyle );
+ SetSizePixel( CalcWindowSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBar::HeaderBar( Window* pParent, const ResId& rResId ) :
+ Window( pParent, rResId )
+{
+ ImplInit( rResId.GetWinBits() );
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBar::~HeaderBar()
+{
+ // Alle Items loeschen
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long HeaderBar::ImplGetItemPos( USHORT nPos ) const
+{
+ long nX = -mnOffset;
+ for ( USHORT i = 0; i < nPos; i++ )
+ nX += mpItemList->GetObject( i )->mnSize;
+ return nX;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle HeaderBar::ImplGetItemRect( USHORT nPos ) const
+{
+ Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
+ aRect.Right() = aRect.Left() + mpItemList->GetObject( nPos )->mnSize - 1;
+ // Gegen Ueberlauf auf einigen Systemen testen
+ if ( aRect.Right() > 16000 )
+ aRect.Right() = 16000;
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::ImplHitTest( const Point& rPos,
+ long& nMouseOff, USHORT& nPos ) const
+{
+ ImplHeadItem* pItem;
+ USHORT nCount = (USHORT)mpItemList->Count();
+ BOOL bLastFixed = TRUE;
+ long nX = -mnOffset;
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ pItem = mpItemList->GetObject( i );
+
+ if ( rPos.X() < (nX+pItem->mnSize) )
+ {
+ USHORT nMode;
+
+ if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
+ {
+ nMode = HEAD_HITTEST_DIVIDER;
+ nPos = i-1;
+ nMouseOff = rPos.X()-nX+1;
+ }
+ else
+ {
+ nPos = i;
+
+ if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) )
+ {
+ nMode = HEAD_HITTEST_DIVIDER;
+ nMouseOff = rPos.X()-(nX+pItem->mnSize);
+ }
+ else
+ {
+ nMode = HEAD_HITTEST_ITEM;
+ nMouseOff = rPos.X()-nX;
+ }
+ }
+
+ return nMode;
+ }
+
+ if ( pItem->mnBits & HIB_FIXED )
+ bLastFixed = TRUE;
+ else
+ bLastFixed = FALSE;
+
+ nX += pItem->mnSize;
+ }
+
+ if ( !bLastFixed )
+ {
+ pItem = mpItemList->GetObject( nCount-1 );
+ if ( (pItem->mnSize < 4) && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
+ {
+ nPos = nCount-1;
+ nMouseOff = rPos.X()-nX+1;
+ return HEAD_HITTEST_DIVIDER;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplInvertDrag( USHORT nStartPos, USHORT nEndPos )
+{
+ Rectangle aRect1 = ImplGetItemRect( nStartPos );
+ Rectangle aRect2 = ImplGetItemRect( nEndPos );
+ Point aStartPos = aRect1.Center();
+ Point aEndPos = aStartPos;
+ Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
+ aStartPos.X()+2, aStartPos.Y()+2 );
+
+ if ( nEndPos > nStartPos )
+ {
+ aStartPos.X() += 3;
+ aEndPos.X() = aRect2.Right()-6;
+ }
+ else
+ {
+ aStartPos.X() -= 3;
+ aEndPos.X() = aRect2.Left()+6;
+ }
+
+ SetRasterOp( ROP_INVERT );
+ DrawRect( aStartRect );
+ DrawLine( aStartPos, aEndPos );
+ if ( nEndPos > nStartPos )
+ {
+ DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
+ Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
+ DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
+ Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
+ DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
+ Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
+ DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
+ }
+ else
+ {
+ DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
+ Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
+ DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
+ Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
+ DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
+ Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
+ DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
+ }
+ SetRasterOp( ROP_OVERPAINT );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplDrawItem( OutputDevice* pDev,
+ USHORT nPos, BOOL bHigh, BOOL bDrag,
+ const Rectangle& rItemRect,
+ const Rectangle* pRect,
+ ULONG )
+{
+ Rectangle aRect = rItemRect;
+
+ // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
+ if ( aRect.GetWidth() <= 1 )
+ return;
+
+ // Feststellen, ob Rectangle ueberhaupt sichtbar
+ if ( pRect )
+ {
+ if ( aRect.Right() < pRect->Left() )
+ return;
+ else if ( aRect.Left() > pRect->Right() )
+ return;
+ }
+ else
+ {
+ if ( aRect.Right() < 0 )
+ return;
+ else if ( aRect.Left() > mnDX )
+ return;
+ }
+
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ HeaderBarItemBits nBits = pItem->mnBits;
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Border muss nicht gemalt werden
+ aRect.Top() += mnBorderOff1;
+ aRect.Bottom() -= mnBorderOff2;
+
+ // Hintergrund loeschen
+ if ( !pRect || bDrag )
+ {
+ if ( bDrag )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
+ pDev->DrawRect( aRect );
+ }
+ else
+ pDev->DrawWallpaper( aRect, GetBackground() );
+ }
+
+ // Trennlinie malen
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pDev->DrawLine( Point( aRect.Right(), aRect.Top() ),
+ Point( aRect.Right(), aRect.Bottom() ) );
+
+ // ButtonStyle malen
+ // avoid 3D borders
+ Color aSelectionTextColor( COL_TRANSPARENT );
+ if( bHigh )
+ DrawSelectionBackground( aRect, 1, TRUE, FALSE, FALSE, &aSelectionTextColor );
+ else if ( !mbButtonStyle || (nBits & HIB_FLAT) )
+ DrawSelectionBackground( aRect, 0, TRUE, FALSE, FALSE, &aSelectionTextColor );
+
+ // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
+ if ( aRect.GetWidth() < 1 )
+ return;
+
+ // Positionen und Groessen berechnen und Inhalt ausgeben
+ pItem->maOutText = pItem->maText;
+ Size aImageSize = pItem->maImage.GetSizePixel();
+ Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0 );
+ if ( pItem->maOutText.Len() )
+ aTxtSize.Height() = pDev->GetTextHeight();
+ long nArrowWidth = 0;
+ if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
+ nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF;
+
+ // Wenn kein Platz fuer Image, dann nicht ausgeben
+ long nTestHeight = aImageSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTestHeight += aTxtSize.Height();
+ if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) )
+ {
+ aImageSize.Width() = 0;
+ aImageSize.Height() = 0;
+ }
+
+ // Text auf entsprechende Laenge kuerzen
+ BOOL bLeftText = FALSE;
+ long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth;
+ if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
+ nMaxTxtWidth -= aImageSize.Width();
+ long nTxtWidth = aTxtSize.Width();
+ if ( nTxtWidth > nMaxTxtWidth )
+ {
+ bLeftText = TRUE;
+ // 3 == Len of "..."
+ pItem->maOutText.AppendAscii( "..." );
+ do
+ {
+ pItem->maOutText.Erase( pItem->maOutText.Len()-3-1, 1 );
+ nTxtWidth = pDev->GetTextWidth( pItem->maOutText );
+ }
+ while ( (nTxtWidth > nMaxTxtWidth) && (pItem->maOutText.Len() > 3) );
+ if ( pItem->maOutText.Len() == 3 )
+ {
+ nTxtWidth = 0;
+ pItem->maOutText.Erase();
+ }
+ }
+
+ // Text/Imageposition berechnen
+ long nTxtPos;
+ if ( !bLeftText && (nBits & HIB_RIGHT) )
+ {
+ nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF;
+ if ( nBits & HIB_RIGHTIMAGE )
+ nTxtPos -= aImageSize.Width();
+ }
+ else if ( !bLeftText && (nBits & HIB_CENTER) )
+ {
+ long nTempWidth = nTxtWidth;
+ if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
+ nTempWidth += aImageSize.Width();
+ nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2;
+ if ( nBits & HIB_LEFTIMAGE )
+ nTxtPos += aImageSize.Width();
+ if ( nArrowWidth )
+ {
+ if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() )
+ {
+ nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
+ if ( nBits & HIB_LEFTIMAGE )
+ nTxtPos += aImageSize.Width();
+ }
+ }
+ }
+ else
+ {
+ nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
+ if ( nBits & HIB_LEFTIMAGE )
+ nTxtPos += aImageSize.Width();
+ if ( nBits & HIB_RIGHT )
+ nTxtPos += nArrowWidth;
+ }
+
+ // TextPosition berechnen
+ long nTxtPosY = 0;
+ if ( pItem->maOutText.Len() || (nArrowWidth && aTxtSize.Height()) )
+ {
+ if ( nBits & HIB_TOP )
+ {
+ nTxtPosY = aRect.Top();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTxtPosY += aImageSize.Height();
+ }
+ else if ( nBits & HIB_BOTTOM )
+ nTxtPosY = aRect.Bottom()-aTxtSize.Height();
+ else
+ {
+ long nTempHeight = aTxtSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTempHeight += aImageSize.Height();
+ nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTxtPosY += aImageSize.Height();
+ }
+ }
+
+ // Text ausgebeben
+ if ( pItem->maOutText.Len() )
+ {
+ if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
+ {
+ pDev->Push( PUSH_TEXTCOLOR );
+ pDev->SetTextColor( aSelectionTextColor );
+ }
+ if ( IsEnabled() )
+ pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText );
+ else
+ pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, STRING_LEN, TEXT_DRAW_DISABLE );
+ if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
+ pDev->Pop();
+ }
+
+ // Wenn Image vorhanden, Position berechnen und ausgeben
+ long nImagePosY = 0;
+ if ( aImageSize.Width() && aImageSize.Height() )
+ {
+ long nImagePos = nTxtPos;
+ if ( nBits & HIB_LEFTIMAGE )
+ {
+ nImagePos -= aImageSize.Width();
+ if ( nBits & HIB_RIGHT )
+ nImagePos -= nArrowWidth;
+ }
+ else if ( nBits & HIB_RIGHTIMAGE )
+ {
+ nImagePos += nTxtWidth;
+ if ( !(nBits & HIB_RIGHT) )
+ nImagePos += nArrowWidth;
+ }
+ else
+ {
+ if ( nBits & HIB_RIGHT )
+ nImagePos = aRect.Right()-aImageSize.Width();
+ else if ( nBits & HIB_CENTER )
+ nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2;
+ else
+ nImagePos = aRect.Left()+HEADERBAR_TEXTOFF;
+ }
+
+ if ( nBits & HIB_TOP )
+ nImagePosY = aRect.Top();
+ else if ( nBits & HIB_BOTTOM )
+ {
+ nImagePosY = aRect.Bottom()-aImageSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nImagePosY -= aTxtSize.Height();
+ }
+ else
+ {
+ long nTempHeight = aImageSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTempHeight += aTxtSize.Height();
+ nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
+ }
+ if ( nImagePos+aImageSize.Width() <= aRect.Right() )
+ {
+ USHORT nStyle = 0;
+ if ( !IsEnabled() )
+ nStyle |= IMAGE_DRAW_DISABLE;
+ pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle );
+ }
+ }
+
+ if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
+ {
+ long nArrowX = nTxtPos;
+ if ( nBits & HIB_RIGHT )
+ nArrowX -= nArrowWidth;
+ else
+ nArrowX += nTxtWidth+HEADERBAR_ARROWOFF;
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.Len() )
+ {
+ if ( nBits & HIB_RIGHT )
+ nArrowX -= aImageSize.Width();
+ else
+ nArrowX += aImageSize.Width();
+ }
+
+ // Feststellen, ob Platz genug ist, das Item zu malen
+ BOOL bDraw = TRUE;
+ if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF )
+ bDraw = FALSE;
+ else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() )
+ bDraw = FALSE;
+
+ if ( bDraw )
+ {
+ long nArrowY;
+ if ( aTxtSize.Height() )
+ nArrowY = nTxtPosY+(aTxtSize.Height()/2);
+ else if ( aImageSize.Width() && aImageSize.Height() )
+ nArrowY = nImagePosY+(aImageSize.Height()/2);
+ else
+ {
+ if ( nBits & HIB_TOP )
+ nArrowY = aRect.Top()+1;
+ else if ( nBits & HIB_BOTTOM )
+ nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1;
+ else
+ nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);;
+ }
+ nArrowY -= HEAD_ARROWSIZE1-1;
+ if ( nBits & HIB_DOWNARROW )
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( nArrowX, nArrowY ),
+ Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
+ pDev->DrawLine( Point( nArrowX, nArrowY ),
+ Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
+ }
+ else
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) );
+ pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
+ }
+ }
+ }
+
+ // Gegebenenfalls auch UserDraw aufrufen
+ if ( nBits & HIB_USERDRAW )
+ {
+ Region aRegion( aRect );
+ if ( pRect )
+ aRegion.Intersect( *pRect );
+ pDev->SetClipRegion( aRegion );
+ UserDrawEvent aODEvt( pDev, aRect, pItem->mnId );
+ UserDraw( aODEvt );
+ pDev->SetClipRegion();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplDrawItem( USHORT nPos, BOOL bHigh, BOOL bDrag,
+ const Rectangle* pRect )
+{
+ Rectangle aRect = ImplGetItemRect( nPos );
+ ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplUpdate( USHORT nPos, BOOL bEnd, BOOL bDirect )
+{
+ if ( IsVisible() && IsUpdateMode() )
+ {
+ if ( !bDirect )
+ {
+ Rectangle aRect;
+ USHORT nItemCount = (USHORT)(mpItemList->Count());
+ if ( nPos < nItemCount )
+ aRect = ImplGetItemRect( nPos );
+ else
+ {
+ aRect.Bottom() = mnDY-1;
+ if ( nItemCount )
+ aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right();
+ }
+ if ( bEnd )
+ aRect.Right() = mnDX-1;
+ aRect.Top() += mnBorderOff1;
+ aRect.Bottom() -= mnBorderOff2;
+ Invalidate( aRect );
+ }
+ else
+ {
+ for ( USHORT i = nPos; i < mpItemList->Count(); i++ )
+ ImplDrawItem( i );
+ if ( bEnd )
+ {
+ Rectangle aRect = ImplGetItemRect( (USHORT)mpItemList->Count() );
+ aRect.Left() = aRect.Right();
+ aRect.Right() = mnDX-1;
+ if ( aRect.Left() < aRect.Right() )
+ {
+ aRect.Top() += mnBorderOff1;
+ aRect.Bottom() -= mnBorderOff2;
+ Erase( aRect );
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplStartDrag( const Point& rMousePos, BOOL bCommand )
+{
+ USHORT nPos;
+ USHORT nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
+ if ( nHitTest )
+ {
+ mbDrag = FALSE;
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( nHitTest & HEAD_HITTEST_DIVIDER )
+ mbDrag = TRUE;
+ else
+ {
+ if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) ||
+ (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) )
+ {
+ mbItemMode = TRUE;
+ mbDrag = TRUE;
+ if ( bCommand )
+ {
+ if ( mbDragable )
+ mbItemDrag = TRUE;
+ else
+ {
+ mbItemMode = FALSE;
+ mbDrag = FALSE;
+ }
+ }
+ }
+ else
+ {
+ if ( !bCommand )
+ {
+ mnCurItemId = pItem->mnId;
+ Select();
+ mnCurItemId = 0;
+ }
+ }
+ }
+
+ if ( mbDrag )
+ {
+ mbOutDrag = FALSE;
+ mnCurItemId = pItem->mnId;
+ mnItemDragPos = nPos;
+ StartTracking();
+ mnStartPos = rMousePos.X()-mnMouseOff;
+ mnDragPos = mnStartPos;
+ StartDrag();
+ if ( mbItemMode )
+ ImplDrawItem( nPos, TRUE, mbItemDrag );
+ else
+ {
+ Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
+ ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
+ }
+ }
+ else
+ mnMouseOff = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplDrag( const Point& rMousePos )
+{
+ BOOL bNewOutDrag;
+ USHORT nPos = GetItemPos( mnCurItemId );
+
+ mnDragPos = rMousePos.X()-mnMouseOff;
+ if ( mbItemMode )
+ {
+ Rectangle aItemRect = ImplGetItemRect( nPos );
+ if ( aItemRect.IsInside( rMousePos ) )
+ bNewOutDrag = FALSE;
+ else
+ bNewOutDrag = TRUE;
+
+ // Evt. ItemDrag anschalten
+ if ( bNewOutDrag && mbDragable && !mbItemDrag &&
+ !(mpItemList->GetObject(nPos)->mnBits & HIB_FIXEDPOS) )
+ {
+ if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
+ {
+ mbItemDrag = TRUE;
+ ImplDrawItem( nPos, TRUE, mbItemDrag );
+ }
+ }
+
+ USHORT nOldItemDragPos = mnItemDragPos;
+ if ( mbItemDrag )
+ {
+ if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) )
+ bNewOutDrag = TRUE;
+ else
+ bNewOutDrag = FALSE;
+
+ if ( bNewOutDrag )
+ mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
+ else
+ {
+ USHORT nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
+ if ( nTempId )
+ mnItemDragPos = GetItemPos( nTempId );
+ else
+ {
+ if ( rMousePos.X() <= 0 )
+ mnItemDragPos = 0;
+ else
+ mnItemDragPos = GetItemCount()-1;
+ }
+
+ // Nicht verschiebbare Items aussparen
+ if ( mnItemDragPos < nPos )
+ {
+ while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
+ (mnItemDragPos < nPos) )
+ mnItemDragPos++;
+ }
+ else if ( mnItemDragPos > nPos )
+ {
+ while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
+ (mnItemDragPos > nPos) )
+ mnItemDragPos--;
+ }
+ }
+
+ if ( (mnItemDragPos != nOldItemDragPos) &&
+ (nOldItemDragPos != nPos) &&
+ (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
+ {
+ ImplInvertDrag( nPos, nOldItemDragPos );
+ ImplDrawItem( nOldItemDragPos );
+ }
+ }
+
+ if ( bNewOutDrag != mbOutDrag )
+ ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag );
+
+ if ( mbItemDrag )
+ {
+ if ( (mnItemDragPos != nOldItemDragPos) &&
+ (mnItemDragPos != nPos) &&
+ (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
+ {
+ ImplDrawItem( mnItemDragPos, FALSE, TRUE );
+ ImplInvertDrag( nPos, mnItemDragPos );
+ }
+ }
+
+ mbOutDrag = bNewOutDrag;
+ }
+ else
+ {
+ Rectangle aItemRect = ImplGetItemRect( nPos );
+ if ( mnDragPos < aItemRect.Left() )
+ mnDragPos = aItemRect.Left();
+ if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
+ HideTracking();
+ else
+ {
+ Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
+ ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
+ }
+ }
+
+ Drag();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplEndDrag( BOOL bCancel )
+{
+ HideTracking();
+
+ if ( bCancel || mbOutDrag )
+ {
+ if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
+ {
+ USHORT nPos = GetItemPos( mnCurItemId );
+ ImplDrawItem( nPos );
+ }
+
+ mnCurItemId = 0;
+ }
+ else
+ {
+ USHORT nPos = GetItemPos( mnCurItemId );
+ if ( mbItemMode )
+ {
+ if ( mbItemDrag )
+ {
+ Pointer aPointer( POINTER_ARROW );
+ SetPointer( aPointer );
+ if ( (mnItemDragPos != nPos) &&
+ (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
+ {
+ ImplInvertDrag( nPos, mnItemDragPos );
+ MoveItem( mnCurItemId, mnItemDragPos );
+ }
+ else
+ ImplDrawItem( nPos );
+ }
+ else
+ {
+ Select();
+ ImplUpdate( nPos );
+ }
+ }
+ else
+ {
+ long nDelta = mnDragPos - mnStartPos;
+ if ( nDelta )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ pItem->mnSize += nDelta;
+ ImplUpdate( nPos, TRUE );
+ }
+ }
+ }
+
+ mbDrag = FALSE;
+ EndDrag();
+ mnCurItemId = 0;
+ mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
+ mbOutDrag = FALSE;
+ mbItemMode = FALSE;
+ mbItemDrag = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ long nTemp;
+ USHORT nPos;
+ USHORT nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
+ if ( nHitTest )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( nHitTest & HEAD_HITTEST_DIVIDER )
+ mbItemMode = FALSE;
+ else
+ mbItemMode = TRUE;
+ mnCurItemId = pItem->mnId;
+ DoubleClick();
+ mbItemMode = FALSE;
+ mnCurItemId = 0;
+ }
+ }
+ else
+ ImplStartDrag( rMEvt.GetPosPixel(), FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::MouseMove( const MouseEvent& rMEvt )
+{
+ long nTemp1;
+ USHORT nTemp2;
+ PointerStyle eStyle = POINTER_ARROW;
+ USHORT nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );
+
+ if ( nHitTest & HEAD_HITTEST_DIVIDER )
+ eStyle = POINTER_HSIZEBAR;
+ Pointer aPtr( eStyle );
+ SetPointer( aPtr );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( rTEvt.IsTrackingEnded() )
+ ImplEndDrag( rTEvt.IsTrackingCanceled() );
+ else
+ ImplDrag( aMousePos );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Paint( const Rectangle& rRect )
+{
+ if ( mnBorderOff1 || mnBorderOff2 )
+ {
+ SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
+ if ( mnBorderOff1 )
+ DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
+ if ( mnBorderOff2 )
+ DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
+ // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
+ if ( mnBorderOff1 && mnBorderOff2 )
+ {
+ DrawLine( Point( 0, 0 ), Point( 0, mnDY-1 ) );
+ DrawLine( Point( mnDX-1, 0 ), Point( mnDX-1, mnDY-1 ) );
+ }
+ }
+
+ USHORT nCurItemPos;
+ if ( mbDrag )
+ nCurItemPos = GetItemPos( mnCurItemId );
+ else
+ nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ ImplDrawItem( i, (i == nCurItemPos) ? TRUE : FALSE, FALSE, &rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Rectangle aRect( aPos, aSize );
+ Font aFont = GetDrawPixelFont( pDev );
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) )
+ {
+ pDev->DrawWallpaper( aRect, GetBackground() );
+ if ( mnBorderOff1 || mnBorderOff2 )
+ {
+ pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
+ if ( mnBorderOff1 )
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
+ if ( mnBorderOff2 )
+ pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
+ // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
+ if ( mnBorderOff1 && mnBorderOff2 )
+ {
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
+ pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) );
+ }
+ }
+ }
+
+ Rectangle aItemRect( aRect );
+// aItemRect.Bottom()--;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ {
+ aItemRect.Left() = aRect.Left()+ImplGetItemPos( i );
+ aItemRect.Right() = aItemRect.Left() + mpItemList->GetObject( i )->mnSize - 1;
+ // Gegen Ueberlauf auf einigen Systemen testen
+ if ( aItemRect.Right() > 16000 )
+ aItemRect.Right() = 16000;
+ Region aRegion( aRect );
+ pDev->SetClipRegion( aRegion );
+ ImplDrawItem( pDev, i, FALSE, FALSE, aItemRect, &aRect, nFlags );
+ pDev->SetClipRegion();
+ }
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Resize()
+{
+ Size aSize = GetOutputSizePixel();
+ if ( IsVisible() && (mnDY != aSize.Height()) )
+ Invalidate();
+ mnDX = aSize.Width();
+ mnDY = aSize.Height();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag )
+ {
+ ImplStartDrag( rCEvt.GetMousePosPixel(), TRUE );
+ return;
+ }
+
+ Window::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ Rectangle aItemRect = GetItemRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+
+ XubString aStr = GetHelpText( nItemId );
+ if ( !aStr.Len() || !(rHEvt.GetMode() & HELPMODE_BALLOON) )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( GetItemPos( nItemId ) );
+ // Wir zeigen die Quick-Hilfe nur an, wenn Text nicht
+ // vollstaendig sichtbar, ansonsten zeigen wir den Hilfetext
+ // an, wenn das Item keinen Text besitzt
+ if ( pItem->maOutText != pItem->maText )
+ aStr = pItem->maText;
+ else if ( pItem->maText.Len() )
+ aStr.Erase();
+ }
+
+ if ( aStr.Len() )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ return;
+ }
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId, this );
+ return;
+ }
+ }
+ }
+
+ Window::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ENABLE )
+ Invalidate();
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::StartDrag()
+{
+ maStartDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Drag()
+{
+ maDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::EndDrag()
+{
+ maEndDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::InsertItem( USHORT nItemId, const Image& rImage,
+ long nSize, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
+ "HeaderBar::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplHeadItem* pItem = new ImplHeadItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnSize = nSize;
+ pItem->maImage = rImage;
+ pItem->mpUserData = 0;
+ mpItemList->Insert( pItem, nPos );
+
+ // Ausgabe updaten
+ ImplUpdate( nPos, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::InsertItem( USHORT nItemId, const XubString& rText,
+ long nSize, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
+ "HeaderBar::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplHeadItem* pItem = new ImplHeadItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnSize = nSize;
+ pItem->mnHelpId = 0;
+ pItem->maText = rText;
+ pItem->mpUserData = 0;
+ mpItemList->Insert( pItem, nPos );
+
+ // Ausgabe updaten
+ ImplUpdate( nPos, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::InsertItem( USHORT nItemId,
+ const Image& rImage, const XubString& rText,
+ long nSize, HeaderBarItemBits nBits,
+ USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
+ "HeaderBar::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplHeadItem* pItem = new ImplHeadItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnSize = nSize;
+ pItem->mnHelpId = 0;
+ pItem->maImage = rImage;
+ pItem->maText = rText;
+ pItem->mpUserData = 0;
+ mpItemList->Insert( pItem, nPos );
+
+ // Ausgabe updaten
+ ImplUpdate( nPos, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::RemoveItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->Remove( nPos );
+ delete pItem;
+ ImplUpdate( nPos, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::MoveItem( USHORT nItemId, USHORT nNewPos )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ if ( nPos != nNewPos )
+ {
+ ImplHeadItem* pItem = mpItemList->Remove( nPos );
+ if ( nNewPos < nPos )
+ nPos = nNewPos;
+ mpItemList->Insert( pItem, nNewPos );
+ ImplUpdate( nPos, TRUE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Clear()
+{
+ // Alle Items loeschen
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+ mpItemList->Clear();
+
+ ImplUpdate( 0, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetOffset( long nNewOffset )
+{
+ // Hier erstmal neu zeichnen, damit mit alten Offset noch das
+ // richtige gemalt wird
+ //Update();
+
+ // Bereich verschieben
+ Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
+ long nDelta = mnOffset-nNewOffset;
+ mnOffset = nNewOffset;
+ Scroll( nDelta, 0, aRect );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemPos( USHORT nItemId ) const
+{
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return (USHORT)mpItemList->GetCurPos();
+ pItem = mpItemList->Next();
+ }
+
+ return HEADERBAR_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemId( USHORT nPos ) const
+{
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemId( const Point& rPos ) const
+{
+ USHORT nPos = 0;
+ while ( nPos < mpItemList->Count() )
+ {
+ if ( ImplGetItemRect( nPos ).IsInside( rPos ) )
+ return GetItemId( nPos );
+
+ nPos++;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle HeaderBar::GetItemRect( USHORT nItemId ) const
+{
+ Rectangle aRect;
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ aRect = ImplGetItemRect( nPos );
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemSize( USHORT nItemId, long nNewSize )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mnSize != nNewSize )
+ {
+ pItem->mnSize = nNewSize;
+ ImplUpdate( nPos, TRUE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long HeaderBar::GetItemSize( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnSize;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemBits( USHORT nItemId, HeaderBarItemBits nNewBits )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mnBits != nNewBits )
+ {
+ pItem->mnBits = nNewBits;
+ ImplUpdate( nPos );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBarItemBits HeaderBar::GetItemBits( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemData( USHORT nItemId, void* pNewData )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->mpUserData = pNewData;
+ ImplUpdate( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* HeaderBar::GetItemData( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mpUserData;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemImage( USHORT nItemId, const Image& rImage )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->maImage = rImage;
+ ImplUpdate( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image HeaderBar::GetItemImage( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maImage;
+ else
+ return Image();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->maText = rText;
+ ImplUpdate( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString HeaderBar::GetItemText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maText;
+ else
+ return String();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetHelpText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+XubString HeaderBar::GetHelpText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetHelpId( USHORT nItemId, ULONG nHelpId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG HeaderBar::GetHelpId( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnHelpId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Size HeaderBar::CalcWindowSizePixel() const
+{
+ long nMaxImageSize = 0;
+ Size aSize( 0, GetTextHeight() );
+
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Image-Groessen beruecksichtigen
+ long nImageHeight = pItem->maImage.GetSizePixel().Height();
+ if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.Len() )
+ nImageHeight += aSize.Height();
+ if ( nImageHeight > nMaxImageSize )
+ nMaxImageSize = nImageHeight;
+
+ // Breite aufaddieren
+ aSize.Width() += pItem->mnSize;
+
+ pItem = mpItemList->Next();
+ }
+
+ if ( nMaxImageSize > aSize.Height() )
+ aSize.Height() = nMaxImageSize;
+
+ // Border aufaddieren
+ if ( mbButtonStyle )
+ aSize.Height() += 4;
+ else
+ aSize.Height() += 2;
+ aSize.Height() += mnBorderOff1+mnBorderOff2;
+
+ return aSize;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HeaderBar::CreateAccessible()
+{
+ if ( !mxAccessible.is() )
+ {
+ if ( maCreateAccessibleHdl.IsSet() )
+ maCreateAccessibleHdl.Call( this );
+
+ if ( !mxAccessible.is() )
+ mxAccessible = Window::CreateAccessible();
+ }
+
+ return mxAccessible;
+}
+
+void HeaderBar::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > _xAccessible )
+{
+ mxAccessible = _xAccessible;
+}
+
diff --git a/svtools/source/control/hyperlabel.cxx b/svtools/source/control/hyperlabel.cxx
new file mode 100644
index 000000000000..10ef8cdcfadf
--- /dev/null
+++ b/svtools/source/control/hyperlabel.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_svtools.hxx"
+#ifndef SVTOOLS_ROADMAP_HXX
+#include <svtools/hyperlabel.hxx>
+#endif
+#include <vcl/bitmap.hxx>
+#include <tools/color.hxx>
+
+#ifndef _VCL_TABPAGE_HXX
+#include <vcl/tabpage.hxx>
+#endif
+
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ //=====================================================================
+ //= FontChanger
+ //=====================================================================
+ class FontChanger
+ {
+ protected:
+ OutputDevice* m_pDev;
+
+ public:
+ FontChanger( OutputDevice* _pDev, const Font& _rNewFont )
+ :m_pDev( _pDev )
+ {
+ m_pDev->Push( PUSH_FONT );
+ m_pDev->SetFont( _rNewFont );
+ }
+
+ ~FontChanger()
+ {
+ m_pDev->Pop( );
+ }
+ };
+
+ class HyperLabelImpl
+ {
+ public:
+ sal_Int16 ID;
+ sal_Int32 Index;
+ sal_Bool bInteractive;
+ Size m_aMinSize;
+ sal_Bool m_bHyperMode;
+
+ HyperLabelImpl();
+ };
+
+ //---------------------------------------------------------------------
+ HyperLabelImpl::HyperLabelImpl()
+ {
+ }
+
+ HyperLabel::HyperLabel( Window* _pParent, const ResId& _rId )
+ :FixedText( _pParent, _rId )
+ ,m_pImpl( new HyperLabelImpl )
+ {
+ implInit();
+ }
+
+ HyperLabel::HyperLabel( Window* _pParent, WinBits _nWinStyle )
+ :FixedText( _pParent, _nWinStyle )
+ ,m_pImpl( new HyperLabelImpl )
+ {
+ implInit();
+ }
+
+
+ sal_Int32 HyperLabel::GetLogicWidth()
+ {
+ Size rLogicLocSize = PixelToLogic( m_pImpl->m_aMinSize, MAP_APPFONT );
+ return rLogicLocSize.Width();
+ }
+
+
+ Size HyperLabel::CalcMinimumSize( long nMaxWidth ) const
+ {
+ m_pImpl->m_aMinSize = FixedText::CalcMinimumSize( nMaxWidth );
+ // the MinimumSize is used to size the FocusRectangle
+ // and for the MouseMove method
+ m_pImpl->m_aMinSize.Height() += 2;
+ m_pImpl->m_aMinSize.Width() += 1;
+ return m_pImpl->m_aMinSize;
+ }
+
+ void HyperLabel::implInit()
+ {
+ ToggleBackgroundColor( COL_TRANSPARENT );
+
+ WinBits nWinStyle = GetStyle();
+ nWinStyle |= WB_EXTRAOFFSET;
+ SetStyle( nWinStyle );
+
+ Show();
+ }
+
+ void HyperLabel::ToggleBackgroundColor( const Color& _rGBColor )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetControlBackground( _rGBColor );
+ if (_rGBColor == COL_TRANSPARENT)
+ SetTextColor( rStyleSettings.GetFieldTextColor( ) );
+ else
+ SetTextColor( rStyleSettings.GetHighlightTextColor( ) );
+ }
+
+
+ void HyperLabel::MouseMove( const MouseEvent& rMEvt )
+ {
+ Font aFont = GetControlFont( );
+ const Color aColor = GetTextColor();
+
+ if (rMEvt.IsLeaveWindow())
+ {
+ DeactivateHyperMode(aFont, aColor);
+ }
+ else
+ {
+ Point aPoint = GetPointerPosPixel();
+ if (aPoint.X() < m_pImpl->m_aMinSize.Width())
+ {
+ if ( IsEnabled() && (m_pImpl->bInteractive) )
+ {
+ ActivateHyperMode( aFont, aColor);
+ return;
+ }
+ }
+ DeactivateHyperMode(aFont, aColor);
+ }
+ }
+
+ void HyperLabel::ActivateHyperMode(Font aFont, const Color aColor)
+ {
+ aFont.SetUnderline(UNDERLINE_SINGLE);
+ m_pImpl->m_bHyperMode = sal_True;
+ SetPointer( POINTER_REFHAND );
+ SetControlFont( aFont);
+ SetTextColor( aColor);
+
+ }
+
+ void HyperLabel::DeactivateHyperMode(Font aFont, const Color aColor)
+ {
+ m_pImpl->m_bHyperMode = sal_False;
+ aFont.SetUnderline(UNDERLINE_NONE);
+ SetPointer( POINTER_ARROW );
+ SetControlFont( aFont);
+ SetTextColor( aColor);
+ }
+
+ void HyperLabel::MouseButtonDown( const MouseEvent& )
+ {
+ if ( m_pImpl->m_bHyperMode && m_pImpl->bInteractive )
+ {
+ maClickHdl.Call( this );
+ }
+ }
+
+ void HyperLabel::GetFocus()
+ {
+ if ( IsEnabled() && m_pImpl->bInteractive )
+ {
+ Point aPoint(0,0);
+ Rectangle rRect(aPoint, Size( m_pImpl->m_aMinSize.Width(), GetSizePixel().Height() ) );
+ ShowFocus( rRect );
+ }
+ }
+
+ void HyperLabel::LoseFocus()
+ {
+ HideFocus();
+ }
+
+ HyperLabel::~HyperLabel( )
+ {
+ delete m_pImpl;
+ }
+
+ void HyperLabel::SetInteractive( sal_Bool _bInteractive )
+ {
+ m_pImpl->bInteractive = ( _bInteractive && IsEnabled() );
+ }
+
+ sal_Int16 HyperLabel::GetID() const
+ {
+ return m_pImpl->ID;
+ }
+
+ sal_Int32 HyperLabel::GetIndex() const
+ {
+ return m_pImpl->Index;
+ }
+
+ void HyperLabel::SetID( sal_Int16 _ID )
+ {
+ m_pImpl->ID = _ID;
+ }
+
+ void HyperLabel::SetIndex( sal_Int32 _Index )
+ {
+ m_pImpl->Index = _Index;
+ }
+
+ ::rtl::OUString HyperLabel::GetLabel( )
+ {
+ return GetText();
+ }
+
+ void HyperLabel::SetLabel( const ::rtl::OUString& _rText )
+ {
+ SetText(_rText);
+ }
+
+
+ //------------------------------------------------------------------------------
+ void HyperLabel::DataChanged( const DataChangedEvent& rDCEvt )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ FixedText::DataChanged( rDCEvt );
+ if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
+ ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
+ {
+ const Color& rGBColor = GetControlBackground();
+ if (rGBColor == COL_TRANSPARENT)
+ SetTextColor( rStyleSettings.GetFieldTextColor( ) );
+ else
+ {
+ SetControlBackground(rStyleSettings.GetHighlightColor());
+ SetTextColor( rStyleSettings.GetHighlightTextColor( ) );
+ }
+ Invalidate();
+ }
+ }
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
+
diff --git a/svtools/source/control/indexentryres.cxx b/svtools/source/control/indexentryres.cxx
new file mode 100755
index 000000000000..5a79edab5b77
--- /dev/null
+++ b/svtools/source/control/indexentryres.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_svtools.hxx"
+#include <svtools/svtdata.hxx>
+#include <svtools/svtools.hrc>
+
+
+#include <indexentryres.hxx>
+
+// -------------------------------------------------------------------------
+//
+// wrapper for locale specific translations data of indexentry algorithm
+//
+// -------------------------------------------------------------------------
+
+class IndexEntryRessourceData
+{
+ friend class IndexEntryRessource;
+ private: /* data */
+ String ma_Name;
+ String ma_Translation;
+ private: /* member functions */
+ IndexEntryRessourceData () {}
+ public:
+ IndexEntryRessourceData ( const String &r_Algorithm, const String &r_Translation)
+ : ma_Name (r_Algorithm), ma_Translation (r_Translation) {}
+
+ const String& GetAlgorithm () const { return ma_Name; }
+
+ const String& GetTranslation () const { return ma_Translation; }
+
+ ~IndexEntryRessourceData () {}
+
+ IndexEntryRessourceData& operator= (const IndexEntryRessourceData& r_From)
+ {
+ ma_Name = r_From.GetAlgorithm();
+ ma_Translation = r_From.GetTranslation();
+ return *this;
+ }
+};
+
+// -------------------------------------------------------------------------
+//
+// implementation of the indexentry-algorithm-name translation
+//
+// -------------------------------------------------------------------------
+
+#define INDEXENTRY_RESSOURCE_COUNT (STR_SVT_INDEXENTRY_END - STR_SVT_INDEXENTRY_START + 1)
+
+IndexEntryRessource::IndexEntryRessource()
+{
+ mp_Data = new IndexEntryRessourceData[INDEXENTRY_RESSOURCE_COUNT];
+
+ #define ASCSTR(str) String(RTL_CONSTASCII_USTRINGPARAM(str))
+ #define RESSTR(rid) String(SvtResId(rid))
+
+ mp_Data[STR_SVT_INDEXENTRY_ALPHANUMERIC - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("alphanumeric"), RESSTR(STR_SVT_INDEXENTRY_ALPHANUMERIC));
+ mp_Data[STR_SVT_INDEXENTRY_DICTIONARY - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("dict"), RESSTR(STR_SVT_INDEXENTRY_DICTIONARY));
+ mp_Data[STR_SVT_INDEXENTRY_PINYIN - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("pinyin"), RESSTR(STR_SVT_INDEXENTRY_PINYIN));
+ mp_Data[STR_SVT_INDEXENTRY_PINYIN - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("radical"), RESSTR(STR_SVT_INDEXENTRY_RADICAL));
+ mp_Data[STR_SVT_INDEXENTRY_STROKE - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("stroke"), RESSTR(STR_SVT_INDEXENTRY_STROKE));
+ mp_Data[STR_SVT_INDEXENTRY_STROKE - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("zhuyin"), RESSTR(STR_SVT_INDEXENTRY_ZHUYIN));
+ mp_Data[STR_SVT_INDEXENTRY_ZHUYIN - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("phonetic (alphanumeric first) (grouped by syllable)"),
+ RESSTR(STR_SVT_INDEXENTRY_PHONETIC_FS));
+ mp_Data[STR_SVT_INDEXENTRY_PHONETIC_FS - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("phonetic (alphanumeric first) (grouped by consonant)"),
+ RESSTR(STR_SVT_INDEXENTRY_PHONETIC_FC));
+ mp_Data[STR_SVT_INDEXENTRY_PHONETIC_FC - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("phonetic (alphanumeric last) (grouped by syllable)"),
+ RESSTR(STR_SVT_INDEXENTRY_PHONETIC_LS));
+ mp_Data[STR_SVT_INDEXENTRY_PHONETIC_LS - STR_SVT_INDEXENTRY_START] =
+ IndexEntryRessourceData (ASCSTR("phonetic (alphanumeric last) (grouped by consonant)"),
+ RESSTR(STR_SVT_INDEXENTRY_PHONETIC_LC));
+}
+
+IndexEntryRessource::~IndexEntryRessource()
+{
+ delete[] mp_Data;
+}
+
+const String&
+IndexEntryRessource::GetTranslation (const String &r_Algorithm)
+{
+ xub_StrLen nIndex = r_Algorithm.Search('.');
+ String aLocaleFreeAlgorithm;
+
+ if (nIndex == STRING_NOTFOUND)
+ aLocaleFreeAlgorithm = r_Algorithm;
+ else {
+ nIndex += 1;
+ aLocaleFreeAlgorithm = String(r_Algorithm, nIndex, r_Algorithm.Len() - nIndex);
+ }
+
+ for (sal_uInt32 i = 0; i < INDEXENTRY_RESSOURCE_COUNT; i++)
+ if (aLocaleFreeAlgorithm == mp_Data[i].GetAlgorithm())
+ return mp_Data[i].GetTranslation();
+ return r_Algorithm;
+}
+
diff --git a/svtools/source/control/inettbc.cxx b/svtools/source/control/inettbc.cxx
new file mode 100644
index 000000000000..02a578629039
--- /dev/null
+++ b/svtools/source/control/inettbc.cxx
@@ -0,0 +1,1375 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifdef UNX
+#include <pwd.h>
+#include <sys/types.h>
+#endif
+
+
+#include <svtools/inettbc.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+
+#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HDL_
+#include <com/sun/star/task/XInteractionHandler.hdl>
+#endif
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+
+#include <vcl/toolbox.hxx>
+#ifndef _VOS_THREAD_HXX //autogen
+#include <vos/thread.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX //autogen
+#include <vos/mutex.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <unotools/historyoptions.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/itemset.hxx>
+#include "svl/urihelper.hxx"
+#include <unotools/pathoptions.hxx>
+
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <ucbhelper/content.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+
+#include "iodlg.hrc"
+#include <asynclink.hxx>
+#include <svl/urlfilter.hxx>
+
+#include <vector>
+#include <algorithm>
+
+// -----------------------------------------------------------------------
+
+using namespace ::rtl;
+using namespace ::ucbhelper;
+using namespace ::utl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+
+// -----------------------------------------------------------------------
+class SvtURLBox_Impl
+{
+public:
+ SvStringsDtor* pURLs;
+ SvStringsDtor* pCompletions;
+ const IUrlFilter* pUrlFilter;
+ ::std::vector< WildCard > m_aFilters;
+
+ static sal_Bool TildeParsing( String& aText, String& aBaseUrl );
+
+ inline SvtURLBox_Impl( )
+ :pURLs( NULL )
+ ,pCompletions( NULL )
+ ,pUrlFilter( NULL )
+ {
+ FilterMatch::createWildCardFilterList(String(),m_aFilters);
+ }
+};
+
+// -----------------------------------------------------------------------
+class SvtMatchContext_Impl : public ::vos::OThread
+{
+ static ::vos::OMutex* pDirMutex;
+
+ SvStringsDtor aPickList;
+ SvStringsDtor* pCompletions;
+ SvStringsDtor* pURLs;
+ svtools::AsynchronLink aLink;
+ String aBaseURL;
+ String aText;
+ SvtURLBox* pBox;
+ BOOL bStop;
+ BOOL bOnlyDirectories;
+ BOOL bNoSelection;
+
+ DECL_STATIC_LINK( SvtMatchContext_Impl, Select_Impl, void* );
+
+ virtual void SAL_CALL onTerminated( );
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL Cancel();
+ void Insert( const String& rCompletion, const String& rURL, BOOL bForce = FALSE);
+ void ReadFolder( const String& rURL, const String& rMatch, BOOL bSmart );
+ void FillPicklist( SvStringsDtor& rPickList );
+
+public:
+ static ::vos::OMutex* GetMutex();
+
+ SvtMatchContext_Impl( SvtURLBox* pBoxP, const String& rText );
+ ~SvtMatchContext_Impl();
+ void Stop();
+};
+
+::vos::OMutex* SvtMatchContext_Impl::pDirMutex = 0;
+
+::vos::OMutex* SvtMatchContext_Impl::GetMutex()
+{
+ ::vos::OGuard aGuard( ::vos::OMutex::getGlobalMutex() );
+ if( !pDirMutex )
+ pDirMutex = new ::vos::OMutex;
+ return pDirMutex;
+}
+
+//-------------------------------------------------------------------------
+SvtMatchContext_Impl::SvtMatchContext_Impl(
+ SvtURLBox* pBoxP, const String& rText )
+ : aLink( STATIC_LINK( this, SvtMatchContext_Impl, Select_Impl ) )
+ , aBaseURL( pBoxP->aBaseURL )
+ , aText( rText )
+ , pBox( pBoxP )
+ , bStop( FALSE )
+ , bOnlyDirectories( pBoxP->bOnlyDirectories )
+ , bNoSelection( pBoxP->bNoSelection )
+{
+ pURLs = new SvStringsDtor;
+ pCompletions = new SvStringsDtor;
+
+ aLink.CreateMutex();
+
+ FillPicklist( aPickList );
+
+ create();
+}
+
+//-------------------------------------------------------------------------
+SvtMatchContext_Impl::~SvtMatchContext_Impl()
+{
+ aLink.ClearPendingCall();
+ delete pURLs;
+ delete pCompletions;
+}
+
+//-------------------------------------------------------------------------
+void SvtMatchContext_Impl::FillPicklist( SvStringsDtor& rPickList )
+{
+ // Einlesung der Historypickliste
+ Sequence< Sequence< PropertyValue > > seqPicklist = SvtHistoryOptions().GetList( eHISTORY );
+ sal_uInt32 nCount = seqPicklist.getLength();
+
+ for( sal_uInt32 nItem=0; nItem < nCount; nItem++ )
+ {
+ Sequence< PropertyValue > seqPropertySet = seqPicklist[ nItem ];
+
+ OUString sTitle;
+ INetURLObject aURL;
+
+ sal_uInt32 nPropertyCount = seqPropertySet.getLength();
+
+ for( sal_uInt32 nProperty=0; nProperty < nPropertyCount; nProperty++ )
+ {
+ if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_TITLE )
+ {
+ seqPropertySet[nProperty].Value >>= sTitle;
+ aURL.SetURL( sTitle );
+ const StringPtr pStr = new String( aURL.GetMainURL( INetURLObject::DECODE_WITH_CHARSET ) );
+ rPickList.Insert( pStr, (USHORT) nItem );
+ break;
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SvtMatchContext_Impl::Cancel()
+{
+ // Cancel button pressed
+ terminate();
+}
+
+//-------------------------------------------------------------------------
+void SvtMatchContext_Impl::Stop()
+{
+ bStop = TRUE;
+
+ if( isRunning() )
+ terminate();
+}
+
+//-------------------------------------------------------------------------
+void SvtMatchContext_Impl::onTerminated( )
+{
+ aLink.Call( this );
+}
+
+//-------------------------------------------------------------------------
+// This method is called via AsynchronLink, so it has the SolarMutex and
+// calling solar code ( VCL ... ) is safe. It is called when the thread is
+// terminated ( finished work or stopped ). Cancelling the thread via
+// Cancellable does not not discard the information gained so far, it
+// inserts all collected completions into the listbox.
+
+IMPL_STATIC_LINK( SvtMatchContext_Impl, Select_Impl, void*, )
+{
+ // avoid recursion through cancel button
+ if( pThis->bStop )
+ {
+ // completions was stopped, no display
+ delete pThis;
+ return 0;
+ }
+
+ SvtURLBox* pBox = pThis->pBox;
+ pBox->bAutoCompleteMode = TRUE;
+
+ // did we filter completions which otherwise would have been valid?
+ // (to be filled below)
+ bool bValidCompletionsFiltered = false;
+
+ // insert all completed strings into the listbox
+ pBox->Clear();
+
+ for( USHORT nPos = 0; nPos<pThis->pCompletions->Count(); nPos++ )
+ {
+ String sCompletion( *(*pThis->pCompletions)[nPos] );
+
+ // convert the file into an URL
+ String sURL( sCompletion );
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCompletion, sURL );
+ // note: if this doesn't work, we're not interested in: we're checking the
+ // untouched sCompletion then
+
+ if ( pBox->pImp->pUrlFilter )
+ {
+ if ( !pBox->pImp->pUrlFilter->isUrlAllowed( sURL ) )
+ { // this URL is not allowed
+ bValidCompletionsFiltered = true;
+ continue;
+ }
+ }
+ if (( sURL.Len() > 0 ) && ( sURL.GetChar(sURL.Len()-1) != '/' ))
+ {
+ String sUpperURL( sURL );
+ sUpperURL.ToUpperAscii();
+
+ ::std::vector< WildCard >::const_iterator aMatchingFilter =
+ ::std::find_if(
+ pBox->pImp->m_aFilters.begin(),
+ pBox->pImp->m_aFilters.end(),
+ FilterMatch( sUpperURL )
+ );
+ if ( aMatchingFilter == pBox->pImp->m_aFilters.end() )
+
+ { // this URL is not allowed
+ bValidCompletionsFiltered = true;
+ continue;
+ }
+ }
+
+ pBox->InsertEntry( sCompletion );
+ }
+
+ if( !pThis->bNoSelection && pThis->pCompletions->Count() && !bValidCompletionsFiltered )
+ {
+ // select the first one
+ String aTmp( pBox->GetEntry(0) );
+ pBox->SetText( aTmp );
+ pBox->SetSelection( Selection( pThis->aText.Len(), aTmp.Len() ) );
+ }
+
+ // transfer string lists to listbox and forget them
+ delete pBox->pImp->pURLs;
+ delete pBox->pImp->pCompletions;
+ pBox->pImp->pURLs = pThis->pURLs;
+ pBox->pImp->pCompletions = pThis->pCompletions;
+ pThis->pURLs = NULL;
+ pThis->pCompletions = NULL;
+
+ // force listbox to resize ( it may be open )
+ pBox->Resize();
+
+ // the box has this control as a member so we have to set that member
+ // to zero before deleting ourself.
+ pBox->pCtx = NULL;
+ delete pThis;
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+void SvtMatchContext_Impl::Insert( const String& rCompletion,
+ const String& rURL,
+ BOOL bForce )
+{
+ if( !bForce )
+ {
+ // avoid doubles
+ for( USHORT nPos = pCompletions->Count(); nPos--; )
+ if( *(*pCompletions)[ nPos ] == rCompletion )
+ return;
+ }
+
+ const StringPtr pCompletion = new String( rCompletion );
+ pCompletions->Insert( pCompletion, pCompletions->Count() );
+ const StringPtr pURL = new String( rURL );
+ pURLs->Insert( pURL, pURLs->Count() );
+}
+
+//-------------------------------------------------------------------------
+void SvtMatchContext_Impl::ReadFolder( const String& rURL,
+ const String& rMatch,
+ BOOL bSmart )
+{
+ // check folder to scan
+ if( !UCBContentHelper::IsFolder( rURL ) )
+ return;
+
+ sal_Bool bPureHomePath = sal_False;
+#ifdef UNX
+ bPureHomePath = aText.Search( '~' ) == 0 && aText.Search( '/' ) == STRING_NOTFOUND;
+#endif
+
+ sal_Bool bExectMatch = bPureHomePath
+ || aText.CompareToAscii( "." ) == COMPARE_EQUAL
+ || (aText.Len() > 1 && aText.Copy( aText.Len() - 2, 2 ).CompareToAscii( "/." ) == COMPARE_EQUAL)
+ || (aText.Len() > 2 && aText.Copy( aText.Len() - 3, 3 ).CompareToAscii( "/.." ) == COMPARE_EQUAL);
+
+ // for pure home pathes ( ~username ) the '.' at the end of rMatch
+ // means that it poits to root catalog
+ // this is done only for file contents since home pathes parsing is usefull only for them
+ if ( bPureHomePath && rMatch.Equals( String::CreateFromAscii( "file:///." ) ) )
+ {
+ // a home that refers to /
+
+ String aNewText( aText );
+ aNewText += '/';
+ Insert( aNewText, rURL, TRUE );
+
+ return;
+ }
+
+ // string to match with
+ INetURLObject aMatchObj( rMatch );
+ String aMatchName;
+
+ if ( rURL != String(aMatchObj.GetMainURL( INetURLObject::NO_DECODE ) ))
+ {
+ aMatchName = aMatchObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+
+ // matching is always done case insensitive, but completion will be case sensitive and case preserving
+ aMatchName.ToLowerAscii();
+
+ // if the matchstring ends with a slash, we must search for this also
+ if ( rMatch.GetChar(rMatch.Len()-1) == '/' )
+ aMatchName += '/';
+ }
+
+ xub_StrLen nMatchLen = aMatchName.Len();
+
+ INetURLObject aFolderObj( rURL );
+ DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+
+ try
+ {
+ uno::Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+
+ Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ),
+ new ::ucbhelper::CommandEnvironment( uno::Reference< XInteractionHandler >(),
+ uno::Reference< XProgressHandler >() ) );
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(2);
+ OUString* pProps = aProps.getArray();
+ pProps[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
+ pProps[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) );
+
+ try
+ {
+ uno::Reference< XDynamicResultSet > xDynResultSet;
+ ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS;
+ if ( bOnlyDirectories )
+ eInclude = INCLUDE_FOLDERS_ONLY;
+
+ xDynResultSet = aCnt.createDynamicCursor( aProps, eInclude );
+
+ uno::Reference < XAnyCompareFactory > xCompare;
+ uno::Reference < XSortedDynamicResultSetFactory > xSRSFac(
+ xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SortedDynamicResultSetFactory") ) ), UNO_QUERY );
+
+ Sequence< NumberedSortingInfo > aSortInfo( 2 );
+ NumberedSortingInfo* pInfo = aSortInfo.getArray();
+ pInfo[ 0 ].ColumnIndex = 2;
+ pInfo[ 0 ].Ascending = sal_False;
+ pInfo[ 1 ].ColumnIndex = 1;
+ pInfo[ 1 ].Ascending = sal_True;
+
+ uno::Reference< XDynamicResultSet > xDynamicResultSet;
+ xDynamicResultSet =
+ xSRSFac->createSortedDynamicResultSet( xDynResultSet, aSortInfo, xCompare );
+
+ if ( xDynamicResultSet.is() )
+ {
+ xResultSet = xDynamicResultSet->getStaticResultSet();
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( schedule() && xResultSet->next() )
+ {
+ String aURL = xContentAccess->queryContentIdentifierString();
+ String aTitle = xRow->getString(1);
+ sal_Bool bIsFolder = xRow->getBoolean(2);
+
+ // matching is always done case insensitive, but completion will be case sensitive and case preserving
+ aTitle.ToLowerAscii();
+
+ if (
+ !nMatchLen ||
+ (bExectMatch && aMatchName.Equals(aTitle)) ||
+ (!bExectMatch && aMatchName.CompareTo(aTitle, nMatchLen) == COMPARE_EQUAL)
+ )
+ {
+ // all names fit if matchstring is empty
+ INetURLObject aObj( aURL );
+ sal_Unicode aDelimiter = '/';
+ if ( bSmart )
+ // when parsing is done "smart", the delimiter must be "guessed"
+ aObj.getFSysPath( (INetURLObject::FSysStyle)(INetURLObject::FSYS_DETECT & ~INetURLObject::FSYS_VOS), &aDelimiter );
+
+ if ( bIsFolder )
+ aObj.setFinalSlash();
+
+ // get the last name of the URL
+ String aMatch = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ String aInput( aText );
+ if ( nMatchLen )
+ {
+ if ((aText.Len() && aText.GetChar(aText.Len() - 1) == '.') || bPureHomePath)
+ {
+ // if a "special folder" URL was typed, don't touch the user input
+ aMatch.Erase( 0, nMatchLen );
+ }
+ else
+ {
+ // make the user input case preserving
+ DBG_ASSERT( aInput.Len() >= nMatchLen, "Suspicious Matching!" );
+ aInput.Erase( aInput.Len() - nMatchLen );
+ }
+ }
+
+ aInput += aMatch;
+
+ // folders should get a final slash automatically
+ if ( bIsFolder )
+ aInput += aDelimiter;
+
+ Insert( aInput, aObj.GetMainURL( INetURLObject::NO_DECODE ), TRUE );
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+//-------------------------------------------------------------------------
+String SvtURLBox::ParseSmart( String aText, String aBaseURL, String aWorkDir )
+{
+ String aMatch;
+
+ // parse ~ for Unix systems
+ // does nothing for Windows
+ if( !SvtURLBox_Impl::TildeParsing( aText, aBaseURL ) )
+ return String();
+
+ INetURLObject aURLObject;
+ if( aBaseURL.Len() )
+ {
+ INetProtocol eBaseProt = INetURLObject::CompareProtocolScheme( aBaseURL );
+
+ // if a base URL is set the string may be parsed relative
+ if( aText.Search( '/' ) == 0 )
+ {
+ // text starting with slashes means absolute file URLs
+ String aTemp = INetURLObject::GetScheme( eBaseProt );
+
+ // file URL must be correctly encoded!
+ String aTextURL = INetURLObject::encode( aText, INetURLObject::PART_FPATH,
+ '%', INetURLObject::ENCODE_ALL );
+ aTemp += aTextURL;
+
+ INetURLObject aTmp( aTemp );
+ if ( !aTmp.HasError() && aTmp.GetProtocol() != INET_PROT_NOT_VALID )
+ aMatch = aTmp.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ String aSmart( aText );
+ INetURLObject aObj( aBaseURL );
+
+ // HRO: I suppose this hack should only be done for Windows !!!???
+#ifdef WNT
+ // HRO: INetURLObject::smatRel2Abs does not recognize '\\' as a relative path
+ // but in case of "\\\\" INetURLObject is right - this is an absolute path !
+
+ if( aText.Search( '\\' ) == 0 && (aText.Len() < 2 || aText.GetChar( 1 ) != '\\') )
+ {
+ // cut to first segment
+ String aTmp = INetURLObject::GetScheme( eBaseProt );
+ aTmp += '/';
+ aTmp += String(aObj.getName( 0, true, INetURLObject::DECODE_WITH_CHARSET ));
+ aObj.SetURL( aTmp );
+
+ aSmart.Erase(0,1);
+ }
+#endif
+ // base URL must be a directory !
+ aObj.setFinalSlash();
+
+ // take base URL and append current input
+ bool bWasAbsolute = FALSE;
+#ifdef UNX
+ // don't support FSYS_MAC under Unix, because here ':' is a valid character for a filename
+ INetURLObject::FSysStyle eStyle = static_cast< INetURLObject::FSysStyle >( INetURLObject::FSYS_VOS | INetURLObject::FSYS_UNX | INetURLObject::FSYS_DOS );
+ // encode file URL correctly
+ aSmart = INetURLObject::encode( aSmart, INetURLObject::PART_FPATH, '%', INetURLObject::ENCODE_ALL );
+ INetURLObject aTmp( aObj.smartRel2Abs(
+ aSmart, bWasAbsolute, false, INetURLObject::WAS_ENCODED, RTL_TEXTENCODING_UTF8, false, eStyle ) );
+#else
+ INetURLObject aTmp( aObj.smartRel2Abs( aSmart, bWasAbsolute ) );
+#endif
+
+ if ( aText.GetChar( aText.Len() - 1 ) == '.' )
+ // INetURLObject appends a final slash for the directories "." and "..", this is a bug!
+ // Remove it as a workaround
+ aTmp.removeFinalSlash();
+ if ( !aTmp.HasError() && aTmp.GetProtocol() != INET_PROT_NOT_VALID )
+ aMatch = aTmp.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ }
+ else
+ {
+ ::utl::LocalFileHelper::ConvertSystemPathToURL( aText, aWorkDir, aMatch );
+ }
+
+ return aMatch;
+}
+
+//-------------------------------------------------------------------------
+void SvtMatchContext_Impl::run()
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ if( bStop )
+ // have we been stopped while we were waiting for the mutex?
+ return;
+
+ // Reset match lists
+ pCompletions->Remove( 0, pCompletions->Count() );
+ pURLs->Remove( 0, pURLs->Count() );
+
+ // check for input
+ USHORT nTextLen = aText.Len();
+ if ( !nTextLen )
+ return;
+
+ if( aText.Search( '*' ) != STRING_NOTFOUND || aText.Search( '?' ) != STRING_NOTFOUND )
+ // no autocompletion for wildcards
+ return;
+
+ String aMatch;
+ String aWorkDir( SvtPathOptions().GetWorkPath() );
+ INetProtocol eProt = INetURLObject::CompareProtocolScheme( aText );
+ INetProtocol eBaseProt = INetURLObject::CompareProtocolScheme( aBaseURL );
+ if ( !aBaseURL.Len() )
+ eBaseProt = INetURLObject::CompareProtocolScheme( aWorkDir );
+ INetProtocol eSmartProt = pBox->GetSmartProtocol();
+
+ // if the user input is a valid URL, go on with it
+ // otherwise it could be parsed smart with a predefined smart protocol
+ // ( or if this is not set with the protocol of a predefined base URL )
+ if( eProt == INET_PROT_NOT_VALID || eProt == eSmartProt || (eSmartProt == INET_PROT_NOT_VALID && eProt == eBaseProt) )
+ {
+ // not stopped yet ?
+ if( schedule() )
+ {
+ if ( eProt == INET_PROT_NOT_VALID )
+ aMatch = SvtURLBox::ParseSmart( aText, aBaseURL, aWorkDir );
+ else
+ aMatch = aText;
+ if ( aMatch.Len() )
+ {
+ INetURLObject aURLObject( aMatch );
+ String aMainURL( aURLObject.GetMainURL( INetURLObject::NO_DECODE ) );
+ if ( aMainURL.Len() )
+ {
+ // if text input is a directory, it must be part of the match list! Until then it is scanned
+ if ( UCBContentHelper::IsFolder( aMainURL ) && aURLObject.hasFinalSlash() )
+ Insert( aText, aMatch );
+ else
+ // otherwise the parent folder will be taken
+ aURLObject.removeSegment();
+
+ // scan directory and insert all matches
+ ReadFolder( aURLObject.GetMainURL( INetURLObject::NO_DECODE ), aMatch, eProt == INET_PROT_NOT_VALID );
+ }
+ }
+ }
+ }
+
+ if ( bOnlyDirectories )
+ // don't scan history picklist if only directories are allowed, picklist contains only files
+ return;
+
+ BOOL bFull = FALSE;
+ int nCount = aPickList.Count();
+
+ INetURLObject aCurObj;
+ String aEmpty, aCurString, aCurMainURL;
+ INetURLObject aObj;
+ aObj.SetSmartProtocol( eSmartProt == INET_PROT_NOT_VALID ? INET_PROT_HTTP : eSmartProt );
+ for( ;; )
+ {
+ for( USHORT nPos = 0; schedule() && nPos < nCount; nPos++ )
+ {
+ aCurObj.SetURL( *aPickList.GetObject( nPos ) );
+ aCurObj.SetSmartURL( aCurObj.GetURLNoPass());
+ aCurMainURL = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( eProt != INET_PROT_NOT_VALID && aCurObj.GetProtocol() != eProt )
+ continue;
+
+ if( eSmartProt != INET_PROT_NOT_VALID && aCurObj.GetProtocol() != eSmartProt )
+ continue;
+
+ switch( aCurObj.GetProtocol() )
+ {
+ case INET_PROT_HTTP:
+ case INET_PROT_HTTPS:
+ case INET_PROT_FTP:
+ {
+ if( eProt == INET_PROT_NOT_VALID && !bFull )
+ {
+ aObj.SetSmartURL( aText );
+ if( aObj.GetURLPath().getLength() > 1 )
+ continue;
+ }
+
+ aCurString = aCurMainURL;
+ if( eProt == INET_PROT_NOT_VALID )
+ {
+ // try if text matches the scheme
+ String aScheme( INetURLObject::GetScheme( aCurObj.GetProtocol() ) );
+ if ( aText.CompareTo( aScheme, aText.Len() ) == COMPARE_EQUAL && aText.Len() < aScheme.Len() )
+ {
+ if( bFull )
+ aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
+ else
+ {
+ aCurObj.SetMark( aEmpty );
+ aCurObj.SetParam( aEmpty );
+ aCurObj.SetURLPath( aEmpty );
+ aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ Insert( aMatch, aMatch );
+ }
+
+ // now try smart matching
+ aCurString.Erase( 0, aScheme.Len() );
+ }
+
+ if( aText.CompareTo( aCurString, aText.Len() )== COMPARE_EQUAL )
+ {
+ if( bFull )
+ aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
+ else
+ {
+ aCurObj.SetMark( aEmpty );
+ aCurObj.SetParam( aEmpty );
+ aCurObj.SetURLPath( aEmpty );
+ aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ String aURL( aMatch );
+ if( eProt == INET_PROT_NOT_VALID )
+ aMatch.Erase( 0, sal::static_int_cast< xub_StrLen >(INetURLObject::GetScheme( aCurObj.GetProtocol() ).getLength()) );
+
+ if( aText.Len() < aMatch.Len() )
+ Insert( aMatch, aURL );
+
+ continue;
+ }
+ break;
+ }
+ default:
+ {
+ if( bFull )
+ continue;
+
+ if( aText.CompareTo( aCurMainURL, aText.Len() ) == COMPARE_EQUAL )
+ {
+ if( aText.Len() < aCurMainURL.Len() )
+ Insert( aCurMainURL, aCurMainURL );
+
+ continue;
+ }
+ break;
+ }
+ }
+ }
+
+ if( !bFull )
+ bFull = TRUE;
+ else
+ break;
+ }
+
+ return;
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+void SvtURLBox::TryAutoComplete( BOOL bForce )
+{
+ if( Application::AnyInput( INPUT_KEYBOARD ) ) return;
+
+ String aMatchString;
+ String aCurText = GetText();
+ Selection aSelection( GetSelection() );
+ if( aSelection.Max() != aCurText.Len() && !bForce )
+ return;
+ USHORT nLen = (USHORT)aSelection.Min();
+ aCurText.Erase( nLen );
+ if( aCurText.Len() && bIsAutoCompleteEnabled )
+ {
+ if ( pCtx )
+ {
+ pCtx->Stop();
+ pCtx = NULL;
+ }
+ pCtx = new SvtMatchContext_Impl( this, aCurText );
+ }
+}
+
+//-------------------------------------------------------------------------
+SvtURLBox::SvtURLBox( Window* pParent, INetProtocol eSmart )
+ : ComboBox( pParent , WB_DROPDOWN | WB_AUTOSIZE | WB_AUTOHSCROLL ),
+ pCtx( 0 ),
+ eSmartProtocol( eSmart ),
+ bAutoCompleteMode( FALSE ),
+ bOnlyDirectories( FALSE ),
+ bTryAutoComplete( FALSE ),
+ bCtrlClick( FALSE ),
+ bHistoryDisabled( FALSE ),
+ bNoSelection( FALSE ),
+ bIsAutoCompleteEnabled( TRUE )
+{
+ ImplInit();
+
+ if ( GetDesktopRectPixel().GetWidth() > 800 )
+ SetSizePixel( Size( 300, 240 ) );
+ else
+ SetSizePixel( Size( 225, 240 ) );
+}
+
+//-------------------------------------------------------------------------
+SvtURLBox::SvtURLBox( Window* pParent, WinBits _nStyle, INetProtocol eSmart )
+ : ComboBox( pParent, _nStyle ),
+ pCtx( 0 ),
+ eSmartProtocol( eSmart ),
+ bAutoCompleteMode( FALSE ),
+ bOnlyDirectories( FALSE ),
+ bTryAutoComplete( FALSE ),
+ bCtrlClick( FALSE ),
+ bHistoryDisabled( FALSE ),
+ bNoSelection( FALSE ),
+ bIsAutoCompleteEnabled( TRUE )
+{
+ ImplInit();
+}
+
+//-------------------------------------------------------------------------
+SvtURLBox::SvtURLBox( Window* pParent, const ResId& _rResId, INetProtocol eSmart )
+ : ComboBox( pParent , _rResId ),
+ pCtx( 0 ),
+ eSmartProtocol( eSmart ),
+ bAutoCompleteMode( FALSE ),
+ bOnlyDirectories( FALSE ),
+ bTryAutoComplete( FALSE ),
+ bCtrlClick( FALSE ),
+ bHistoryDisabled( FALSE ),
+ bNoSelection( FALSE ),
+ bIsAutoCompleteEnabled( TRUE )
+{
+ ImplInit();
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::ImplInit()
+{
+ pImp = new SvtURLBox_Impl();
+ SetHelpId( SID_OPENURL );
+ EnableAutocomplete( FALSE );
+
+ SetText( String() );
+
+ GetSubEdit()->SetAutocompleteHdl( LINK( this, SvtURLBox, AutoCompleteHdl_Impl ) );
+ UpdatePicklistForSmartProtocol_Impl();
+}
+
+//-------------------------------------------------------------------------
+SvtURLBox::~SvtURLBox()
+{
+ if( pCtx )
+ {
+ pCtx->Stop();
+ pCtx = NULL;
+ }
+
+ delete pImp->pURLs;
+ delete pImp->pCompletions;
+ delete pImp;
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::UpdatePickList( )
+{
+ if( pCtx )
+ {
+ pCtx->Stop();
+ pCtx = NULL;
+ }
+
+ String sText = GetText();
+ if ( sText.Len() && bIsAutoCompleteEnabled )
+ pCtx = new SvtMatchContext_Impl( this, sText );
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::SetSmartProtocol( INetProtocol eProt )
+{
+ if ( eSmartProtocol != eProt )
+ {
+ eSmartProtocol = eProt;
+ UpdatePicklistForSmartProtocol_Impl();
+ }
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::UpdatePicklistForSmartProtocol_Impl()
+{
+ Clear();
+ if ( !bHistoryDisabled )
+ {
+ // read history pick list
+ Sequence< Sequence< PropertyValue > > seqPicklist = SvtHistoryOptions().GetList( eHISTORY );
+ sal_uInt32 nCount = seqPicklist.getLength();
+ INetURLObject aCurObj;
+
+ for( sal_uInt32 nItem=0; nItem < nCount; nItem++ )
+ {
+ Sequence< PropertyValue > seqPropertySet = seqPicklist[ nItem ];
+
+ OUString sURL;
+
+ sal_uInt32 nPropertyCount = seqPropertySet.getLength();
+
+ for( sal_uInt32 nProperty=0; nProperty < nPropertyCount; nProperty++ )
+ {
+ if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_URL )
+ {
+ seqPropertySet[nProperty].Value >>= sURL;
+ aCurObj.SetURL( sURL );
+
+ if ( sURL.getLength() && ( eSmartProtocol != INET_PROT_NOT_VALID ) )
+ {
+ if( aCurObj.GetProtocol() != eSmartProtocol )
+ break;
+ }
+
+ String aURL( aCurObj.GetMainURL( INetURLObject::DECODE_WITH_CHARSET ) );
+
+ if ( aURL.Len() && ( !pImp->pUrlFilter || pImp->pUrlFilter->isUrlAllowed( aURL ) ) )
+ {
+ BOOL bFound = (aURL.GetChar(aURL.Len()-1) == '/' );
+ if ( !bFound )
+ {
+ String aUpperURL( aURL );
+ aUpperURL.ToUpperAscii();
+
+ bFound
+ = (::std::find_if(
+ pImp->m_aFilters.begin(),
+ pImp->m_aFilters.end(),
+ FilterMatch( aUpperURL ) )
+ != pImp->m_aFilters.end());
+ }
+ if ( bFound )
+ {
+ String aFile;
+ if (::utl::LocalFileHelper::ConvertURLToSystemPath(aURL,aFile))
+ InsertEntry(aFile);
+ else
+ InsertEntry(aURL);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+BOOL SvtURLBox::ProcessKey( const KeyCode& rKey )
+{
+ // every key input stops the current matching thread
+ if( pCtx )
+ {
+ pCtx->Stop();
+ pCtx = NULL;
+ }
+
+ KeyCode aCode( rKey.GetCode() );
+ if ( aCode == KEY_RETURN && GetText().Len() )
+ {
+ // wait for completion of matching thread
+ ::vos::OGuard aGuard( SvtMatchContext_Impl::GetMutex() );
+
+ if ( bAutoCompleteMode )
+ {
+ // reset picklist
+ bAutoCompleteMode = FALSE;
+ Selection aSelection( GetSelection() );
+ SetSelection( Selection( aSelection.Min(), aSelection.Min() ) );
+ if ( bOnlyDirectories )
+ Clear();
+ else
+ UpdatePicklistForSmartProtocol_Impl();
+ Resize();
+ }
+
+ bCtrlClick = rKey.IsMod1();
+ BOOL bHandled = FALSE;
+ if ( GetOpenHdl().IsSet() )
+ {
+ bHandled = TRUE;
+ GetOpenHdl().Call(this);
+ }
+ else if ( GetSelectHdl().IsSet() )
+ {
+ bHandled = TRUE;
+ GetSelectHdl().Call(this);
+ }
+
+ bCtrlClick = FALSE;
+
+ ClearModifyFlag();
+ return bHandled;
+ }
+ else if ( aCode == KEY_RETURN && !GetText().Len() && GetOpenHdl().IsSet() )
+ {
+ // for file dialog
+ bAutoCompleteMode = FALSE;
+ GetOpenHdl().Call(this);
+ return TRUE;
+ }
+ else if( aCode == KEY_ESCAPE )
+ {
+ Selection aSelection( GetSelection() );
+ if ( bAutoCompleteMode || aSelection.Min() != aSelection.Max() )
+ {
+ SetSelection( Selection( aSelection.Min(), aSelection.Min() ) );
+ if ( bOnlyDirectories )
+ Clear();
+ else
+ UpdatePicklistForSmartProtocol_Impl();
+ Resize();
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ bAutoCompleteMode = FALSE;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::Modify()
+{
+ ComboBox::Modify();
+}
+
+//-------------------------------------------------------------------------
+long SvtURLBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetWindow() == GetSubEdit() && rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+
+ const KeyEvent& rEvent = *rNEvt.GetKeyEvent();
+ const KeyCode& rKey = rEvent.GetKeyCode();
+ KeyCode aCode( rKey.GetCode() );
+ if( ProcessKey( rKey ) )
+ {
+ return TRUE;
+ }
+ else if( ( aCode == KEY_UP || aCode == KEY_DOWN ) && !rKey.IsMod2() )
+ {
+ Selection aSelection( GetSelection() );
+ USHORT nLen = (USHORT)aSelection.Min();
+ GetSubEdit()->KeyInput( rEvent );
+ SetSelection( Selection( nLen, GetText().Len() ) );
+ return TRUE;
+ }
+
+ if ( MatchesPlaceHolder( GetText() ) )
+ {
+ // set the selection so a key stroke will overwrite
+ // the placeholder rather than edit it
+ SetSelection( Selection( 0, GetText().Len() ) );
+ }
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+//-------------------------------------------------------------------------
+IMPL_LINK( SvtURLBox, AutoCompleteHdl_Impl, void*, EMPTYARG )
+{
+ if ( GetSubEdit()->GetAutocompleteAction() == AUTOCOMPLETE_KEYINPUT )
+ {
+ TryAutoComplete( FALSE );
+ return 1L;
+ }
+
+ return 0L;
+}
+
+//-------------------------------------------------------------------------
+long SvtURLBox::Notify( NotifyEvent &rEvt )
+{
+ if ( EVENT_GETFOCUS == rEvt.GetType() )
+ {
+#ifndef UNX
+ // pb: don't select automatically on unix #93251#
+ SetSelection( Selection( 0, GetText().Len() ) );
+#endif
+ }
+ else if ( EVENT_LOSEFOCUS == rEvt.GetType() )
+ {
+ if( !GetText().Len() )
+ ClearModifyFlag();
+ if ( pCtx )
+ {
+ pCtx->Stop();
+ pCtx = NULL;
+ }
+ }
+
+ return ComboBox::Notify( rEvt );
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::Select()
+{
+ ComboBox::Select();
+ ClearModifyFlag();
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::SetOnlyDirectories( BOOL bDir )
+{
+ bOnlyDirectories = bDir;
+ if ( bOnlyDirectories )
+ Clear();
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::SetNoURLSelection( BOOL bSet )
+{
+ bNoSelection = bSet;
+}
+
+//-------------------------------------------------------------------------
+String SvtURLBox::GetURL()
+{
+ // wait for end of autocompletion
+ ::vos::OGuard aGuard( SvtMatchContext_Impl::GetMutex() );
+
+ String aText( GetText() );
+ if ( MatchesPlaceHolder( aText ) )
+ return aPlaceHolder;
+ // try to get the right case preserving URL from the list of URLs
+ if ( pImp->pCompletions && pImp->pURLs )
+ {
+ for( USHORT nPos=0; nPos<pImp->pCompletions->Count(); nPos++ )
+ {
+#ifdef DBG_UTIL
+ String aTmp( *(*pImp->pCompletions)[ nPos ] );
+#endif
+ if( *(*pImp->pCompletions)[ nPos ] == aText )
+ return *(*pImp->pURLs)[nPos];
+ }
+ }
+
+#ifdef WNT
+ // erase trailing spaces on Windows since thay are invalid on this OS and
+ // most of the time they are inserted by accident via copy / paste
+ aText.EraseTrailingChars();
+ if ( !aText.Len() )
+ return aText;
+ // #i9739# - 2002-12-03 - fs@openoffice.org
+#endif
+
+ INetURLObject aObj( aText );
+ if( aText.Search( '*' ) != STRING_NOTFOUND || aText.Search( '?' ) != STRING_NOTFOUND )
+ {
+ // no autocompletion for wildcards
+ INetURLObject aTempObj;
+ if ( eSmartProtocol != INET_PROT_NOT_VALID )
+ aTempObj.SetSmartProtocol( eSmartProtocol );
+ if ( aTempObj.SetSmartURL( aText ) )
+ return aTempObj.GetMainURL( INetURLObject::NO_DECODE );
+ else
+ return aText;
+ }
+
+ if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ String aName = ParseSmart( aText, aBaseURL, SvtPathOptions().GetWorkPath() );
+ aObj.SetURL( aName );
+ ::rtl::OUString aURL( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
+ if ( !aURL.getLength() )
+ // aText itself is invalid, and even together with aBaseURL, it could not
+ // made valid -> no chance
+ return aText;
+
+ bool bSlash = aObj.hasFinalSlash();
+ {
+ static const rtl::OUString aPropName(
+ rtl::OUString::createFromAscii("CasePreservingURL"));
+
+ rtl::OUString aFileURL;
+
+ Any aAny =
+ UCBContentHelper::GetProperty(aURL,aPropName);
+ sal_Bool success = (aAny >>= aFileURL);
+ String aTitle;
+ if(success)
+ aTitle = String(
+ INetURLObject(aFileURL).getName(
+ INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET ));
+ else
+ success =
+ UCBContentHelper::GetTitle(aURL,aTitle);
+
+ if( success &&
+ ( aTitle.Len() > 1 ||
+ (aTitle.CompareToAscii("/") != 0 &&
+ aTitle.CompareToAscii(".") != 0) ) )
+ {
+ aObj.SetName( aTitle );
+ if ( bSlash )
+ aObj.setFinalSlash();
+ }
+ }
+ }
+
+ return aObj.GetMainURL( INetURLObject::NO_DECODE );
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::DisableHistory()
+{
+ bHistoryDisabled = TRUE;
+ UpdatePicklistForSmartProtocol_Impl();
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::SetBaseURL( const String& rURL )
+{
+ ::vos::OGuard aGuard( SvtMatchContext_Impl::GetMutex() );
+
+ // Reset match lists
+ if ( pImp->pCompletions )
+ pImp->pCompletions->Remove( 0, pImp->pCompletions->Count() );
+
+ if ( pImp->pURLs )
+ pImp->pURLs->Remove( 0, pImp->pURLs->Count() );
+
+ aBaseURL = rURL;
+}
+
+//-------------------------------------------------------------------------
+/** Parse leading ~ for Unix systems,
+ does nothing for Windows
+ */
+sal_Bool SvtURLBox_Impl::TildeParsing(
+ String&
+#ifdef UNX
+ aText
+#endif
+ , String&
+#ifdef UNX
+ aBaseURL
+#endif
+)
+{
+#ifdef UNX
+ if( aText.Search( '~' ) == 0 )
+ {
+ String aParseTilde;
+ sal_Bool bTrailingSlash = sal_True; // use trailing slash
+
+ if( aText.Len() == 1 || aText.GetChar( 1 ) == '/' )
+ {
+ // covers "~" or "~/..." cases
+ const char* aHomeLocation = getenv( "HOME" );
+ if( !aHomeLocation )
+ aHomeLocation = "";
+
+ aParseTilde = String::CreateFromAscii( aHomeLocation );
+
+ // in case the whole path is just "~" then there should
+ // be no trailing slash at the end
+ if( aText.Len() == 1 )
+ bTrailingSlash = sal_False;
+ }
+ else
+ {
+ // covers "~username" and "~username/..." cases
+ xub_StrLen nNameEnd = aText.Search( '/' );
+ String aUserName = aText.Copy( 1, ( nNameEnd != STRING_NOTFOUND ) ? nNameEnd : ( aText.Len() - 1 ) );
+
+ struct passwd* pPasswd = NULL;
+#ifdef SOLARIS
+ Sequence< sal_Int8 > sBuf( 1024 );
+ struct passwd aTmp;
+ sal_Int32 nRes = getpwnam_r( OUStringToOString( OUString( aUserName ), RTL_TEXTENCODING_ASCII_US ).getStr(),
+ &aTmp,
+ (char*)sBuf.getArray(),
+ 1024,
+ &pPasswd );
+ if( !nRes && pPasswd )
+ aParseTilde = String::CreateFromAscii( pPasswd->pw_dir );
+ else
+ return sal_False; // no such user
+#else
+ pPasswd = getpwnam( OUStringToOString( OUString( aUserName ), RTL_TEXTENCODING_ASCII_US ).getStr() );
+ if( pPasswd )
+ aParseTilde = String::CreateFromAscii( pPasswd->pw_dir );
+ else
+ return sal_False; // no such user
+#endif
+
+ // in case the path is "~username" then there should
+ // be no trailing slash at the end
+ if( nNameEnd == STRING_NOTFOUND )
+ bTrailingSlash = sal_False;
+ }
+
+ if( !bTrailingSlash )
+ {
+ if( !aParseTilde.Len() || aParseTilde.EqualsAscii( "/" ) )
+ {
+ // "/" path should be converted to "/."
+ aParseTilde = String::CreateFromAscii( "/." );
+ }
+ else
+ {
+ // "blabla/" path should be converted to "blabla"
+ aParseTilde.EraseTrailingChars( '/' );
+ }
+ }
+ else
+ {
+ if( aParseTilde.GetChar( aParseTilde.Len() - 1 ) != '/' )
+ aParseTilde += '/';
+ if( aText.Len() > 2 )
+ aParseTilde += aText.Copy( 2 );
+ }
+
+ aText = aParseTilde;
+ aBaseURL = String(); // tilde provide absolute path
+ }
+#endif
+
+ return sal_True;
+}
+
+//-------------------------------------------------------------------------
+void SvtURLBox::SetUrlFilter( const IUrlFilter* _pFilter )
+{
+ pImp->pUrlFilter = _pFilter;
+}
+
+//-------------------------------------------------------------------------
+const IUrlFilter* SvtURLBox::GetUrlFilter( ) const
+{
+ return pImp->pUrlFilter;
+}
+// -----------------------------------------------------------------------------
+void SvtURLBox::SetFilter(const String& _sFilter)
+{
+ pImp->m_aFilters.clear();
+ FilterMatch::createWildCardFilterList(_sFilter,pImp->m_aFilters);
+}
+
diff --git a/svtools/source/control/makefile.mk b/svtools/source/control/makefile.mk
new file mode 100755
index 000000000000..a2e622730635
--- /dev/null
+++ b/svtools/source/control/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=ctrl
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES=\
+ ctrltool.src \
+ ctrlbox.src \
+ calendar.src \
+ filectrl.src
+
+EXCEPTIONSFILES=\
+ $(SLO)$/svxbox.obj \
+ $(SLO)$/filectrl2.obj \
+ $(SLO)$/roadmap.obj \
+ $(SLO)$/scriptedtext.obj\
+ $(SLO)$/fmtfield.obj \
+ $(SLO)$/inettbc.obj \
+ $(SLO)$/valueacc.obj \
+ $(SLO)$/toolbarmenu.obj \
+ $(SLO)$/toolbarmenuacc.obj
+
+SLOFILES=\
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/asynclink.obj \
+ $(SLO)$/urlcontrol.obj \
+ $(SLO)$/fileurlbox.obj \
+ $(SLO)$/ctrltool.obj \
+ $(SLO)$/ctrlbox.obj \
+ $(SLO)$/stdctrl.obj \
+ $(SLO)$/stdmenu.obj \
+ $(SLO)$/valueset.obj \
+ $(SLO)$/tabbar.obj \
+ $(SLO)$/headbar.obj \
+ $(SLO)$/prgsbar.obj \
+ $(SLO)$/ruler.obj \
+ $(SLO)$/taskbar.obj \
+ $(SLO)$/taskbox.obj \
+ $(SLO)$/taskstat.obj \
+ $(SLO)$/taskmisc.obj \
+ $(SLO)$/calendar.obj \
+ $(SLO)$/filectrl.obj \
+ $(SLO)$/scrwin.obj \
+ $(SLO)$/collatorres.obj \
+ $(SLO)$/indexentryres.obj \
+ $(SLO)$/hyperlabel.obj \
+ $(SLO)$/fixedhyper.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/control/prgsbar.cxx b/svtools/source/control/prgsbar.cxx
new file mode 100644
index 000000000000..b67202e9c1fc
--- /dev/null
+++ b/svtools/source/control/prgsbar.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SV_PRGSBAR_CXX
+
+#ifndef _TOOLS_DEBUGS_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _VCL_STATUS_HXX
+#include <vcl/status.hxx>
+#endif
+#include <prgsbar.hxx>
+
+// =======================================================================
+
+#define PROGRESSBAR_OFFSET 3
+#define PROGRESSBAR_WIN_OFFSET 2
+
+// =======================================================================
+
+void ProgressBar::ImplInit()
+{
+ mnPercent = 0;
+ mbCalcNew = TRUE;
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+static WinBits clearProgressBarBorder( Window* pParent, WinBits nOrgStyle )
+{
+ WinBits nOutStyle = nOrgStyle;
+ if( pParent && (nOrgStyle & WB_BORDER) != 0 )
+ {
+ if( pParent->IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ nOutStyle &= WB_BORDER;
+ }
+ return nOutStyle;
+}
+
+// -----------------------------------------------------------------------
+
+ProgressBar::ProgressBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, clearProgressBarBorder( pParent, nWinStyle ) )
+{
+ SetOutputSizePixel( Size( 150, 20 ) );
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ProgressBar::ProgressBar( Window* pParent, const ResId& rResId ) :
+ Window( pParent, rResId )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ProgressBar::~ProgressBar()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+/* !!! Derzeit unterstuetzen wir keine Textausgaben
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+*/
+
+ if ( bBackground )
+ {
+ if( !IsControlBackground() &&
+ IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ if( (GetStyle() & WB_BORDER) )
+ SetBorderStyle( WINDOW_BORDER_REMOVEBORDER );
+ EnableChildTransparentMode( TRUE );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ }
+ else
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor = rStyleSettings.GetHighlightColor();
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ if ( aColor.IsRGBEqual( GetBackground().GetColor() ) )
+ {
+ if ( aColor.GetLuminance() > 100 )
+ aColor.DecreaseLuminance( 64 );
+ else
+ aColor.IncreaseLuminance( 64 );
+ }
+ SetLineColor();
+ SetFillColor( aColor );
+/* !!! Derzeit unterstuetzen wir keine Textausgaben
+ SetTextColor( aColor );
+ SetTextFillColor();
+*/
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::ImplDrawProgress( USHORT nOldPerc, USHORT nNewPerc )
+{
+ if ( mbCalcNew )
+ {
+ mbCalcNew = FALSE;
+
+ Size aSize = GetOutputSizePixel();
+ mnPrgsHeight = aSize.Height()-(PROGRESSBAR_WIN_OFFSET*2);
+ mnPrgsWidth = (mnPrgsHeight*2)/3;
+ maPos.Y() = PROGRESSBAR_WIN_OFFSET;
+ long nMaxWidth = (aSize.Width()-(PROGRESSBAR_WIN_OFFSET*2)+PROGRESSBAR_OFFSET);
+ USHORT nMaxCount = (USHORT)(nMaxWidth / (mnPrgsWidth+PROGRESSBAR_OFFSET));
+ if ( nMaxCount <= 1 )
+ nMaxCount = 1;
+ else
+ {
+ while ( ((10000/(10000/nMaxCount))*(mnPrgsWidth+PROGRESSBAR_OFFSET)) > nMaxWidth )
+ nMaxCount--;
+ }
+ mnPercentCount = 10000/nMaxCount;
+ nMaxWidth = ((10000/(10000/nMaxCount))*(mnPrgsWidth+PROGRESSBAR_OFFSET))-PROGRESSBAR_OFFSET;
+ maPos.X() = (aSize.Width()-nMaxWidth)/2;
+ }
+
+ ::DrawProgress( this, maPos, PROGRESSBAR_OFFSET, mnPrgsWidth, mnPrgsHeight,
+ nOldPerc*100, nNewPerc*100, mnPercentCount,
+ Rectangle( Point(), GetSizePixel() ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::Paint( const Rectangle& )
+{
+ ImplDrawProgress( 0, mnPercent );
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::Resize()
+{
+ mbCalcNew = TRUE;
+ if ( IsReallyVisible() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::SetValue( USHORT nNewPercent )
+{
+ DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" );
+
+ if ( nNewPercent < mnPercent )
+ {
+ mbCalcNew = TRUE;
+ mnPercent = nNewPercent;
+ if ( IsReallyVisible() )
+ {
+ Invalidate();
+ Update();
+ }
+ }
+ else
+ {
+ ImplDrawProgress( mnPercent, nNewPercent );
+ mnPercent = nNewPercent;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::StateChanged( StateChangedType nType )
+{
+/* !!! Derzeit unterstuetzen wir keine Textausgaben
+ if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else
+*/
+ if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+
+ Window::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
diff --git a/svtools/source/control/roadmap.cxx b/svtools/source/control/roadmap.cxx
new file mode 100644
index 000000000000..7cf88816199f
--- /dev/null
+++ b/svtools/source/control/roadmap.cxx
@@ -0,0 +1,1025 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <roadmap.hxx>
+
+#ifndef _STRING_HXX
+#define _STRING_HXX
+#endif
+
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+
+#include <algorithm>
+#include <vcl/bitmap.hxx>
+#include <tools/color.hxx>
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/OUString.hxx>
+#endif
+#include <memory>
+
+#define ROADMAP_INDENT_X 4
+#define ROADMAP_INDENT_Y 27
+#define ROADMAP_ITEM_DISTANCE_Y 6
+#define RMINCOMPLETE -1
+#define NADDITEM 1
+#define INCOMPLETELABEL ::String::CreateFromAscii("...") // TODO: Cast to String
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ typedef std::vector< ::rtl::OUString > S_Vector;
+ typedef std::vector< RoadmapItem* > HL_Vector;
+
+ //=====================================================================
+ //= ColorChanger
+ //=====================================================================
+ class IDLabel : public FixedText
+ {
+ public:
+ IDLabel( Window* _pParent, WinBits _nWinStyle = 0 );
+ ~IDLabel( );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+ };
+
+ //=====================================================================
+ //= ColorChanger
+ //=====================================================================
+ class ColorChanger
+ {
+ protected:
+ OutputDevice* m_pDev;
+
+ public:
+ ColorChanger( OutputDevice* _pDev, const Color& _rNewLineColor, const Color& _rNewFillColor )
+ :m_pDev( _pDev )
+ {
+ m_pDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ m_pDev->SetLineColor( _rNewLineColor );
+ m_pDev->SetFillColor( _rNewFillColor );
+ }
+
+ ~ColorChanger()
+ {
+ m_pDev->Pop();
+ }
+ };
+
+ //=====================================================================
+ //= RoadmapItem
+ //=====================================================================
+ class RoadmapItem : public RoadmapTypes
+ {
+ private:
+ IDLabel* mpID;
+ HyperLabel* mpDescription;
+ const Size m_aItemPlayground;
+
+ public:
+ RoadmapItem( ORoadmap& _rParent, const Size& _rItemPlayground );
+ ~RoadmapItem( );
+
+ void SetID( sal_Int16 _ID );
+ sal_Int16 GetID() const;
+
+ void SetIndex( ItemIndex _Index );
+ ItemIndex GetIndex() const;
+
+ void SetLabel( const ::rtl::OUString& _rText );
+ ::rtl::OUString GetLabel( );
+
+ void Update( ItemIndex _RMIndex, const ::rtl::OUString& _rText );
+
+ void SetPosition( RoadmapItem* OldHyperLabel );
+
+ void ToggleBackgroundColor( const Color& _rGBColor );
+ void SetInteractive( sal_Bool _bInteractive );
+
+ void SetClickHdl( const Link& rLink );
+ const Link& GetClickHdl() const;
+ void SetZOrder( RoadmapItem* pRefRoadmapHyperLabel, USHORT nFlags );
+ void Enable( BOOL bEnable = TRUE);
+ BOOL IsEnabled() const;
+ void GrabFocus();
+
+ bool Contains( const Window* _pWindow ) const;
+
+ HyperLabel* GetDescriptionHyperLabel() const { return mpDescription; }
+
+ private:
+ void ImplUpdateIndex( const ItemIndex _nIndex );
+ void ImplUpdatePosSize();
+ };
+
+ //=====================================================================
+ //= RoadmapImpl
+ //=====================================================================
+ class RoadmapImpl : public RoadmapTypes
+ {
+ protected:
+ const ORoadmap& m_rAntiImpl;
+ Link m_aSelectHdl;
+ BitmapEx m_aPicture;
+ HL_Vector m_aRoadmapSteps;
+ ItemId m_iCurItemID;
+ sal_Bool m_bInteractive;
+ sal_Bool m_bComplete;
+ Size m_aItemSizePixel;
+
+ public:
+ RoadmapImpl( const ORoadmap& _rAntiImpl )
+ :m_rAntiImpl( _rAntiImpl )
+ ,m_iCurItemID( -1 )
+ ,m_bInteractive( sal_True )
+ ,m_bComplete( sal_True )
+ {
+ }
+
+ RoadmapItem* InCompleteHyperLabel;
+
+ void addHyperLabel( RoadmapItem* _rRoadmapStep ) { m_aRoadmapSteps.push_back(_rRoadmapStep); }
+
+ HL_Vector& getHyperLabels() { return m_aRoadmapSteps; }
+ const HL_Vector& getHyperLabels() const { return m_aRoadmapSteps; }
+
+ void insertHyperLabel( ItemIndex _Index, RoadmapItem* _rRoadmapStep ) { m_aRoadmapSteps.insert( m_aRoadmapSteps.begin() + _Index, _rRoadmapStep ); }
+
+ ItemIndex getItemCount() const { return m_aRoadmapSteps.size();}
+
+ void setCurItemID( ItemId i ) {m_iCurItemID = i; }
+ ItemId getCurItemID() const { return m_iCurItemID; }
+
+ void setInteractive(const sal_Bool _bInteractive) {m_bInteractive = _bInteractive; }
+ sal_Bool isInteractive() const { return m_bInteractive; };
+
+ void setComplete(const sal_Bool _bComplete) {m_bComplete = _bComplete; }
+ sal_Bool isComplete() const { return m_bComplete; };
+
+ void setPicture( const BitmapEx& _rPic ) { m_aPicture = _rPic; }
+ const BitmapEx& getPicture( ) const { return m_aPicture; }
+
+ void setSelectHdl( const Link& _rHdl ) { m_aSelectHdl = _rHdl; }
+ const Link& getSelectHdl( ) const { return m_aSelectHdl; }
+
+ void initItemSize();
+ const Size& getItemSize() const { return m_aItemSizePixel; }
+
+ void removeHyperLabel( ItemIndex _Index )
+ {
+ if ( ( _Index > -1 ) && ( _Index < getItemCount() ) )
+ {
+ delete m_aRoadmapSteps[_Index];
+ m_aRoadmapSteps.erase( m_aRoadmapSteps.begin() + _Index);
+ }
+ }
+ };
+
+
+ //=====================================================================
+ //= Roadmap
+ //=====================================================================
+ //---------------------------------------------------------------------
+ void RoadmapImpl::initItemSize()
+ {
+ Size aLabelSize( m_rAntiImpl.GetOutputSizePixel() );
+ aLabelSize.Height() = m_rAntiImpl.LogicToPixel( Size( 0, LABELBASEMAPHEIGHT ), MAP_APPFONT ).Height();
+ aLabelSize.Width() -= m_rAntiImpl.LogicToPixel( Size( 2 * ROADMAP_INDENT_X, 0 ), MAP_APPFONT ).Width();
+ m_aItemSizePixel = aLabelSize;
+ }
+
+ //=====================================================================
+ //= Roadmap
+ //=====================================================================
+ //---------------------------------------------------------------------
+ ORoadmap::ORoadmap( Window* _pParent, const ResId& _rId )
+ :Control( _pParent, _rId )
+ ,m_pImpl( new RoadmapImpl( *this ) )
+ {
+ implInit();
+ }
+
+ //---------------------------------------------------------------------
+ ORoadmap::ORoadmap( Window* _pParent, WinBits _nWinStyle )
+ :Control( _pParent, _nWinStyle )
+ ,m_pImpl( new RoadmapImpl( *this ) )
+
+ {
+ implInit();
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::implInit()
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aTextColor = rStyleSettings.GetFieldTextColor();
+ Font aFont = GetFont( );
+ aFont.SetColor( aTextColor );
+ aFont.SetWeight( WEIGHT_BOLD );
+ aFont.SetUnderline( UNDERLINE_SINGLE );
+ SetFont( aFont );
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+ m_pImpl->InCompleteHyperLabel = NULL;
+ m_pImpl->setCurItemID(-1 );
+ m_pImpl->setComplete( sal_True );
+
+ // Roadmap control should be reachable as one unit with a Tab key
+ // the next Tab key should spring out of the control.
+ // To reach it the control itself should get focus and set it
+ // on entries. The entries themself should not be reachable with
+ // the Tab key directly. So each entry should have WB_NOTABSTOP.
+ //
+ // In other words the creator should create the control with the following
+ // flags:
+ // SetStyle( ( GetStyle() | WB_TABSTOP ) & ~WB_DIALOGCONTROL );
+
+// TODO: if somebody sets a new font from outside (OutputDevice::SetFont), we would have to react
+// on this with calculating a new bold font.
+// Unfortunately, the OutputDevice does not offer a notify mechanism for a changed font.
+// So settings the font from outside is simply a forbidded scenario at the moment
+ EnableMapMode( sal_False );
+ }
+
+ //---------------------------------------------------------------------
+ ORoadmap::~ORoadmap( )
+ {
+ HL_Vector aItemsCopy = m_pImpl->getHyperLabels();
+ m_pImpl->getHyperLabels().clear();
+ for ( HL_Vector::iterator i = aItemsCopy.begin(); i< aItemsCopy.end(); ++i )
+ {
+ delete *i;
+ }
+ if ( ! m_pImpl->isComplete() )
+ delete m_pImpl->InCompleteHyperLabel;
+ delete m_pImpl;
+ m_pImpl = NULL;
+ }
+
+
+ RoadmapTypes::ItemId ORoadmap::GetCurrentRoadmapItemID() const
+ {
+ return m_pImpl->getCurItemID();
+ }
+
+
+ RoadmapItem* ORoadmap::GetPreviousHyperLabel( ItemIndex _Index)
+ {
+ RoadmapItem* pOldItem = NULL;
+ if ( _Index > 0 )
+ pOldItem = m_pImpl->getHyperLabels().at( _Index - 1 );
+ return pOldItem;
+ }
+
+
+ //---------------------------------------------------------------------
+
+ RoadmapItem* ORoadmap::InsertHyperLabel( ItemIndex _Index, const ::rtl::OUString& _sLabel, ItemId _RMID, sal_Bool _bEnabled)
+ {
+ if ( m_pImpl->getItemCount() == 0 )
+ m_pImpl->initItemSize();
+
+ RoadmapItem* pItem = NULL;
+ RoadmapItem* pOldItem = GetPreviousHyperLabel( _Index );
+
+ pItem = new RoadmapItem( *this, m_pImpl->getItemSize() );
+ if ( _RMID != RMINCOMPLETE )
+ {
+ pItem->SetInteractive( m_pImpl->isInteractive() );
+ m_pImpl->insertHyperLabel( _Index, pItem );
+ }
+ else
+ {
+ pItem->SetInteractive( sal_False );
+ }
+ pItem->SetPosition( pOldItem );
+ pItem->Update( _Index, _sLabel );
+ pItem->SetClickHdl(LINK( this, ORoadmap, ImplClickHdl ) );
+ pItem->SetID( _RMID );
+ pItem->SetIndex( _Index );
+ if (!_bEnabled)
+ pItem->Enable( _bEnabled );
+ return pItem;
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::SetRoadmapBitmap( const BitmapEx& _rBmp, sal_Bool _bInvalidate )
+ {
+ m_pImpl->setPicture( _rBmp );
+ if ( _bInvalidate )
+ Invalidate( );
+ }
+
+ //---------------------------------------------------------------------
+ const BitmapEx& ORoadmap::GetRoadmapBitmap( ) const
+ {
+ return m_pImpl->getPicture( );
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::SetRoadmapInteractive( sal_Bool _bInteractive )
+ {
+ m_pImpl->setInteractive( _bInteractive );
+
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ for ( HL_Vector::const_iterator i = rItems.begin();
+ i < rItems.end();
+ ++i
+ )
+ {
+ (*i)->SetInteractive( _bInteractive );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool ORoadmap::IsRoadmapInteractive()
+ {
+ return m_pImpl->isInteractive();
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::SetRoadmapComplete( sal_Bool _bComplete )
+ {
+ sal_Bool bWasComplete = m_pImpl->isComplete();
+ m_pImpl->setComplete( _bComplete );
+ if ( _bComplete )
+ {
+ if ( m_pImpl->InCompleteHyperLabel != NULL)
+ {
+ delete m_pImpl->InCompleteHyperLabel;
+ m_pImpl->InCompleteHyperLabel = NULL;
+ }
+ }
+ else if ( bWasComplete )
+ m_pImpl->InCompleteHyperLabel = InsertHyperLabel( m_pImpl->getItemCount(), ::String::CreateFromAscii( "..." ), RMINCOMPLETE );
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::UpdatefollowingHyperLabels( ItemIndex _nIndex )
+ {
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ if ( _nIndex < (ItemIndex)rItems.size() )
+ {
+ RoadmapItem* pItem = NULL;
+ for ( HL_Vector::const_iterator i = rItems.begin() + _nIndex;
+ i< rItems.end();
+ ++i, ++_nIndex
+ )
+ {
+ pItem = *i;
+
+ pItem->SetIndex( _nIndex );
+ pItem->SetPosition( GetPreviousHyperLabel( _nIndex ) );
+ }
+ }
+ if ( ! m_pImpl->isComplete() )
+ {
+ RoadmapItem* pOldItem = GetPreviousHyperLabel( m_pImpl->getItemCount() );
+ m_pImpl->InCompleteHyperLabel->SetPosition( pOldItem );
+ m_pImpl->InCompleteHyperLabel->Update( m_pImpl->getItemCount(), ::String::CreateFromAscii("...") );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::ReplaceRoadmapItem( ItemIndex _Index, const ::rtl::OUString& _RoadmapItem, ItemId _RMID, sal_Bool _bEnabled )
+ {
+ RoadmapItem* pItem = GetByIndex( _Index);
+ if ( pItem != NULL )
+ {
+ pItem->Update( _Index, _RoadmapItem );
+ pItem->SetID( _RMID );
+ pItem->Enable( _bEnabled );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapTypes::ItemIndex ORoadmap::GetItemCount() const
+ {
+ return m_pImpl->getItemCount();
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapTypes::ItemId ORoadmap::GetItemID( ItemIndex _nIndex ) const
+ {
+ const RoadmapItem* pHyperLabel = GetByIndex( _nIndex );
+ if ( pHyperLabel )
+ return pHyperLabel->GetID();
+ return -1;
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapTypes::ItemIndex ORoadmap::GetItemIndex( ItemId _nID ) const
+ {
+ ItemId nLocID = 0;
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ for ( HL_Vector::const_iterator i = rItems.begin();
+ i < rItems.end();
+ ++i
+ )
+ {
+ nLocID = (*i)->GetID();
+ if ( nLocID == _nID )
+ return ItemIndex( i - rItems.begin() );
+ }
+ return -1;
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::InsertRoadmapItem( ItemIndex _Index, const ::rtl::OUString& _RoadmapItem, ItemId _nUniqueId, sal_Bool _bEnabled )
+ {
+ InsertHyperLabel( _Index, _RoadmapItem, _nUniqueId, _bEnabled );
+ // Todo: YPos is superfluous, if items are always appended
+ UpdatefollowingHyperLabels( _Index + 1 );
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::DeleteRoadmapItem( ItemIndex _Index )
+ {
+ if ( m_pImpl->getItemCount() > 0 && ( _Index > -1) && ( _Index < m_pImpl->getItemCount() ) )
+ {
+ m_pImpl->removeHyperLabel( _Index );
+ UpdatefollowingHyperLabels( _Index );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool ORoadmap::IsRoadmapComplete( ) const
+ {
+ return m_pImpl->isComplete();
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool ORoadmap::IsRoadmapItemEnabled( ItemId _nItemId, ItemIndex _nStartIndex ) const
+ {
+ const RoadmapItem* _pLabelItem = GetByID( _nItemId, _nStartIndex );
+ return _pLabelItem ? _pLabelItem->IsEnabled() : sal_False;
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::EnableRoadmapItem( ItemId _nItemId, sal_Bool _bEnable, ItemIndex _nStartIndex )
+ {
+ RoadmapItem* pItem = GetByID( _nItemId, _nStartIndex );
+ if ( pItem != NULL )
+ pItem->Enable( _bEnable );
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::ChangeRoadmapItemLabel( ItemId _nID, const ::rtl::OUString& _sLabel, ItemIndex _nStartIndex )
+ {
+ RoadmapItem* pItem = GetByID( _nID, _nStartIndex );
+ if ( pItem != NULL )
+ {
+ pItem->Update( pItem->GetIndex(), _sLabel );
+
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ for ( HL_Vector::const_iterator i = rItems.begin() + _nStartIndex;
+ i < rItems.end();
+ ++i
+ )
+ {
+ (*i)->SetPosition( GetPreviousHyperLabel( i - rItems.begin() ) );
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------
+
+ ::rtl::OUString ORoadmap::GetRoadmapItemLabel( ItemId _nID, ItemIndex _nStartIndex )
+ {
+ RoadmapItem* pItem = GetByID( _nID, _nStartIndex );
+ if ( pItem != NULL )
+ return pItem->GetLabel();
+ else
+ return ::rtl::OUString();
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::ChangeRoadmapItemID( ItemId _nID, ItemId _NewID, ItemIndex _nStartIndex )
+ {
+ RoadmapItem* pItem = GetByID( _nID, _nStartIndex );
+ if ( pItem != NULL )
+ pItem->SetID( _NewID );
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapItem* ORoadmap::GetByID( ItemId _nID, ItemIndex _nStartIndex)
+ {
+ ItemId nLocID = 0;
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ for ( HL_Vector::const_iterator i = rItems.begin() + _nStartIndex;
+ i < rItems.end();
+ ++i
+ )
+ {
+ nLocID = (*i)->GetID();
+ if ( nLocID == _nID )
+ return *i;
+ }
+ return NULL;
+ }
+
+ //---------------------------------------------------------------------
+ const RoadmapItem* ORoadmap::GetByID( ItemId _nID, ItemIndex _nStartIndex ) const
+ {
+ return const_cast< ORoadmap* >( this )->GetByID( _nID, _nStartIndex );
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapItem* ORoadmap::GetByIndex( ItemIndex _nItemIndex)
+ {
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ if ( ( _nItemIndex > -1 ) && ( _nItemIndex < (ItemIndex)rItems.size() ) )
+ {
+ return rItems.at( _nItemIndex );
+ }
+ return NULL;
+ }
+
+ //---------------------------------------------------------------------
+ const RoadmapItem* ORoadmap::GetByIndex( ItemIndex _nItemIndex ) const
+ {
+ return const_cast< ORoadmap* >( this )->GetByIndex( _nItemIndex );
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapTypes::ItemId ORoadmap::GetNextAvailableItemId( ItemIndex _nNewIndex )
+ {
+ RoadmapItem* pItem = NULL;
+
+ ItemIndex searchIndex = ++_nNewIndex;
+ while ( searchIndex < m_pImpl->getItemCount() )
+ {
+ pItem = GetByIndex( searchIndex );
+ if ( pItem->IsEnabled() )
+ return pItem->GetID( );
+
+ ++searchIndex;
+ }
+ return -1;
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapTypes::ItemId ORoadmap::GetPreviousAvailableItemId( ItemIndex _nNewIndex )
+ {
+ RoadmapItem* pItem = NULL;
+ ItemIndex searchIndex = --_nNewIndex;
+ while ( searchIndex > -1 )
+ {
+ pItem = GetByIndex( searchIndex );
+ if ( pItem->IsEnabled() )
+ return pItem->GetID( );
+
+ searchIndex--;
+ }
+ return -1;
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::DeselectOldRoadmapItems()
+ {
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ for ( HL_Vector::const_iterator i = rItems.begin();
+ i < rItems.end();
+ ++i
+ )
+ {
+ (*i)->ToggleBackgroundColor( COL_TRANSPARENT );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::SetItemSelectHdl( const Link& _rHdl )
+ {
+ m_pImpl->setSelectHdl( _rHdl );
+ }
+
+ //---------------------------------------------------------------------
+ Link ORoadmap::GetItemSelectHdl( ) const
+ {
+ return m_pImpl->getSelectHdl();
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::Select()
+ {
+ GetItemSelectHdl().Call( this );
+ CallEventListeners( VCLEVENT_ROADMAP_ITEMSELECTED );
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::GetFocus()
+ {
+ RoadmapItem* pCurHyperLabel = GetByID( GetCurrentRoadmapItemID() );
+ if ( pCurHyperLabel != NULL )
+ pCurHyperLabel->GrabFocus();
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool ORoadmap::SelectRoadmapItemByID( ItemId _nNewID )
+ {
+ DeselectOldRoadmapItems();
+ RoadmapItem* pItem = GetByID( _nNewID );
+ if ( pItem != NULL )
+ {
+ if ( pItem->IsEnabled() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ pItem->ToggleBackgroundColor( rStyleSettings.GetHighlightColor() ); //HighlightColor
+
+ pItem->GrabFocus();
+ m_pImpl->setCurItemID(_nNewID);
+
+ Select();
+ return sal_True;
+ }
+ }
+ return sal_False;
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::Paint( const Rectangle& _rRect )
+ {
+ Control::Paint( _rRect );
+
+
+ // draw the bitmap
+ if ( !!m_pImpl->getPicture() )
+ {
+ Size aBitmapSize = m_pImpl->getPicture().GetSizePixel();
+ Size aMySize = GetOutputSizePixel();
+
+ Point aBitmapPos( aMySize.Width() - aBitmapSize.Width(), aMySize.Height() - aBitmapSize.Height() );
+
+ // draw it
+ DrawBitmapEx( aBitmapPos, m_pImpl->getPicture() );
+ }
+
+ //.................................................................
+ // draw the headline
+ DrawHeadline();
+ }
+
+ //---------------------------------------------------------------------
+ void ORoadmap::DrawHeadline()
+ {
+ Point aTextPos = LogicToPixel( Point( ROADMAP_INDENT_X, 8 ), MAP_APPFONT );
+
+ Size aOutputSize( GetOutputSizePixel() );
+
+ // draw it
+ DrawText( Rectangle( aTextPos, aOutputSize ), GetText(), TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ DrawTextLine( aTextPos, aOutputSize.Width(), STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, sal_False );
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetLineColor( rStyleSettings.GetFieldTextColor());
+ SetTextColor(rStyleSettings.GetFieldTextColor());
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapItem* ORoadmap::GetByPointer(Window* pWindow)
+ {
+ const HL_Vector& rItems = m_pImpl->getHyperLabels();
+ for ( HL_Vector::const_iterator i = rItems.begin();
+ i < rItems.end();
+ ++i
+ )
+ {
+ if ( (*i)->Contains( pWindow ) )
+ return *i;
+ }
+ return NULL;
+ }
+
+ //---------------------------------------------------------------------
+ long ORoadmap::PreNotify( NotifyEvent& _rNEvt )
+ {
+ // capture KeyEvents for taskpane cycling
+ if ( _rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ Window* pWindow = _rNEvt.GetWindow();
+ RoadmapItem* pItem = GetByPointer( pWindow );
+ if ( pItem != NULL )
+ {
+ sal_Int16 nKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
+ switch( nKeyCode )
+ {
+ case KEY_UP:
+ { // Note: Performancewise this is not optimal, because we search for an ID in the labels
+ // and afterwards we search again for a label with the appropriate ID ->
+ // unnecessarily we search twice!!!
+ ItemId nPrevItemID = GetPreviousAvailableItemId( pItem->GetIndex() );
+ if ( nPrevItemID != -1 )
+ return SelectRoadmapItemByID( nPrevItemID );
+ }
+ break;
+ case KEY_DOWN:
+ {
+ ItemId nNextItemID = GetNextAvailableItemId( pItem->GetIndex() );
+ if ( nNextItemID != -1 )
+ return SelectRoadmapItemByID( nNextItemID );
+ }
+ break;
+ case KEY_SPACE:
+ return SelectRoadmapItemByID( pItem->GetID() );
+ }
+ }
+ }
+ return Window::PreNotify( _rNEvt );
+ }
+
+ //---------------------------------------------------------------------
+ IMPL_LINK(ORoadmap, ImplClickHdl, HyperLabel*, _CurHyperLabel)
+ {
+ return SelectRoadmapItemByID( _CurHyperLabel->GetID() );
+ }
+
+
+
+ //---------------------------------------------------------------------
+ void ORoadmap::DataChanged( const DataChangedEvent& rDCEvt )
+ {
+ if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
+ ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+ Color aTextColor = rStyleSettings.GetFieldTextColor();
+ Font aFont = GetFont();
+ aFont.SetColor( aTextColor );
+ SetFont( aFont );
+ RoadmapTypes::ItemId curItemID = GetCurrentRoadmapItemID();
+ RoadmapItem* pLabelItem = GetByID( curItemID );
+ pLabelItem->ToggleBackgroundColor(rStyleSettings.GetHighlightColor());
+ Invalidate();
+ }
+ }
+
+
+ //---------------------------------------------------------------------
+ RoadmapItem::RoadmapItem( ORoadmap& _rParent, const Size& _rItemPlayground )
+ :m_aItemPlayground( _rItemPlayground )
+ {
+ mpID = new IDLabel( &_rParent, WB_WORDBREAK );
+ mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetFieldTextColor( ) );
+ mpID->Show();
+ mpDescription = new HyperLabel( &_rParent, WB_NOTABSTOP | WB_WORDBREAK );
+ mpDescription->Show();
+ }
+
+ //---------------------------------------------------------------------
+ bool RoadmapItem::Contains( const Window* _pWindow ) const
+ {
+ return ( mpID == _pWindow ) || ( mpDescription == _pWindow );
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::GrabFocus()
+ {
+ if ( mpDescription )
+ mpDescription->GrabFocus();
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetInteractive( sal_Bool _bInteractive )
+ {
+ if ( mpDescription )
+ mpDescription->SetInteractive(_bInteractive);
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetID( sal_Int16 _ID )
+ {
+ if ( mpDescription )
+ mpDescription->SetID(_ID);
+ }
+
+ //---------------------------------------------------------------------
+ sal_Int16 RoadmapItem::GetID() const
+ {
+ return mpDescription ? mpDescription->GetID() : sal_Int16(-1);
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::ImplUpdateIndex( const ItemIndex _nIndex )
+ {
+ if ( mpDescription )
+ mpDescription->SetIndex( _nIndex );
+
+ if ( mpID )
+ {
+ ::rtl::OUString aIDText = ::rtl::OUString::valueOf( (sal_Int32)( _nIndex + 1 ) ) + ::rtl::OUString::createFromAscii( "." );
+ mpID->SetText( aIDText );
+ }
+
+ // update the geometry of both controls
+ ImplUpdatePosSize();
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetIndex( ItemIndex _Index )
+ {
+ ImplUpdateIndex( _Index );
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapTypes::ItemIndex RoadmapItem::GetIndex() const
+ {
+ return mpDescription ? mpDescription->GetIndex() : ItemIndex(-1);
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetLabel( const ::rtl::OUString& _rText )
+ {
+ if ( mpDescription )
+ mpDescription->SetText(_rText);
+ }
+
+ //---------------------------------------------------------------------
+ ::rtl::OUString RoadmapItem::GetLabel( )
+ {
+ return mpDescription ? mpDescription->GetText() : String();
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetPosition( RoadmapItem* _pOldItem )
+ {
+ Point aIDPos;
+ if ( _pOldItem == NULL )
+ {
+ aIDPos = mpID->LogicToPixel( Point( ROADMAP_INDENT_X, ROADMAP_INDENT_Y ), MAP_APPFONT );
+ }
+ else
+ {
+ Size aOldSize = _pOldItem->GetDescriptionHyperLabel()->GetSizePixel();
+
+ aIDPos = _pOldItem->mpID->GetPosPixel();
+ aIDPos.Y() += aOldSize.Height();
+ aIDPos.Y() += mpID->GetParent()->LogicToPixel( Size( 0, ROADMAP_ITEM_DISTANCE_Y ) ).Height();
+ }
+ mpID->SetPosPixel( aIDPos );
+
+ sal_Int32 nDescPos = aIDPos.X() + mpID->GetSizePixel().Width();
+ mpDescription->SetPosPixel( Point( nDescPos, aIDPos.Y() ) );
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetZOrder( RoadmapItem* pRefRoadmapHyperLabel, USHORT nFlags )
+ {
+ if (pRefRoadmapHyperLabel == NULL)
+ mpDescription->SetZOrder( NULL, nFlags); //WINDOW_ZORDER_FIRST );
+ else
+ mpDescription->SetZOrder( pRefRoadmapHyperLabel->mpDescription, nFlags); //, WINDOW_ZORDER_BEHIND );
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::Enable( BOOL _bEnable)
+ {
+ mpID->Enable(_bEnable);
+ mpDescription->Enable(_bEnable);
+ }
+
+ //---------------------------------------------------------------------
+ BOOL RoadmapItem::IsEnabled() const
+ {
+ return mpID->IsEnabled();
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::ToggleBackgroundColor( const Color& _rGBColor )
+ {
+ if (_rGBColor == COL_TRANSPARENT)
+ {
+ mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetFieldTextColor( ) );
+ mpID->SetControlBackground( COL_TRANSPARENT );
+ }
+ else
+ {
+ mpID->SetControlBackground( mpID->GetSettings().GetStyleSettings().GetHighlightColor() );
+ mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetHighlightTextColor( ) );
+ }
+ mpDescription->ToggleBackgroundColor(_rGBColor);
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::ImplUpdatePosSize()
+ {
+ // calculate widths
+ long nIDWidth = mpID->GetTextWidth( mpID->GetText() );
+ long nMaxIDWidth = mpID->GetTextWidth( ::rtl::OUString::createFromAscii( "100." ) );
+ nIDWidth = ::std::min( nIDWidth, nMaxIDWidth );
+
+ // check how many space the description would need
+ Size aDescriptionSize = mpDescription->CalcMinimumSize( m_aItemPlayground.Width() - nIDWidth );
+
+ // position and size both controls
+ Size aIDSize( nIDWidth, aDescriptionSize.Height() );
+ mpID->SetSizePixel( aIDSize );
+
+ Point aIDPos = mpID->GetPosPixel();
+ mpDescription->SetPosPixel( Point( aIDPos.X() + nIDWidth, aIDPos.Y() ) );
+ mpDescription->SetSizePixel( aDescriptionSize );
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::Update( ItemIndex _RMIndex, const ::rtl::OUString& _rText )
+ {
+ // update description label
+ mpDescription->SetLabel( _rText );
+
+ // update the index in both controls, which triggers updating the geometry of both
+ ImplUpdateIndex( _RMIndex );
+ }
+
+ //---------------------------------------------------------------------
+ RoadmapItem::~RoadmapItem( )
+ {
+ {
+ ::std::auto_ptr<Control> aTemp(mpID);
+ mpID = NULL;
+ }
+ {
+ ::std::auto_ptr<Control> aTemp(mpDescription);
+ mpDescription = NULL;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapItem::SetClickHdl( const Link& rLink )
+ {
+ if ( mpDescription )
+ mpDescription->SetClickHdl( rLink);
+ }
+
+ //---------------------------------------------------------------------
+ const Link& RoadmapItem::GetClickHdl( ) const
+ {
+ return mpDescription->GetClickHdl();
+ }
+
+ //---------------------------------------------------------------------
+ IDLabel::IDLabel( Window* _pParent, WinBits _nWinStyle )
+ :FixedText( _pParent, _nWinStyle )
+ {
+
+ }
+
+ //---------------------------------------------------------------------
+ IDLabel::~IDLabel( )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ void IDLabel::DataChanged( const DataChangedEvent& rDCEvt )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ FixedText::DataChanged( rDCEvt );
+ if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
+ ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
+ {
+ const Color& rGBColor = GetControlBackground();
+ if (rGBColor == COL_TRANSPARENT)
+ SetTextColor( rStyleSettings.GetFieldTextColor( ) );
+ else
+ {
+ SetControlBackground(rStyleSettings.GetHighlightColor());
+ SetTextColor( rStyleSettings.GetHighlightTextColor( ) );
+ }
+ Invalidate();
+ }
+ }
+
+
+
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
diff --git a/svtools/source/control/ruler.cxx b/svtools/source/control/ruler.cxx
new file mode 100644
index 000000000000..6fcbd92597ba
--- /dev/null
+++ b/svtools/source/control/ruler.cxx
@@ -0,0 +1,3181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <string.h>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/poly.hxx>
+
+#include <vcl/i18nhelp.hxx>
+
+#define _SV_RULER_CXX
+#include <ruler.hxx>
+
+// =======================================================================
+
+#define RULER_OFF 3
+#define RULER_TEXTOFF 2
+#define RULER_RESIZE_OFF 4
+#define RULER_LINE_WIDTH 7
+#define RULER_MIN_SIZE 3
+
+#define RULER_TICK1_WIDTH 1
+#define RULER_TICK2_WIDTH 3
+#define RULER_TICK3_WIDTH 5
+
+#define RULER_VAR_SIZE 8
+
+#define RULER_TAB_HEIGHT2 2
+#define RULER_TAB_WIDTH2 2
+#define RULER_TAB_CWIDTH 8
+#define RULER_TAB_CWIDTH2 4
+#define RULER_TAB_CWIDTH3 4
+#define RULER_TAB_CWIDTH4 2
+#define RULER_TAB_DHEIGHT 4
+#define RULER_TAB_DHEIGHT2 1
+#define RULER_TAB_DWIDTH 5
+#define RULER_TAB_DWIDTH2 3
+#define RULER_TAB_DWIDTH3 3
+#define RULER_TAB_DWIDTH4 1
+
+#define RULER_UPDATE_LINES 0x01
+#define RULER_UPDATE_DRAW 0x02
+
+#define RULER_CLIP 150
+
+// =======================================================================
+
+#define RULER_UNIT_MM 0
+#define RULER_UNIT_CM 1
+#define RULER_UNIT_M 2
+#define RULER_UNIT_KM 3
+#define RULER_UNIT_INCH 4
+#define RULER_UNIT_FOOT 5
+#define RULER_UNIT_MILE 6
+#define RULER_UNIT_POINT 7
+#define RULER_UNIT_PICA 8
+#define RULER_UNIT_COUNT 9
+
+// -----------------
+// - ImplRulerData -
+// -----------------
+class ImplRulerData
+{
+ friend class Ruler;
+
+private:
+ RulerLine* pLines;
+ RulerArrow* pArrows;
+ RulerBorder* pBorders;
+ RulerIndent* pIndents;
+ RulerTab* pTabs;
+ long nNullVirOff;
+ long nRulVirOff;
+ long nRulWidth;
+ long nPageOff;
+ long nPageWidth;
+ long nNullOff;
+ long nMargin1;
+ long nMargin2;
+ USHORT nLines;
+ USHORT nArrows;
+ USHORT nBorders;
+ USHORT nIndents;
+ USHORT nTabs;
+ USHORT nMargin1Style;
+ USHORT nMargin2Style;
+ BOOL bAutoPageWidth;
+ BOOL bTextRTL;
+
+#ifdef _SV_RULER_CXX
+public:
+ ImplRulerData();
+ ~ImplRulerData();
+ ImplRulerData& operator=( const ImplRulerData& rData );
+#endif
+};
+
+
+struct ImplRulerUnitData
+{
+ MapUnit eMapUnit; // MAP_UNIT zum Umrechnen
+ long nTickUnit; // Teiler fuer Einheit
+ long nTick1; // Schrittweite
+ long nTick2; // Tick fuer halbe Werte
+ long nTick3; // Tick fuer Zahlenausgabe
+ long n100THMM; // Teiler fuer Einheit
+ USHORT nUnitDigits; // Anzahl Nachkommastellen
+ sal_Char aUnitStr[8]; // Einheiten-String
+};
+
+static ImplRulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] =
+{
+{ MAP_100TH_MM, 100, 25, 50, 100, 100, 3, " mm" }, // MM
+{ MAP_100TH_MM, 1000, 250, 500, 1000, 1000, 3, " cm" }, // CM
+{ MAP_MM, 1000, 250, 500, 1000, 10000, 4, " m" }, // M
+{ MAP_CM, 100000, 25000, 50000, 100000, 100000, 6, " km" }, // KM
+{ MAP_100TH_INCH, 100, 10, 50, 100, 2540, 3, "\"" }, // INCH
+{ MAP_100TH_INCH, 1200, 120, 600, 1200, 30480, 3, "'" }, // FOOT
+{ MAP_10TH_INCH, 633600, 63360, 316800, 633600, 1609344, 4, " miles" }, // MILE
+{ MAP_POINT, 1, 12, 12, 36, 353, 2, " pt" }, // POINT
+{ MAP_100TH_MM, 423, 423, 423, 846, 423, 3, " pi" } // PICA
+};
+
+// =======================================================================
+
+struct ImplRulerHitTest
+{
+ long nPos;
+ RulerType eType;
+ USHORT nAryPos;
+ USHORT mnDragSize;
+ BOOL bSize;
+ BOOL bSizeBar;
+ BOOL bExpandTest;
+ ImplRulerHitTest() :
+ bExpandTest( FALSE ) {}
+};
+
+// =======================================================================
+
+ImplRulerData::ImplRulerData()
+{
+ memset( this, 0, sizeof( ImplRulerData ) );
+
+ // PageBreite == EditWinBreite
+ bAutoPageWidth = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplRulerData::~ImplRulerData()
+{
+ delete[] pLines;
+ delete[] pArrows;
+ delete[] pBorders;
+ delete[] pIndents;
+ delete[] pTabs;
+}
+
+// -----------------------------------------------------------------------
+
+ImplRulerData& ImplRulerData::operator=( const ImplRulerData& rData )
+{
+ delete[] pLines;
+ delete[] pArrows;
+ delete[] pBorders;
+ delete[] pIndents;
+ delete[] pTabs;
+
+ memcpy( this, &rData, sizeof( ImplRulerData ) );
+
+ if ( rData.pLines )
+ {
+ pLines = new RulerLine[nLines];
+ memcpy( pLines, rData.pLines, nLines*sizeof( RulerLine ) );
+ }
+
+ if ( rData.pArrows )
+ {
+ pArrows = new RulerArrow[nArrows];
+ memcpy( pArrows, rData.pArrows, nArrows*sizeof( RulerArrow ) );
+ }
+
+ if ( rData.pBorders )
+ {
+ pBorders = new RulerBorder[nBorders];
+ memcpy( pBorders, rData.pBorders, nBorders*sizeof( RulerBorder ) );
+ }
+
+ if ( rData.pIndents )
+ {
+ pIndents = new RulerIndent[nIndents];
+ memcpy( pIndents, rData.pIndents, nIndents*sizeof( RulerIndent ) );
+ }
+
+ if ( rData.pTabs )
+ {
+ pTabs = new RulerTab[nTabs];
+ memcpy( pTabs, rData.pTabs, nTabs*sizeof( RulerTab ) );
+ }
+
+ return *this;
+}
+
+// =======================================================================
+
+void Ruler::ImplInit( WinBits nWinBits )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Default WinBits setzen
+ if ( !(nWinBits & WB_VERT) )
+ {
+ nWinBits |= WB_HORZ;
+
+ // --- RTL --- no UI mirroring for horizontal rulers, because
+ // the document is also not mirrored
+ EnableRTL( FALSE );
+ }
+
+ // Variablen initialisieren
+ mnWinStyle = nWinBits; // Window-Style
+ mnBorderOff = 0; // Border-Offset
+ mnWinOff = 0; // EditWinOffset
+ mnWinWidth = 0; // EditWinWidth
+ mnWidth = 0; // Fensterbreite
+ mnHeight = 0; // Fensterhoehe
+ mnVirOff = 0; // Offset des VirtualDeice vom linke/oberen Rand
+ mnVirWidth = 0; // Breite bzw. Hoehe vom VirtualDevice
+ mnVirHeight = 0; // Hoehe bzw. Breite vom VirtualDevice
+ mnDragPos = 0; // Drag-Position (NullPunkt)
+ mnUpdateEvtId = 0; // Noch kein Update-Event verschickt
+ mnDragAryPos = 0; // Drag-Array-Index
+ mnDragSize = 0; // Wird beim Draggen die Groesse geaendert
+ mnDragScroll = 0; // Soll beim Draggen gescrollt werden
+ mnDragModifier = 0; // Modifier-Tasten beim Draggen
+ mnExtraStyle = 0; // Style des Extra-Feldes
+ mnExtraClicks = 0; // Click-Anzahl fuer Extra-Feld
+ mnExtraModifier = 0; // Modifier-Tasten beim Click im Extrafeld
+ mbCalc = TRUE; // Muessen Pagebreiten neu berechnet werden
+ mbFormat = TRUE; // Muss neu ausgegeben werden
+ mbDrag = FALSE; // Sind wir im Drag-Modus
+ mbDragDelete = FALSE; // Wird Maus beim Draggen unten rausgezogen
+ mbDragCanceled = FALSE; // Wurde Dragging abgebrochen
+ mbAutoWinWidth = TRUE; // EditWinBreite == RulerBreite
+ mbActive = TRUE; // Ist Lineal aktiv
+ mnUpdateFlags = 0; // Was soll im Update-Handler upgedatet werden
+ mpData = mpSaveData; // Wir zeigen auf die normalen Daten
+ meExtraType = RULER_EXTRA_DONTKNOW; // Was im ExtraFeld dargestellt wird
+ meDragType = RULER_TYPE_DONTKNOW; // Gibt an, was gedragt wird
+
+ // Units initialisieren
+ mnUnitIndex = RULER_UNIT_CM;
+ meUnit = FUNIT_CM;
+ maZoom = Fraction( 1, 1 );
+ meSourceUnit = MAP_100TH_MM;
+
+ // Border-Breiten berechnen
+ if ( nWinBits & WB_BORDER )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ mnBorderWidth = 2;
+ else
+ mnBorderWidth = 1;
+ }
+ else
+ mnBorderWidth = 0;
+
+ // Einstellungen setzen
+ ImplInitSettings( TRUE, TRUE, TRUE );
+
+ // Default-Groesse setzen
+ long nDefHeight = GetTextHeight() + RULER_OFF*2 + RULER_TEXTOFF*2 + mnBorderWidth;
+ Size aDefSize;
+ if ( nWinBits & WB_HORZ )
+ aDefSize.Height() = nDefHeight;
+ else
+ aDefSize.Width() = nDefHeight;
+ SetOutputSizePixel( aDefSize );
+}
+
+// -----------------------------------------------------------------------
+
+Ruler::Ruler( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle & WB_3DLOOK ),
+ maVirDev( *this ),
+ maMapMode( MAP_100TH_MM ),
+ mpSaveData(new ImplRulerData),
+ mpData(0),
+ mpDragData(new ImplRulerData)
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Ruler::~Ruler()
+{
+ if ( mnUpdateEvtId )
+ Application::RemoveUserEvent( mnUpdateEvtId );
+ delete mpSaveData;
+ delete mpDragData;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplVDrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if ( nX1 < -RULER_CLIP )
+ {
+ nX1 = -RULER_CLIP;
+ if ( nX2 < -RULER_CLIP )
+ return;
+ }
+ long nClip = mnVirWidth+RULER_CLIP;
+ if ( nX2 > nClip )
+ {
+ nX2 = nClip;
+ if ( nX1 > nClip )
+ return;
+ }
+
+ if ( mnWinStyle & WB_HORZ )
+ maVirDev.DrawLine( Point( nX1, nY1 ), Point( nX2, nY2 ) );
+ else
+ maVirDev.DrawLine( Point( nY1, nX1 ), Point( nY2, nX2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplVDrawRect( long nX1, long nY1, long nX2, long nY2 )
+{
+ if ( nX1 < -RULER_CLIP )
+ {
+ nX1 = -RULER_CLIP;
+ if ( nX2 < -RULER_CLIP )
+ return;
+ }
+ long nClip = mnVirWidth+RULER_CLIP;
+ if ( nX2 > nClip )
+ {
+ nX2 = nClip;
+ if ( nX1 > nClip )
+ return;
+ }
+
+ if ( mnWinStyle & WB_HORZ )
+ maVirDev.DrawRect( Rectangle( nX1, nY1, nX2, nY2 ) );
+ else
+ maVirDev.DrawRect( Rectangle( nY1, nX1, nY2, nX2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplVDrawText( long nX, long nY, const String& rText )
+{
+ if ( (nX > -RULER_CLIP) && (nX < mnVirWidth+RULER_CLIP) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ maVirDev.DrawText( Point( nX, nY ), rText );
+ else
+ maVirDev.DrawText( Point( nY, nX ), rText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplInvertLines( BOOL bErase )
+{
+ // Positionslinien
+ if ( mpData->nLines && mbActive && !mbDrag && !mbFormat &&
+ !(mnUpdateFlags & RULER_UPDATE_LINES) )
+ {
+ long n;
+ long nNullWinOff = mpData->nNullVirOff+mnVirOff;
+ long nRulX1 = mpData->nRulVirOff+mnVirOff;
+ long nRulX2 = nRulX1+mpData->nRulWidth;
+ long nY = (RULER_OFF*2)+mnVirHeight-1;
+
+ // Rectangle berechnen
+ Rectangle aRect;
+ if ( mnWinStyle & WB_HORZ )
+ aRect.Bottom() = nY;
+ else
+ aRect.Right() = nY;
+
+ // Linien ausgeben
+ for ( USHORT i = 0; i < mpData->nLines; i++ )
+ {
+ n = mpData->pLines[i].nPos+nNullWinOff;
+ if ( (n >= nRulX1) && (n < nRulX2) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aRect.Left() = n;
+ aRect.Right() = n;
+ }
+ else
+ {
+ aRect.Top() = n;
+ aRect.Bottom() = n;
+ }
+ if ( bErase )
+ {
+ Rectangle aTempRect = aRect;
+ if ( mnWinStyle & WB_HORZ )
+ aTempRect.Bottom() = RULER_OFF-1;
+ else
+ aTempRect.Right() = RULER_OFF-1;
+ Erase( aTempRect );
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aTempRect.Bottom() = aRect.Bottom();
+ aTempRect.Top() = aTempRect.Bottom()-RULER_OFF+1;
+ }
+ else
+ {
+ aTempRect.Right() = aRect.Right();
+ aTempRect.Left() = aTempRect.Right()-RULER_OFF+1;
+ }
+ Erase( aTempRect );
+ }
+ Invert( aRect );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawTicks( long nMin, long nMax, long nStart, long nCenter )
+{
+ long n = 0;
+ long nTick = 0;
+ long nTick3 = aImplRulerUnitTab[mnUnitIndex].nTick3;
+ long nTickCount = aImplRulerUnitTab[mnUnitIndex].nTick1;
+ Size aPixSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
+ long nTickWidth;
+ long nX;
+ long nY;
+ BOOL bNoTicks = FALSE;
+
+ // Groessenvorberechnung
+ BOOL bVertRight = FALSE;
+ if ( mnWinStyle & WB_HORZ )
+ nTickWidth = aPixSize.Width();
+ else
+ {
+ Font aFont = GetFont();
+ if ( mnWinStyle & WB_RIGHT_ALIGNED )
+ {
+ aFont.SetOrientation( 2700 );
+ bVertRight = TRUE;
+ }
+ else
+ aFont.SetOrientation( 900 );
+ maVirDev.SetFont( aFont );
+ nTickWidth = aPixSize.Height();
+ }
+ long nMaxWidth = maVirDev.PixelToLogic( Size( mpData->nPageWidth, 0 ), maMapMode ).Width();
+ if ( nMaxWidth < 0 )
+ nMaxWidth *= -1;
+ nMaxWidth /= aImplRulerUnitTab[mnUnitIndex].nTickUnit;
+ UniString aNumStr( UniString::CreateFromInt32( nMaxWidth ) );
+ long nTxtWidth = GetTextWidth( aNumStr );
+ if ( (nTxtWidth*2) > nTickWidth )
+ {
+ long nMulti = 1;
+ long nOrgTick3 = nTick3;
+ long nTextOff = 2;
+ while ( nTickWidth < nTxtWidth+nTextOff )
+ {
+ long nOldMulti = nMulti;
+ if ( !nTickWidth )
+ nMulti *= 10;
+ else if ( nMulti < 10 )
+ nMulti++;
+ else if ( nMulti < 100 )
+ nMulti += 10;
+ else if ( nMulti < 1000 )
+ nMulti += 100;
+ else
+ nMulti += 1000;
+ // Ueberlauf, dann geben wir nichts aus, da wir bei so einem
+ // unsinnigen Massstab sowieso nichts vernuenftiges anzeigen
+ // koennen
+ if ( nMulti < nOldMulti )
+ {
+ bNoTicks = TRUE;
+ break;
+ }
+ if ( nMulti >= 100 )
+ nTextOff = 4;
+ nTick3 = nOrgTick3 * nMulti;
+ aPixSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
+ if ( mnWinStyle & WB_HORZ )
+ nTickWidth = aPixSize.Width();
+ else
+ nTickWidth = aPixSize.Height();
+ }
+ nTickCount = nTick3;
+ }
+ else
+ maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
+
+ if ( !bNoTicks )
+ {
+ long nTxtWidth2;
+ long nTxtHeight2 = GetTextHeight()/2;
+ while ( ((nStart-n) >= nMin) || ((nStart+n) <= nMax) )
+ {
+ // Null-Punkt
+ if ( !nTick )
+ {
+ if ( nStart > nMin )
+ {
+ // Nur 0 malen, wenn Margin1 nicht gleich dem NullPunkt ist
+ if ( (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) || (mpData->nMargin1 != 0) )
+ {
+ aNumStr = (sal_Unicode)'0';
+ nTxtWidth2 = maVirDev.GetTextWidth( aNumStr )/2;
+ if ( (mnWinStyle & WB_HORZ)^mpData->bTextRTL )
+ nX = nStart-nTxtWidth2;
+ else
+ nX = nStart+nTxtWidth2;
+ long n_Y = bVertRight ? nCenter+nTxtHeight2 : nCenter-nTxtHeight2;
+ ImplVDrawText( nX, n_Y, aNumStr );
+ }
+ }
+ }
+ else
+ {
+ aPixSize = maVirDev.LogicToPixel( Size( nTick, nTick ), maMapMode );
+
+ if ( mnWinStyle & WB_HORZ )
+ n = aPixSize.Width();
+ else
+ n = aPixSize.Height();
+
+ // Tick3 - Ausgabe (Text)
+ if ( !(nTick % nTick3) )
+ {
+ aNumStr = UniString::CreateFromInt32( nTick / aImplRulerUnitTab[mnUnitIndex].nTickUnit );
+ nTxtWidth2 = GetTextWidth( aNumStr )/2;
+
+ nX = nStart+n;
+ //different orientation needs a different starting position
+ nY = bVertRight ? nCenter+nTxtHeight2 : nCenter-nTxtHeight2;
+ if ( nX < nMax )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ nX -= nTxtWidth2;
+ else
+ nX += nTxtWidth2;
+ ImplVDrawText( nX, nY, aNumStr );
+ }
+ nX = nStart-n;
+ if ( nX > nMin )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ nX -= nTxtWidth2;
+ else
+ nX += nTxtWidth2;
+ ImplVDrawText( nX, nY, aNumStr );
+ }
+ }
+ // Tick/Tick2 - Ausgabe (Striche)
+ else
+ {
+ if ( !(nTick % aImplRulerUnitTab[mnUnitIndex].nTick2) )
+ nTickWidth = RULER_TICK2_WIDTH;
+ else
+ nTickWidth = RULER_TICK1_WIDTH;
+ long nT1 = nCenter-(nTickWidth/2);
+ long nT2 = nT1+nTickWidth-1;
+ long nT;
+
+ nT = nStart+n;
+ if ( nT < nMax )
+ ImplVDrawLine( nT, nT1, nT, nT2 );
+ nT = nStart-n;
+ if ( nT > nMin )
+ ImplVDrawLine( nT, nT1, nT, nT2 );
+ }
+ }
+ // #i49017# with some zoom factors the value nTick can overflow
+ if( ((ULONG)nTick + (ULONG)nTickCount) > (ULONG)LONG_MAX)
+ break;
+ nTick += nTickCount;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawArrows( long nCenter )
+{
+ USHORT i;
+ long n1;
+ long n2;
+ long n3;
+ long n4;
+ long nLogWidth;
+ String aStr;
+ String aStr2;
+ BOOL bDrawUnit;
+ long nTxtWidth;
+ long nTxtHeight2 = GetTextHeight()/2;
+
+ const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
+
+ maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
+ for ( i = 0; i < mpData->nArrows; i++ )
+ {
+ n1 = mpData->pArrows[i].nPos+mpData->nNullVirOff+1;
+ n2 = n1+mpData->pArrows[i].nWidth-2;
+
+ // Einheit umrechnen
+ nLogWidth = mpData->pArrows[i].nLogWidth;
+ if ( meSourceUnit == MAP_TWIP )
+ {
+ if ( nLogWidth >= 100000 )
+ nLogWidth = (nLogWidth*254)/144;
+ else
+ nLogWidth = (nLogWidth*2540)/1440;
+ }
+ if ( nLogWidth >= 1000000 )
+ nLogWidth = (nLogWidth / aImplRulerUnitTab[mnUnitIndex].n100THMM) * 1000;
+ else
+ nLogWidth = (nLogWidth*1000) / aImplRulerUnitTab[mnUnitIndex].n100THMM;
+ aStr = rI18nHelper.GetNum( nLogWidth, aImplRulerUnitTab[mnUnitIndex].nUnitDigits, TRUE, FALSE );
+
+ // Einheit an den String haengen
+ aStr2 = aStr;
+ aStr2.AppendAscii( aImplRulerUnitTab[mnUnitIndex].aUnitStr );
+
+ // Textbreite ermitteln
+ bDrawUnit = TRUE;
+ nTxtWidth = GetTextWidth( aStr2 );
+ if ( nTxtWidth < mpData->pArrows[i].nWidth-10 )
+ aStr = aStr2;
+ else
+ {
+ nTxtWidth = GetTextWidth( aStr );
+ if ( nTxtWidth > mpData->pArrows[i].nWidth-10 )
+ bDrawUnit = FALSE;
+ }
+
+ // Ist genuegen Platz fuer Einheiten-String vorhanden
+ if ( bDrawUnit )
+ {
+ n3 = n1 + ((n2-n1)/2) - 1;
+ if ( mnWinStyle & WB_HORZ )
+ n3 -= nTxtWidth/2;
+ else
+ n3 += nTxtWidth/2;
+ if ( mnWinStyle & WB_HORZ )
+ {
+ n4 = n3 + nTxtWidth + 2;
+ ImplVDrawLine( n1, nCenter, n3, nCenter );
+ ImplVDrawLine( n4, nCenter, n2, nCenter );
+ }
+ else
+ {
+ n4 = n3 - nTxtWidth - 2;
+ ImplVDrawLine( n1, nCenter, n4, nCenter );
+ ImplVDrawLine( n3, nCenter, n2, nCenter );
+ }
+ ImplVDrawText( n3, nCenter-nTxtHeight2, aStr );
+ }
+ else
+ ImplVDrawLine( n1, nCenter, n2, nCenter );
+ ImplVDrawLine( n1+1, nCenter-1, n1+1, nCenter+1 );
+ ImplVDrawLine( n1+2, nCenter-2, n1+2, nCenter+2 );
+ ImplVDrawLine( n2-1, nCenter-1, n2-1, nCenter+1 );
+ ImplVDrawLine( n2-2, nCenter-2, n2-2, nCenter+2 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawBorders( long nMin, long nMax, long nVirTop, long nVirBottom )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long n;
+ long n1;
+ long n2;
+ long nTemp1;
+ long nTemp2;
+ USHORT i;
+
+ for ( i = 0; i < mpData->nBorders; i++ )
+ {
+ if ( mpData->pBorders[i].nStyle & RULER_STYLE_INVISIBLE )
+ continue;
+
+ n1 = mpData->pBorders[i].nPos+mpData->nNullVirOff;
+ n2 = n1+mpData->pBorders[i].nWidth;
+
+ if ( ((n1 >= nMin) && (n1 <= nMax)) || ((n2 >= nMin) && (n2 <= nMax)) )
+ {
+ if ( (n2-n1) > 3 )
+ {
+ maVirDev.SetLineColor();
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ ImplVDrawRect( n1, nVirTop, n2, nVirBottom );
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ ImplVDrawLine( n1+1, nVirTop, n1+1, nVirBottom );
+ ImplVDrawLine( n1, nVirTop, n2, nVirTop );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
+ ImplVDrawLine( n1, nVirBottom, n2, nVirBottom );
+ ImplVDrawLine( n2-1, nVirTop, n2-1, nVirBottom );
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
+ ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
+ }
+
+ if ( mpData->pBorders[i].nStyle & RULER_BORDER_VARIABLE )
+ {
+ if ( n2-n1 > RULER_VAR_SIZE+4 )
+ {
+ nTemp1 = n1 + (((n2-n1+1)-RULER_VAR_SIZE) / 2);
+ nTemp2 = nVirTop + (((nVirBottom-nVirTop+1)-RULER_VAR_SIZE) / 2);
+ long nTemp3 = nTemp1+RULER_VAR_SIZE-1;
+ long nTemp4 = nTemp2+RULER_VAR_SIZE-1;
+ long nTempY = nTemp2;
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ while ( nTempY <= nTemp4 )
+ {
+ ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
+ nTempY += 2;
+ }
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ nTempY = nTemp2+1;
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ while ( nTempY <= nTemp4 )
+ {
+ ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
+ nTempY += 2;
+ }
+ }
+ }
+ }
+
+ if ( mpData->pBorders[i].nStyle & RULER_BORDER_SIZEABLE )
+ {
+ if ( n2-n1 > RULER_VAR_SIZE+10 )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ ImplVDrawLine( n1+4, nVirTop+3, n1+4, nVirBottom-3 );
+ ImplVDrawLine( n2-5, nVirTop+3, n2-5, nVirBottom-3 );
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ ImplVDrawLine( n1+5, nVirTop+3, n1+5, nVirBottom-3 );
+ ImplVDrawLine( n2-4, nVirTop+3, n2-4, nVirBottom-3 );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( n1+4, nVirTop+3, n1+4, nVirBottom-3 );
+ ImplVDrawLine( n2-4, nVirTop+3, n2-4, nVirBottom-3 );
+ }
+ }
+ }
+ }
+ else
+ {
+ n = n1+((n2-n1)/2);
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ if ( mpData->pBorders[i].nStyle & RULER_BORDER_SNAP )
+ ImplVDrawLine( n, nVirTop, n, nVirBottom );
+ else if ( mpData->pBorders[i].nStyle & RULER_BORDER_MARGIN )
+ ImplVDrawLine( n, nVirTop, n, nVirBottom );
+ else
+ {
+ ImplVDrawLine( n-1, nVirTop, n-1, nVirBottom );
+ ImplVDrawLine( n+1, nVirTop, n+1, nVirBottom );
+ maVirDev.SetLineColor();
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ ImplVDrawRect( n, nVirTop, n, nVirBottom );
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawIndent( const Polygon& rPoly, USHORT nStyle )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Point aPos1;
+ Point aPos2;
+ USHORT nIndentStyle = nStyle & RULER_INDENT_STYLE;
+
+ if ( nStyle & RULER_STYLE_INVISIBLE )
+ return;
+
+ if ( nStyle & RULER_STYLE_DONTKNOW )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ }
+
+ maVirDev.DrawPolygon( rPoly );
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && !(nStyle & RULER_STYLE_DONTKNOW) )
+ {
+ if ( nIndentStyle == RULER_INDENT_BOTTOM )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ aPos1 = rPoly.GetPoint( 2 );
+ aPos1.X()++;
+ aPos2 = rPoly.GetPoint( 1 );
+ aPos2.X()++;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ aPos2.X()--;
+ aPos2.Y()++;
+ aPos1 = rPoly.GetPoint( 0 );
+ aPos1.Y()++;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ aPos2 = rPoly.GetPoint( 4 );
+ aPos2.Y()++;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2.X()--;
+ aPos1 = rPoly.GetPoint( 3 );
+ aPos1.X()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ aPos1.Y()--;
+ aPos2 = rPoly.GetPoint( 2 );
+ aPos2.X()++;
+ aPos2.Y()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ aPos1 = rPoly.GetPoint( 2 );
+ aPos1.X()++;
+ aPos1.Y()++;
+ aPos2 = rPoly.GetPoint( 3 );
+ aPos2.Y()++;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2 = rPoly.GetPoint( 1 );
+ aPos2.X()++;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2.X()--;
+ aPos2.Y()--;
+ aPos1 = rPoly.GetPoint( 0 );
+ aPos1.Y()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ aPos2 = rPoly.GetPoint( 4 );
+ aPos2.Y()--;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2.X()--;
+ aPos1 = rPoly.GetPoint( 3 );
+ aPos1.X()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ }
+
+ maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ maVirDev.SetFillColor();
+ maVirDev.DrawPolygon( rPoly );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawIndents( long nMin, long nMax, long nVirTop, long nVirBottom )
+{
+ USHORT j;
+ long n;
+ long nIndentHeight = (mnVirHeight/2) - 1;
+ long nIndentWidth2 = nIndentHeight-3;
+ Polygon aPoly( 5 );
+
+ for ( j = 0; j < mpData->nIndents; j++ )
+ {
+ if ( mpData->pIndents[j].nStyle & RULER_STYLE_INVISIBLE )
+ continue;
+
+ USHORT nStyle = mpData->pIndents[j].nStyle;
+ USHORT nIndentStyle = nStyle & RULER_INDENT_STYLE;
+
+ n = mpData->pIndents[j].nPos+mpData->nNullVirOff;
+
+ if ( (n >= nMin) && (n <= nMax) )
+ {
+ if(nIndentStyle == RULER_INDENT_BORDER)
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ ImplVDrawLine( n, nVirTop, n, nVirBottom );
+ }
+ else if ( nIndentStyle == RULER_INDENT_BOTTOM )
+ {
+ aPoly.SetPoint( Point( n+0, nVirBottom-nIndentHeight ), 0 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirBottom-3 ), 1 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirBottom ), 2 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirBottom ), 3 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirBottom-3 ), 4 );
+ }
+ else
+ {
+ aPoly.SetPoint( Point( n+0, nVirTop+nIndentHeight ), 0 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirTop+3 ), 1 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirTop ), 2 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirTop ), 3 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirTop+3 ), 4 );
+ }
+
+ if(0 == (mnWinStyle & WB_HORZ))
+ {
+ Point aTmp;
+ for(USHORT i = 0; i < 5; i++)
+ {
+ aTmp = aPoly[i];
+ Point aSet(nVirBottom - aTmp.Y(), aTmp.X());
+ aPoly[i] = aSet;
+ }
+ }
+ if(RULER_INDENT_BORDER != nIndentStyle)
+ ImplDrawIndent( aPoly, nStyle );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCenterTabPos( Point& rPos, USHORT nTabStyle )
+{
+ BOOL bRTL = 0 != (nTabStyle & RULER_TAB_RTL);
+ nTabStyle &= RULER_TAB_STYLE;
+ rPos.Y() += RULER_TAB_HEIGHT/2;
+ if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) ||( bRTL && nTabStyle == RULER_TAB_RIGHT))
+ rPos.X() -= RULER_TAB_WIDTH/2;
+ else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||( bRTL && nTabStyle == RULER_TAB_LEFT))
+ rPos.X() += RULER_TAB_WIDTH/2;
+}
+
+// -----------------------------------------------------------------------
+void lcl_RotateRect_Impl(Rectangle& rRect, const long nReference, BOOL bRightAligned)
+{
+ if(!rRect.IsEmpty())
+ {
+ Rectangle aTmp(rRect);
+ rRect.Top() = aTmp.Left();
+ rRect.Bottom() = aTmp.Right();
+ rRect.Left() = aTmp.Top();
+ rRect.Right() = aTmp.Bottom();
+ if(bRightAligned)
+ {
+ long nRef = 2 * nReference;
+ rRect.Left() = nRef - rRect.Left();
+ rRect.Right() = nRef - rRect.Right();
+ }
+ }
+}
+// -----------------------------------------------------------------------
+
+static void ImplDrawRulerTab( OutputDevice* pDevice,
+ const Point& rPos, USHORT nStyle, WinBits nWinBits )
+{
+ if ( nStyle & RULER_STYLE_INVISIBLE )
+ return;
+
+ USHORT nTabStyle = nStyle & RULER_TAB_STYLE;
+ BOOL bRTL = 0 != (nStyle & RULER_TAB_RTL);
+ Rectangle aRect1, aRect2, aRect3;
+ aRect3.SetEmpty();
+ if ( nTabStyle == RULER_TAB_DEFAULT )
+ {
+ aRect1.Left() = rPos.X() - RULER_TAB_DWIDTH2 + 1 ;
+ aRect1.Top() = rPos.Y() - RULER_TAB_DHEIGHT2 + 1 ;
+ aRect1.Right() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH ;
+ aRect1.Bottom() = rPos.Y();
+ aRect2.Left() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3;
+ aRect2.Top() = rPos.Y() - RULER_TAB_DHEIGHT + 1;
+ aRect2.Right() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3 + RULER_TAB_DWIDTH4 - 1;
+ aRect2.Bottom() = rPos.Y();
+
+ }
+ else if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) ||( bRTL && nTabStyle == RULER_TAB_RIGHT))
+ {
+ aRect1.Left() = rPos.X();
+ aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
+ aRect1.Right() = rPos.X() + RULER_TAB_WIDTH - 1;
+ aRect1.Bottom() = rPos.Y();
+ aRect2.Left() = rPos.X();
+ aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
+ aRect2.Right() = rPos.X() + RULER_TAB_WIDTH2 - 1;
+ aRect2.Bottom() = rPos.Y();
+ }
+ else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||( bRTL && nTabStyle == RULER_TAB_LEFT))
+ {
+ aRect1.Left() = rPos.X() - RULER_TAB_WIDTH + 1;
+ aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
+ aRect1.Right() = rPos.X();
+ aRect1.Bottom() = rPos.Y();
+ aRect2.Left() = rPos.X() - RULER_TAB_WIDTH2 + 1;
+ aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
+ aRect2.Right() = rPos.X();
+ aRect2.Bottom() = rPos.Y();
+ }
+ else
+ {
+ aRect1.Left() = rPos.X() - RULER_TAB_CWIDTH2 + 1;
+ aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
+ aRect1.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
+ aRect1.Bottom() = rPos.Y();
+ aRect2.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3;
+ aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
+ aRect2.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3 + RULER_TAB_CWIDTH4 - 1;
+ aRect2.Bottom() = rPos.Y();
+
+ if ( nTabStyle == RULER_TAB_DECIMAL )
+ {
+ aRect3.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH - 1;
+ aRect3.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1 + 1;
+ aRect3.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
+ aRect3.Bottom()= rPos.Y() - RULER_TAB_HEIGHT + 1 + 2 ;
+ }
+ }
+ if( 0 == (nWinBits&WB_HORZ) )
+ {
+ BOOL bRightAligned = 0 != (nWinBits&WB_RIGHT_ALIGNED);
+ lcl_RotateRect_Impl(aRect1, rPos.Y(), bRightAligned);
+ lcl_RotateRect_Impl(aRect2, rPos.Y(), bRightAligned);
+ lcl_RotateRect_Impl(aRect3, rPos.Y(), bRightAligned);
+ }
+ pDevice->DrawRect( aRect1 );
+ pDevice->DrawRect( aRect2 );
+ if(!aRect2.IsEmpty())
+ pDevice->DrawRect( aRect3 );
+
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawTab( OutputDevice* pDevice, const Point& rPos, USHORT nStyle )
+{
+ if ( nStyle & RULER_STYLE_INVISIBLE )
+ return;
+
+ pDevice->SetLineColor();
+ if ( nStyle & RULER_STYLE_DONTKNOW )
+ pDevice->SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
+ else
+ pDevice->SetFillColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
+
+ if(mpData->bTextRTL)
+ nStyle |= RULER_TAB_RTL;
+ ImplDrawRulerTab( pDevice, rPos, nStyle, GetStyle());
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawTabs( long nMin, long nMax, long nVirTop, long nVirBottom )
+{
+ for ( USHORT i = 0; i < mpData->nTabs; i++ )
+ {
+ if ( mpData->pTabs[i].nStyle & RULER_STYLE_INVISIBLE )
+ continue;
+
+ long n;
+ n = mpData->pTabs[i].nPos;
+ n += +mpData->nNullVirOff;
+ long nTopBottom = GetStyle() & WB_RIGHT_ALIGNED ? nVirTop : nVirBottom;
+ if ( (n >= nMin) && (n <= nMax) )
+ ImplDrawTab( &maVirDev, Point( n, nTopBottom ), mpData->pTabs[i].nStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetWindowTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+
+ maVirDev.SetSettings( GetSettings() );
+ maVirDev.SetBackground( GetBackground() );
+ Font aFont = GetFont();
+ if ( mnWinStyle & WB_VERT )
+ aFont.SetOrientation( 900 );
+ maVirDev.SetFont( aFont );
+ maVirDev.SetTextColor( GetTextColor() );
+ maVirDev.SetTextFillColor( GetTextFillColor() );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplCalc()
+{
+ // Offset berechnen
+ mpData->nRulVirOff = mnWinOff + mpData->nPageOff;
+ if ( mpData->nRulVirOff > mnVirOff )
+ mpData->nRulVirOff -= mnVirOff;
+ else
+ mpData->nRulVirOff = 0;
+ long nRulWinOff = mpData->nRulVirOff+mnVirOff;
+
+ // Nicht sichtbaren Bereich der Page berechnen
+ long nNotVisPageWidth;
+ if ( mpData->nPageOff < 0 )
+ {
+ nNotVisPageWidth = -(mpData->nPageOff);
+ if ( nRulWinOff < mnWinOff )
+ nNotVisPageWidth -= mnWinOff-nRulWinOff;
+ }
+ else
+ nNotVisPageWidth = 0;
+
+ // Breite berechnen
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( mbAutoWinWidth )
+ mnWinWidth = mnWidth - mnVirOff;
+ if ( mpData->bAutoPageWidth )
+ mpData->nPageWidth = mnWinWidth;
+ mpData->nRulWidth = Min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
+ if ( nRulWinOff+mpData->nRulWidth > mnWidth )
+ mpData->nRulWidth = mnWidth-nRulWinOff;
+ }
+ else
+ {
+ if ( mbAutoWinWidth )
+ mnWinWidth = mnHeight - mnVirOff;
+ if ( mpData->bAutoPageWidth )
+ mpData->nPageWidth = mnWinWidth;
+ mpData->nRulWidth = Min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
+ if ( nRulWinOff+mpData->nRulWidth > mnHeight )
+ mpData->nRulWidth = mnHeight-nRulWinOff;
+ }
+
+ mbCalc = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplFormat()
+{
+ // Wenn schon formatiert ist, brauchen wir es nicht nochmal
+ if ( !mbFormat )
+ return;
+
+ // Wenn Fenster noch keine Groesse hat, brauchen wir noch nichts machen
+ if ( !mnVirWidth )
+ return;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long nP1; // Pixel-Position von Page1
+ long nP2; // Pixel-Position von Page2
+ long nM1; // Pixel-Position von Margin1
+ long nM2; // Pixel-Position von Margin2
+ long nVirTop; // Obere/Linke-Kante bei Ausgabe
+ long nVirBottom; // Untere/Rechte-Kante bei Ausgabe
+ long nVirLeft; // Linke/Obere-Kante bei Ausgabe
+ long nVirRight; // Rechte/Untere-Kante bei Ausgabe
+ long nNullVirOff; // Fuer schnellere Berechnung
+
+ // Werte berechnen
+ if ( mbCalc )
+ ImplCalc();
+ mpData->nNullVirOff = mnWinOff+mpData->nPageOff+mpData->nNullOff-mnVirOff;
+ nNullVirOff = mpData->nNullVirOff;
+ nVirLeft = mpData->nRulVirOff;
+ nVirRight = nVirLeft+mpData->nRulWidth-1;
+ nVirTop = 0;
+ nVirBottom = mnVirHeight-1;
+
+ if ( !IsReallyVisible() )
+ return;
+
+ Size aVirDevSize;
+ BOOL b3DLook = !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO);
+
+ // VirtualDevice initialisieren
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aVirDevSize.Width() = mnVirWidth;
+ aVirDevSize.Height() = mnVirHeight;
+ }
+ else
+ {
+ aVirDevSize.Height() = mnVirWidth;
+ aVirDevSize.Width() = mnVirHeight;
+ }
+ if ( aVirDevSize != maVirDev.GetOutputSizePixel() )
+ maVirDev.SetOutputSizePixel( aVirDevSize, TRUE );
+ else
+ maVirDev.Erase();
+
+ // Raender berechnen
+ if ( !(mpData->nMargin1Style & RULER_STYLE_INVISIBLE) )
+ {
+ nM1 = mpData->nMargin1+nNullVirOff;
+ if ( mpData->bAutoPageWidth )
+ {
+ nP1 = nVirLeft;
+ if ( nM1 < nVirLeft )
+ nP1--;
+ }
+ else
+ nP1 = nNullVirOff-mpData->nNullOff;
+ }
+ else
+ {
+ nM1 = nVirLeft-1;
+ nP1 = nM1;
+ }
+ if ( !(mpData->nMargin2Style & RULER_STYLE_INVISIBLE) )
+ {
+ nM2 = mpData->nMargin2+nNullVirOff;
+ if ( mpData->bAutoPageWidth )
+ {
+ nP2 = nVirRight;
+ if ( nM2 > nVirRight )
+ nP2++;
+ }
+ else
+ nP2 = nNullVirOff-mpData->nNullOff+mpData->nPageWidth;
+ if ( nM2 > nP2 )
+ nM2 = nP2;
+ }
+ else
+ {
+ nM2 = nVirRight+1;
+ nP2 = nM2;
+ }
+
+ // Obere/untere Kante ausgeben
+ if ( b3DLook )
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( nVirLeft, nVirTop, nM1 - 1, nVirTop ); //top left line
+ ImplVDrawLine( nM2 +1, nVirTop, nP2 -1, nVirTop ); //top right line
+
+ // Jetzt wird zwischen dem Schatten ausgegeben
+ nVirTop++;
+ nVirBottom--;
+
+ // Margin1, Margin2 und Zwischenraum ausgeben
+ maVirDev.SetLineColor();
+ if ( b3DLook )
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ if ( nM1 > nVirLeft )
+ ImplVDrawRect( nP1, nVirTop, nM1-1, nVirBottom ); //left gray rectangle
+ if ( nM2 < nP2 )
+ ImplVDrawRect( nM2+1, nVirTop, nP2, nVirBottom ); //right gray rectangle
+ if ( nM2-nM1 > 0 )
+ {
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ ImplVDrawRect( nM1, nVirTop, nM2-1, nVirBottom ); //center rectangle
+ }
+ if ( b3DLook )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ if ( nM1 > nVirLeft )
+ {
+ ImplVDrawLine( nM1-1, nVirTop, nM1-1, nVirBottom );//right line of the left rectangle
+ ImplVDrawLine( nP1, nVirBottom, nM1-1, nVirBottom );//bottom line of the left rectangle
+ if ( nP1 >= nVirLeft )
+ {
+ ImplVDrawLine( nP1, nVirTop, nP1, nVirBottom );//left line of the left rectangle
+ ImplVDrawLine( nP1, nVirBottom, nP1+1, nVirBottom );//?
+ }
+ }
+ if ( nM2 < nP2 )
+ {
+ ImplVDrawLine( nM2+1, nVirBottom, nP2-1, nVirBottom );//bottom line of the right rectangle
+ ImplVDrawLine( nM2+1, nVirTop, nM2+1, nVirBottom );//left line of the right rectangle
+ if ( nP2 <= nVirRight+1 )
+ ImplVDrawLine( nP2-1, nVirTop, nP2-1, nVirBottom );//right line of the right rectangle
+ }
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ if ( nP1 >= nVirLeft )
+ ImplVDrawLine( nP1, nVirTop, nP1, nVirBottom+1 );
+ if ( nM1 > nP1 )
+ ImplVDrawLine( nM1, nVirTop, nM1, nVirBottom );
+ if ( nM2 < nP2 )
+ ImplVDrawLine( nM2, nVirTop, nM2, nVirBottom );
+ if ( nP2 <= nVirRight+1 )
+ ImplVDrawLine( nP2, nVirTop, nP2, nVirBottom+1 );
+ }
+
+ // Lineal-Beschriftung (nur wenn keine Bemassungspfeile)
+ if ( !mpData->pArrows )
+ {
+ long nMin = nVirLeft;
+ long nMax = nP2;
+ long nStart = mpData->bTextRTL ? mpData->nMargin2 + nNullVirOff : nNullVirOff;
+ long nCenter = nVirTop+((nVirBottom-nVirTop)/2);
+
+ // Nicht Schatten uebermalen
+ if ( nP1 > nVirLeft )
+ nMin++;
+ if ( nP2 < nVirRight )
+ nMax--;
+
+ // Beschriftung ausgeben
+ ImplDrawTicks( nMin, nMax, nStart, nCenter );
+ }
+
+ // Spalten ausgeben
+ if ( mpData->pBorders )
+ ImplDrawBorders( nVirLeft, nP2, nVirTop, nVirBottom );
+
+ // Einzuege ausgeben
+ if ( mpData->pIndents )
+ ImplDrawIndents( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
+
+ // Tabs
+ if ( mpData->pTabs )
+ {
+ ImplDrawTabs( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
+ }
+
+ // Bemassungspfeile
+ if ( mpData->pArrows )
+ ImplDrawArrows( nVirTop+((nVirBottom-nVirTop)/2) );
+
+ // Wir haben formatiert
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplInitExtraField( BOOL bUpdate )
+{
+ // Extra-Field beruecksichtigen
+ if ( mnWinStyle & WB_EXTRAFIELD )
+ {
+ maExtraRect.Left() = RULER_OFF;
+ maExtraRect.Top() = RULER_OFF;
+ maExtraRect.Right() = RULER_OFF+mnVirHeight-1;
+ maExtraRect.Bottom() = RULER_OFF+mnVirHeight-1;
+ if(mpData->bTextRTL)
+ {
+ Size aWinSize = GetOutputSizePixel();
+ if(mnWinStyle & WB_HORZ)
+ maExtraRect.Move(aWinSize.Width() - maExtraRect.GetWidth() - maExtraRect.Left(), 0);
+ else
+ maExtraRect.Move(0, aWinSize.Height() - maExtraRect.GetHeight() - maExtraRect.Top());
+ mnVirOff = 0;
+ }
+ else
+ mnVirOff = maExtraRect.Right()+1;
+
+ }
+ else
+ {
+ maExtraRect.SetEmpty();
+ mnVirOff = 0;
+ }
+
+ if ( bUpdate )
+ {
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDraw()
+{
+ if ( mbFormat )
+ ImplFormat();
+
+ if ( IsReallyVisible() )
+ {
+ // Lineal ueber das VirtualDevice ausgeben
+ Point aOffPos;
+ Size aVirDevSize = maVirDev.GetOutputSizePixel();
+// Size aVirDevSize2 = maVirDev.GetOutputSizePixel();
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aOffPos.X() = mnVirOff;
+ if(mpData->bTextRTL)
+ aVirDevSize.Width() -= maExtraRect.GetWidth();
+
+// else
+// aVirDevSize.Width() -= mnVirOff;
+ aOffPos.Y() = RULER_OFF;
+ }
+ else
+ {
+ aOffPos.X() = RULER_OFF;
+ aOffPos.Y() = mnVirOff;
+// else
+// aVirDevSize.Height() -= mnVirOff;
+ }
+ DrawOutDev( aOffPos, aVirDevSize, Point(), aVirDevSize, maVirDev );
+
+ // Positionslinien neu malen
+ ImplInvertLines( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawExtra( BOOL bPaint )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aRect = maExtraRect;
+ BOOL bEraseRect = FALSE;
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+ }
+ else
+ {
+ aRect.Left() += 1;
+ aRect.Top() += 1;
+ aRect.Right() -= 1;
+ aRect.Bottom() -= 1;
+ }
+
+ if ( !bPaint && !(mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ SetFillColor( rStyleSettings.GetWindowColor() );
+ bEraseRect = TRUE;
+ }
+ else
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && (mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
+ {
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ bEraseRect = TRUE;
+ }
+ }
+
+ if ( bEraseRect )
+ {
+ SetLineColor();
+ DrawRect( aRect );
+ }
+
+ // Inhalt ausgeben
+ if ( meExtraType == RULER_EXTRA_NULLOFFSET )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ SetLineColor( rStyleSettings.GetButtonTextColor() );
+ else
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( Point( aRect.Left()+1, aRect.Top()+4 ),
+ Point( aRect.Right()-1, aRect.Top()+4 ) );
+ DrawLine( Point( aRect.Left()+4, aRect.Top()+1 ),
+ Point( aRect.Left()+4, aRect.Bottom()-1 ) );
+ }
+ else if ( meExtraType == RULER_EXTRA_TAB )
+ {
+ USHORT nTabStyle = mnExtraStyle & RULER_TAB_STYLE;
+ if(mpData->bTextRTL)
+ nTabStyle |= RULER_TAB_RTL;
+ Point aCenter = aRect.Center();
+ Point aDraw(aCenter);
+ ImplCenterTabPos( aDraw, nTabStyle );
+ WinBits nWinBits = GetStyle();
+ if(0 == (nWinBits&WB_HORZ) )
+ {
+ if(0 != (nWinBits&WB_RIGHT_ALIGNED))
+ aDraw.Y() = 2 * aCenter.Y() - aDraw.Y();
+ if(mpData->bTextRTL)
+ {
+ long nTemp = aDraw.X();
+ aDraw.X() = aDraw.Y();
+ aDraw.Y() = nTemp;
+ }
+ }
+ ImplDrawTab( this, aDraw, nTabStyle );
+ }
+
+ if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && (mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
+ Invert( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplUpdate( BOOL bMustCalc )
+{
+ // Hier schon Linien loeschen, damit Sie vor dem Neuberechnen schon
+ // geloscht sind, da danach die alten Positionen nicht mehr bestimmt
+ // werden koennen
+ if ( !mbFormat )
+ ImplInvertLines();
+
+ // Flags setzen
+ if ( bMustCalc )
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+
+ // Wenn wir am Draggen sind, wird nach dem Drag-Handler automatisch
+ // das Lineal neu upgedatet
+ if ( mbDrag )
+ return;
+
+ // Gegebenenfalls Update ausloesen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ mnUpdateFlags |= RULER_UPDATE_DRAW;
+ if ( !mnUpdateEvtId )
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::ImplHitTest( const Point& rPos, ImplRulerHitTest* pHitTest,
+ BOOL bRequireStyle, USHORT nRequiredStyle ) const
+{
+ USHORT i;
+ USHORT nStyle;
+ long nHitBottom;
+ long nX;
+ long nY;
+ long n1;
+ long n2;
+
+ if ( !mbActive )
+ return FALSE;
+
+ // Position ermitteln
+ BOOL bIsHori = 0 != (mnWinStyle & WB_HORZ);
+ if ( bIsHori )
+ {
+ nX = rPos.X();
+ nY = rPos.Y();
+ }
+ else
+ {
+ nX = rPos.Y();
+ nY = rPos.X();
+ }
+ nHitBottom = mnVirHeight+(RULER_OFF*2);
+
+ // --> FME 2004-08-05 #i32608#
+ pHitTest->nAryPos = 0;
+ pHitTest->mnDragSize = 0;
+ pHitTest->bSize = FALSE;
+ pHitTest->bSizeBar = FALSE;
+ // <--
+
+ // Damit ueberstehende Tabs und Einzuege mit beruecksichtigt werden
+ long nXExtraOff;
+ if ( mpData->pTabs || mpData->pIndents )
+ nXExtraOff = (mnVirHeight/2) - 4;
+ else
+ nXExtraOff = 0;
+
+ // Test auf ausserhalb
+ nX -= mnVirOff;
+ long nXTemp = nX;
+ if ( (nX < mpData->nRulVirOff-nXExtraOff) || (nX > mpData->nRulVirOff+mpData->nRulWidth+nXExtraOff) ||
+ (nY < 0) || (nY > nHitBottom) )
+ {
+ pHitTest->nPos = 0;
+ pHitTest->eType = RULER_TYPE_OUTSIDE;
+ return FALSE;
+ }
+
+ nX -= mpData->nNullVirOff;
+ pHitTest->nPos = nX;
+ pHitTest->eType = RULER_TYPE_DONTKNOW;
+
+ // Zuerst die Tabs testen
+ Rectangle aRect;
+ if ( mpData->pTabs )
+ {
+ aRect.Bottom() = nHitBottom;
+ aRect.Top() = aRect.Bottom()-RULER_TAB_HEIGHT-RULER_OFF;
+
+ for ( i = mpData->nTabs; i; i-- )
+ {
+ nStyle = mpData->pTabs[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ nStyle &= RULER_TAB_STYLE;
+
+ // Default-Tabs werden nur angezeigt
+ if ( nStyle != RULER_TAB_DEFAULT )
+ {
+ n1 = mpData->pTabs[i-1].nPos;
+
+ if ( nStyle == RULER_TAB_LEFT )
+ {
+ aRect.Left() = n1;
+ aRect.Right() = n1+RULER_TAB_WIDTH-1;
+ }
+ else if ( nStyle == RULER_TAB_RIGHT )
+ {
+ aRect.Right() = n1;
+ aRect.Left() = n1-RULER_TAB_WIDTH-1;
+ }
+ else
+ {
+ aRect.Left() = n1-RULER_TAB_CWIDTH2+1;
+ aRect.Right() = n1-RULER_TAB_CWIDTH2+RULER_TAB_CWIDTH;
+ }
+
+ if ( aRect.IsInside( Point( nX, nY ) ) )
+ {
+ pHitTest->eType = RULER_TYPE_TAB;
+ pHitTest->nAryPos = i-1;
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ // Dann die Einzuege
+ if ( mpData->pIndents )
+ {
+ long nIndentHeight = (mnVirHeight/2) - 1;
+ long nIndentWidth2 = nIndentHeight-3;
+
+ for ( i = mpData->nIndents; i; i-- )
+ {
+ nStyle = mpData->pIndents[i-1].nStyle;
+ if ( (! bRequireStyle || nStyle == nRequiredStyle) &&
+ !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ nStyle &= RULER_INDENT_STYLE;
+ n1 = mpData->pIndents[i-1].nPos;
+
+ if ( (nStyle == RULER_INDENT_BOTTOM) ^ (!bIsHori) )
+ {
+ aRect.Left() = n1-nIndentWidth2;
+ aRect.Right() = n1+nIndentWidth2;
+ aRect.Top() = nHitBottom-nIndentHeight-RULER_OFF+1;
+ aRect.Bottom() = nHitBottom;
+ }
+ else
+ {
+ aRect.Left() = n1-nIndentWidth2;
+ aRect.Right() = n1+nIndentWidth2;
+ aRect.Top() = 0;
+ aRect.Bottom() = nIndentHeight+RULER_OFF-1;
+ }
+
+ if ( aRect.IsInside( Point( nX, nY ) ) )
+ {
+ pHitTest->eType = RULER_TYPE_INDENT;
+ pHitTest->nAryPos = i-1;
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ // Jetzt zaehlt nichts mehr, was links oder rechts uebersteht
+ if ( (nXTemp < mpData->nRulVirOff) || (nXTemp > mpData->nRulVirOff+mpData->nRulWidth) )
+ {
+ pHitTest->nPos = 0;
+ pHitTest->eType = RULER_TYPE_OUTSIDE;
+ return FALSE;
+ }
+
+ // Danach die Spalten testen
+ int nBorderTolerance = 1;
+ if(pHitTest->bExpandTest)
+ {
+ nBorderTolerance++;
+ }
+
+ for ( i = mpData->nBorders; i; i-- )
+ {
+ n1 = mpData->pBorders[i-1].nPos;
+ n2 = n1 + mpData->pBorders[i-1].nWidth;
+
+ // Spalten werden mit mindestens 3 Pixel breite gezeichnet
+ if ( !mpData->pBorders[i-1].nWidth )
+ {
+ n1 -= nBorderTolerance;
+ n2 += nBorderTolerance;
+
+ }
+
+ if ( (nX >= n1) && (nX <= n2) )
+ {
+ nStyle = mpData->pBorders[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ pHitTest->eType = RULER_TYPE_BORDER;
+ pHitTest->nAryPos = i-1;
+
+ if ( !(nStyle & RULER_BORDER_SIZEABLE) )
+ {
+ if ( nStyle & RULER_BORDER_MOVEABLE )
+ {
+ pHitTest->bSizeBar = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
+ }
+ }
+ else
+ {
+ long nMOff = RULER_MOUSE_BORDERWIDTH;
+ while ( nMOff*2 >= (n2-n1-RULER_MOUSE_BORDERMOVE) )
+ {
+ if ( nMOff < 2 )
+ {
+ nMOff = 0;
+ break;
+ }
+ else
+ nMOff--;
+ }
+
+ if ( nX <= n1+nMOff )
+ {
+ pHitTest->bSize = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_1;
+ }
+ else if ( nX >= n2-nMOff )
+ {
+ pHitTest->bSize = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_2;
+ }
+ else
+ {
+ if ( nStyle & RULER_BORDER_MOVEABLE )
+ {
+ pHitTest->bSizeBar = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
+ }
+ }
+ }
+
+ return TRUE;
+ }
+ }
+ }
+
+ // Und zum Schluss die Raender
+ int nMarginTolerance = pHitTest->bExpandTest ? nBorderTolerance : RULER_MOUSE_MARGINWIDTH;
+
+ if ( (mpData->nMargin1Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
+ {
+ n1 = mpData->nMargin1;
+ if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
+ {
+ pHitTest->eType = RULER_TYPE_MARGIN1;
+ pHitTest->bSize = TRUE;
+ return TRUE;
+ }
+ }
+ if ( (mpData->nMargin2Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
+ {
+ n1 = mpData->nMargin2;
+ if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
+ {
+ pHitTest->eType = RULER_TYPE_MARGIN2;
+ pHitTest->bSize = TRUE;
+ return TRUE;
+ }
+ }
+
+ // Jetzt nocheinmal die Tabs testen, nur mit etwas mehr spielraum
+ if ( mpData->pTabs )
+ {
+ aRect.Top() = RULER_OFF;
+ aRect.Bottom() = nHitBottom;
+
+ for ( i = mpData->nTabs; i; i-- )
+ {
+ nStyle = mpData->pTabs[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ nStyle &= RULER_TAB_STYLE;
+
+ // Default-Tabs werden nur angezeigt
+ if ( nStyle != RULER_TAB_DEFAULT )
+ {
+ n1 = mpData->pTabs[i-1].nPos;
+
+ if ( nStyle == RULER_TAB_LEFT )
+ {
+ aRect.Left() = n1;
+ aRect.Right() = n1+RULER_TAB_WIDTH-1;
+ }
+ else if ( nStyle == RULER_TAB_RIGHT )
+ {
+ aRect.Right() = n1;
+ aRect.Left() = n1-RULER_TAB_WIDTH-1;
+ }
+ else
+ {
+ aRect.Left() = n1-RULER_TAB_CWIDTH2+1;
+ aRect.Right() = n1-RULER_TAB_CWIDTH2+RULER_TAB_CWIDTH;
+ }
+
+ aRect.Left()--;
+ aRect.Right()++;
+
+ if ( aRect.IsInside( Point( nX, nY ) ) )
+ {
+ pHitTest->eType = RULER_TYPE_TAB;
+ pHitTest->nAryPos = i-1;
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::ImplDocHitTest( const Point& rPos, RulerType eDragType,
+ ImplRulerHitTest* pHitTest ) const
+{
+ Point aPos = rPos;
+ BOOL bRequiredStyle = FALSE;
+ USHORT nRequiredStyle = 0;
+
+ if (eDragType == RULER_TYPE_INDENT)
+ {
+ bRequiredStyle = TRUE;
+ nRequiredStyle = RULER_INDENT_BOTTOM;
+ }
+
+ if ( mnWinStyle & WB_HORZ )
+ aPos.X() += mnWinOff;
+ else
+ aPos.Y() += mnWinOff;
+
+ if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_DONTKNOW) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPos.Y() = RULER_OFF+1;
+ else
+ aPos.X() = RULER_OFF+1;
+
+ // HitTest durchfuehren
+ if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
+ {
+ if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
+ return TRUE;
+ }
+ }
+
+ if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_TAB) ||
+ (eDragType == RULER_TYPE_DONTKNOW) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPos.Y() = mnHeight-RULER_OFF-1;
+ else
+ aPos.X() = mnWidth-RULER_OFF-1;
+
+ // HitTest durchfuehren
+ if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
+ {
+ if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
+ return TRUE;
+ }
+ }
+
+ if ( (eDragType == RULER_TYPE_MARGIN1) || (eDragType == RULER_TYPE_MARGIN2) ||
+ (eDragType == RULER_TYPE_BORDER) || (eDragType == RULER_TYPE_DONTKNOW) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPos.Y() = RULER_OFF + (mnVirHeight/2);
+ else
+ aPos.X() = RULER_OFF + (mnVirHeight/2);
+
+ // HitTest durchfuehren
+ if ( ImplHitTest( aPos, pHitTest ) )
+ {
+ if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
+ return TRUE;
+ }
+ }
+
+ // Auf DontKnow setzen
+ pHitTest->eType = RULER_TYPE_DONTKNOW;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::ImplStartDrag( ImplRulerHitTest* pHitTest, USHORT nModifier )
+{
+ // Wenn eine Spalte angeklick wurde, die weder verschiebar noch
+ // in der Groesse aenderbar ist, brauchen wir auch kein Drag ausloesen
+ if ( (pHitTest->eType == RULER_TYPE_BORDER) &&
+ !pHitTest->bSize && !pHitTest->bSizeBar )
+ return FALSE;
+
+ // Dragdaten setzen
+ meDragType = pHitTest->eType;
+ mnDragPos = pHitTest->nPos;
+ mnDragAryPos = pHitTest->nAryPos;
+ mnDragSize = pHitTest->mnDragSize;
+ mnDragModifier = nModifier;
+ *mpDragData = *mpSaveData;
+ mpData = mpDragData;
+
+ // Handler rufen
+ if ( StartDrag() )
+ {
+ // Wenn der Handler das Draggen erlaubt, dann das Draggen
+ // initialisieren
+ ImplInvertLines();
+ mbDrag = TRUE;
+ mnStartDragPos = mnDragPos;
+ StartTracking();
+ return TRUE;
+ }
+ else
+ {
+ // Ansonsten muessen wir die Daten zuruecksetzen
+ meDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+ mnDragSize = 0;
+ mnDragModifier = 0;
+ mpData = mpSaveData;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrag( const Point& rPos )
+{
+ long nX;
+ long nY;
+ long nOutHeight;
+
+ if ( mnWinStyle & WB_HORZ )
+ {
+ nX = rPos.X();
+ nY = rPos.Y();
+ nOutHeight = mnHeight;
+ }
+ else
+ {
+ nX = rPos.Y();
+ nY = rPos.X();
+ nOutHeight = mnWidth;
+ }
+
+ // X berechnen und einpassen
+ nX -= mnVirOff;
+ if ( nX < mpData->nRulVirOff )
+ {
+ nX = mpData->nRulVirOff;
+ mnDragScroll = RULER_SCROLL_1;
+ }
+ else if ( nX > mpData->nRulVirOff+mpData->nRulWidth )
+ {
+ nX = mpData->nRulVirOff+mpData->nRulWidth;
+ mnDragScroll = RULER_SCROLL_2;
+ }
+ nX -= mpData->nNullVirOff;
+
+ // Wenn oberhalb oder links vom Lineal, dann alte Werte
+ mbDragDelete = FALSE;
+ if ( nY < 0 )
+ {
+ if ( !mbDragCanceled )
+ {
+ // Daten wiederherstellen
+ mbDragCanceled = TRUE;
+ ImplRulerData aTempData;
+ aTempData = *mpDragData;
+ *mpDragData = *mpSaveData;
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+
+ // Handler rufen
+ mnDragPos = mnStartDragPos;
+ Drag();
+
+ // Und neu ausgeben (zeitverzoegert)
+/*
+ mnUpdateFlags |= RULER_UPDATE_DRAW;
+ if ( mnUpdateEvtId )
+ Application::RemoveUserEvent( mnUpdateEvtId );
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+*/
+ ImplDraw();
+
+ // Daten wieder wie vor dem Cancel herstellen
+ *mpDragData = aTempData;
+ }
+ }
+ else
+ {
+ mbDragCanceled = FALSE;
+
+ // +2, damit nicht so schnell die Tabs geloescht werden
+ if ( nY > nOutHeight+2 )
+ mbDragDelete = TRUE;
+
+ mnDragPos = nX;
+
+ // Handler rufen
+ Drag();
+
+ // Und neu ausgeben
+ if ( mbFormat )
+ ImplDraw();
+ }
+
+ mnDragScroll = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplEndDrag()
+{
+ // Werte uebernehmen
+ if ( mbDragCanceled )
+ *mpDragData = *mpSaveData;
+ else
+ *mpSaveData = *mpDragData;
+ mpData = mpSaveData;
+ mbDrag = FALSE;
+
+ // Handler rufen
+ EndDrag();
+
+ // Drag-Werte zuruecksetzen
+ meDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+ mnDragSize = 0;
+ mbDragCanceled = FALSE;
+ mbDragDelete = FALSE;
+ mnDragModifier = 0;
+ mnDragScroll = 0;
+ mnStartDragPos = 0;
+
+ // Und neu ausgeben
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Ruler, ImplUpdateHdl, void*, EMPTYARG )
+{
+ mnUpdateEvtId = 0;
+
+ // Feststellen, was upgedatet werden muss
+ if ( mnUpdateFlags & RULER_UPDATE_DRAW )
+ {
+ mnUpdateFlags = 0;
+ ImplDraw();
+ }
+ else if ( mnUpdateFlags & RULER_UPDATE_LINES )
+ {
+ mnUpdateFlags = 0;
+ ImplInvertLines();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && !IsTracking() )
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT nMouseClicks = rMEvt.GetClicks();
+ USHORT nMouseModifier = rMEvt.GetModifier();
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( mbFormat )
+ {
+ ImplDraw();
+ mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ if ( maExtraRect.IsInside( aMousePos ) )
+ {
+ mnExtraClicks = nMouseClicks;
+ mnExtraModifier = nMouseModifier;
+ ExtraDown();
+ mnExtraClicks = 0;
+ mnExtraModifier = 0;
+ }
+ else
+ {
+ ImplRulerHitTest aHitTest;
+
+ if ( nMouseClicks == 1 )
+ {
+ if ( ImplHitTest( aMousePos, &aHitTest ) )
+ ImplStartDrag( &aHitTest, nMouseModifier );
+ else
+ {
+ // Position innerhalb des Lineal-Bereiches
+ if ( aHitTest.eType == RULER_TYPE_DONTKNOW )
+ {
+ mnDragPos = aHitTest.nPos;
+ Click();
+ mnDragPos = 0;
+
+ // Nocheinmal HitTest durchfuehren, da durch den Click
+ // zum Beispiel ein neuer Tab gesetzt werden konnte
+ if ( ImplHitTest( aMousePos, &aHitTest ) )
+ ImplStartDrag( &aHitTest, nMouseModifier );
+ }
+ }
+ }
+ else
+ {
+ if ( ImplHitTest( aMousePos, &aHitTest ) )
+ {
+ mnDragPos = aHitTest.nPos;
+ mnDragAryPos = aHitTest.nAryPos;
+ }
+ meDragType = aHitTest.eType;
+
+ DoubleClick();
+
+ meDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::MouseMove( const MouseEvent& rMEvt )
+{
+ PointerStyle ePtrStyle = POINTER_ARROW;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( mbFormat )
+ {
+ ImplDraw();
+ mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ ImplRulerHitTest aHitTest;
+ if ( ImplHitTest( rMEvt.GetPosPixel(), &aHitTest ) )
+ {
+ if ( aHitTest.bSize )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ ePtrStyle = POINTER_ESIZE;
+ else
+ ePtrStyle = POINTER_SSIZE;
+ }
+ else if ( aHitTest.bSizeBar )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ ePtrStyle = POINTER_HSIZEBAR;
+ else
+ ePtrStyle = POINTER_VSIZEBAR;
+ }
+ }
+
+ SetPointer( Pointer( ePtrStyle ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ // Bei Abbruch, den alten Status wieder herstellen
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ mbDragCanceled = TRUE;
+ mbFormat = TRUE;
+ }
+
+ ImplEndDrag();
+ }
+ else
+ ImplDrag( rTEvt.GetMouseEvent().GetPosPixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Paint( const Rectangle& )
+{
+ ImplDraw();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Extra-Field beruecksichtigen
+ if ( mnWinStyle & WB_EXTRAFIELD )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Top() ),
+ Point( maExtraRect.Right()-1, maExtraRect.Top() ) );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Top() ),
+ Point( maExtraRect.Left(), maExtraRect.Bottom()-1 ) );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Bottom()-1 ),
+ Point( maExtraRect.Right()-1, maExtraRect.Bottom()-1 ) );
+ DrawLine( Point( maExtraRect.Right()-1, maExtraRect.Top() ),
+ Point( maExtraRect.Right()-1, maExtraRect.Bottom()-1 ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( maExtraRect.Left()+1, maExtraRect.Top()+1 ),
+ Point( maExtraRect.Right()-2, maExtraRect.Top()+1 ) );
+ DrawLine( Point( maExtraRect.Left()+1, maExtraRect.Top()+1 ),
+ Point( maExtraRect.Left()+1, maExtraRect.Bottom()-2 ) );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Bottom() ),
+ Point( maExtraRect.Right(), maExtraRect.Bottom() ) );
+ DrawLine( Point( maExtraRect.Right(), maExtraRect.Top() ),
+ Point( maExtraRect.Right(), maExtraRect.Bottom() ) );
+ }
+ else
+ {
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ SetFillColor( rStyleSettings.GetWindowColor() );
+ DrawRect( maExtraRect );
+ }
+
+ // Imhalt vom Extrafeld ausgeben
+ ImplDrawExtra( TRUE );
+ }
+
+ if ( mnWinStyle & WB_BORDER )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( mnBorderOff, mnHeight-2 ),
+ Point( mnWidth, mnHeight-2 ) );
+ if ( mnBorderOff )
+ {
+ DrawLine( Point( mnBorderOff-1, mnHeight-2 ),
+ Point( mnBorderOff-1, mnHeight-1 ) );
+ }
+ }
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( Point( mnBorderOff, mnHeight-1 ),
+ Point( mnWidth, mnHeight-1 ) );
+ }
+ else
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( mnWidth-2, mnBorderOff ),
+ Point( mnWidth-2, mnHeight ) );
+ if ( mnBorderOff )
+ {
+ DrawLine( Point( mnWidth-2, mnBorderOff-1 ),
+ Point( mnWidth-1, mnBorderOff-1 ) );
+ }
+ }
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( Point( mnWidth-1, mnBorderOff ),
+ Point( mnWidth-1, mnHeight ) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Resize()
+{
+ Size aWinSize = GetOutputSizePixel();
+
+ long nNewHeight;
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( aWinSize.Height() != mnHeight )
+ nNewHeight = aWinSize.Height();
+ else
+ nNewHeight = 0;
+ }
+ else
+ {
+ if ( aWinSize.Width() != mnWidth )
+ nNewHeight = aWinSize.Width();
+ else
+ nNewHeight = 0;
+ }
+
+ // Hier schon Linien loeschen
+ BOOL bVisible = IsReallyVisible();
+ if ( bVisible && mpData->nLines )
+ {
+ ImplInvertLines();
+ mnUpdateFlags |= RULER_UPDATE_LINES;
+ if ( !mnUpdateEvtId )
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+ }
+ mbFormat = TRUE;
+
+ // Wenn sich die Hoehe bzw. Breite aendert, dann muessen besimmte Werte
+ // neu berechnet werden
+ //extra field should always be updated
+ ImplInitExtraField( mpData->bTextRTL );
+ if ( nNewHeight )
+ {
+ mbCalc = TRUE;
+ mnVirHeight = nNewHeight - mnBorderWidth - (RULER_OFF*2);
+ }
+ else
+ {
+ if ( mpData->bAutoPageWidth )
+ ImplUpdate( TRUE );
+ else if ( mbAutoWinWidth )
+ mbCalc = TRUE;
+ }
+
+ // Wenn Ruler eine Groesse hat, dann Groesse vom VirtualDevice setzen
+ if ( (mnVirWidth > RULER_MIN_SIZE) ||
+ ((aWinSize.Width() > RULER_MIN_SIZE) && (aWinSize.Height() > RULER_MIN_SIZE)) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ mnVirWidth = aWinSize.Width()-mnVirOff;
+ else
+ mnVirWidth = aWinSize.Height()-mnVirOff;
+ if ( mnVirWidth < RULER_MIN_SIZE )
+ mnVirWidth = 0;
+ }
+
+ // Gegebenenfalls ein Teil vom Rand loeschen, da 3D-Effekt/Trennlinie am
+ // Fensterrand
+ if ( bVisible )
+ {
+ if ( nNewHeight )
+ Invalidate();
+ else if ( mpData->bAutoPageWidth )
+ {
+ // Nur bei AutoPageWidth haben wir rechts einen 3D-Effekt,
+ // der sich der Fensterbreite anpasst und deshalb neu gezeichnet
+ // werden muss
+ Rectangle aRect;
+
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( mnWidth < aWinSize.Width() )
+ aRect.Left() = mnWidth-RULER_RESIZE_OFF;
+ else
+ aRect.Left() = aWinSize.Width()-RULER_RESIZE_OFF;
+ aRect.Right() = aRect.Left()+RULER_RESIZE_OFF;
+ aRect.Top() = RULER_OFF;
+ aRect.Bottom() = RULER_OFF+mnVirHeight;
+ }
+ else
+ {
+ if ( mnHeight < aWinSize.Height() )
+ aRect.Top() = mnHeight-RULER_RESIZE_OFF;
+ else
+ aRect.Top() = aWinSize.Height()-RULER_RESIZE_OFF;
+ aRect.Bottom() = aRect.Top()+RULER_RESIZE_OFF;
+ aRect.Left() = RULER_OFF;
+ aRect.Right() = RULER_OFF+mnVirHeight;
+ }
+
+ Invalidate( aRect );
+ }
+ }
+
+ // Neue Groesse merken
+ mnWidth = aWinSize.Width();
+ mnHeight = aWinSize.Height();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplFormat();
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDraw();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long Ruler::StartDrag()
+{
+ if ( maStartDragHdl.IsSet() )
+ return maStartDragHdl.Call( this );
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Drag()
+{
+ maDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::EndDrag()
+{
+ maEndDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Click()
+{
+ maClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ExtraDown()
+{
+ maExtraDownHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Activate()
+{
+ mbActive = TRUE;
+
+ // Positionslinien wieder anzeigen (erst hinter mbActive=TRUE rufen, da
+ // von ImplInvertLines() ausgewertet wird). Das Zeichnen der Linien
+ // wird verzoegert, damit im vermutlich noch nicht gepainteten Zustand
+ // Linien gezeichnet werden.
+ mnUpdateFlags |= RULER_UPDATE_LINES;
+ if ( !mnUpdateEvtId )
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Deactivate()
+{
+ // Positionslinien loeschen (schon vor mbActive=FALSE rufen, da
+ // von ImplInvertLines() ausgewertet wird)
+ ImplInvertLines();
+
+ mbActive = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::StartDocDrag( const MouseEvent& rMEvt, RulerType eDragType )
+{
+ if ( !mbDrag )
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT nMouseClicks = rMEvt.GetClicks();
+ USHORT nMouseModifier = rMEvt.GetModifier();
+ ImplRulerHitTest aHitTest;
+ if(eDragType != RULER_TYPE_DONTKNOW)
+ aHitTest.bExpandTest = TRUE;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( mbFormat )
+ {
+ ImplDraw();
+ mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ if ( nMouseClicks == 1 )
+ {
+ if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
+ {
+ Pointer aPtr;
+
+ if ( aHitTest.bSize )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPtr = Pointer( POINTER_ESIZE );
+ else
+ aPtr = Pointer( POINTER_SSIZE );
+ }
+ else if ( aHitTest.bSizeBar )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPtr = Pointer( POINTER_HSIZEBAR );
+ else
+ aPtr = Pointer( POINTER_VSIZEBAR );
+ }
+ SetPointer( aPtr );
+ return ImplStartDrag( &aHitTest, nMouseModifier );
+ }
+ }
+ else if ( nMouseClicks == 2 )
+ {
+ if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
+ {
+ mnDragPos = aHitTest.nPos;
+ mnDragAryPos = aHitTest.nAryPos;
+ }
+ eDragType = aHitTest.eType;
+
+ DoubleClick();
+
+ eDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+RulerType Ruler::GetDocType( const Point& rPos, RulerType eDragType,
+ USHORT* pAryPos ) const
+{
+ ImplRulerHitTest aHitTest;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( IsReallyVisible() && mbFormat )
+ {
+ ((Ruler*)this)->ImplDraw();
+ ((Ruler*)this)->mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ // HitTest durchfuehren
+ ImplDocHitTest( rPos, eDragType, &aHitTest );
+
+ // Werte zurueckgeben
+ if ( pAryPos )
+ *pAryPos = aHitTest.nAryPos;
+ return aHitTest.eType;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::CancelDrag()
+{
+ if ( mbDrag )
+ {
+ ImplDrag( Point( -1, -1 ) );
+ ImplEndDrag();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+RulerType Ruler::GetType( const Point& rPos, USHORT* pAryPos ) const
+{
+ ImplRulerHitTest aHitTest;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( IsReallyVisible() && mbFormat )
+ {
+ ((Ruler*)this)->ImplDraw();
+ ((Ruler*)this)->mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ // HitTest durchfuehren
+ ImplHitTest( rPos, &aHitTest );
+
+ // Werte zurueckgeben
+ if ( pAryPos )
+ *pAryPos = aHitTest.nAryPos;
+ return aHitTest.eType;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetWinPos( long nNewOff, long nNewWidth )
+{
+ // Gegebenenfalls werden die Breiten automatisch berechnet
+ if ( !nNewWidth )
+ mbAutoWinWidth = TRUE;
+ else
+ mbAutoWinWidth = FALSE;
+
+ // Werte setzen (werden in ImplFormat gegebenenfalls mitberechnet)
+ mnWinOff = nNewOff;
+ mnWinWidth = nNewWidth;
+ ImplUpdate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetPagePos( long nNewOff, long nNewWidth )
+{
+ // Muessen wir ueberhaupt was machen
+ if ( (mpData->nPageOff == nNewOff) && (mpData->nPageWidth == nNewWidth) )
+ return;
+
+ // Gegebenenfalls werden die Breiten automatisch berechnet
+ if ( !nNewWidth )
+ mpData->bAutoPageWidth = TRUE;
+ else
+ mpData->bAutoPageWidth = FALSE;
+
+ // Werte setzen (werden in ImplFormat gegebenenfalls mitberechnet)
+ mpData->nPageOff = nNewOff;
+ mpData->nPageWidth = nNewWidth;
+ ImplUpdate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetBorderPos( long nOff )
+{
+ if ( mnWinStyle & WB_BORDER )
+ {
+ if ( mnBorderOff != nOff )
+ {
+ mnBorderOff = nOff;
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetUnit( FieldUnit eNewUnit )
+{
+ if ( meUnit != eNewUnit )
+ {
+ meUnit = eNewUnit;
+ switch ( meUnit )
+ {
+ case FUNIT_MM:
+ mnUnitIndex = RULER_UNIT_MM;
+ break;
+ case FUNIT_CM:
+ mnUnitIndex = RULER_UNIT_CM;
+ break;
+ case FUNIT_M:
+ mnUnitIndex = RULER_UNIT_M;
+ break;
+ case FUNIT_KM:
+ mnUnitIndex = RULER_UNIT_KM;
+ break;
+ case FUNIT_INCH:
+ mnUnitIndex = RULER_UNIT_INCH;
+ break;
+ case FUNIT_FOOT:
+ mnUnitIndex = RULER_UNIT_FOOT;
+ break;
+ case FUNIT_MILE:
+ mnUnitIndex = RULER_UNIT_MILE;
+ break;
+ case FUNIT_POINT:
+ mnUnitIndex = RULER_UNIT_POINT;
+ break;
+ case FUNIT_PICA:
+ mnUnitIndex = RULER_UNIT_PICA;
+ break;
+ default:
+#ifdef DBG_UTIL
+ DBG_ERRORFILE( "Ruler::SetUnit() - Wrong Unit" );
+#endif
+ break;
+ }
+
+ maMapMode.SetMapUnit( aImplRulerUnitTab[mnUnitIndex].eMapUnit );
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetZoom( const Fraction& rNewZoom )
+{
+ DBG_ASSERT( rNewZoom.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
+
+ if ( maZoom != rNewZoom )
+ {
+ maZoom = rNewZoom;
+ maMapMode.SetScaleX( maZoom );
+ maMapMode.SetScaleY( maZoom );
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetExtraType( RulerExtra eNewExtraType, USHORT nStyle )
+{
+ if ( mnWinStyle & WB_EXTRAFIELD )
+ {
+ meExtraType = eNewExtraType;
+ mnExtraStyle = nStyle;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDrawExtra( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetNullOffset( long nPos )
+{
+ if ( mpData->nNullOff != nPos )
+ {
+ mpData->nNullOff = nPos;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetMargin1( long nPos, USHORT nMarginStyle )
+{
+ if ( (mpData->nMargin1 != nPos) || (mpData->nMargin1Style != nMarginStyle) )
+ {
+ mpData->nMargin1 = nPos;
+ mpData->nMargin1Style = nMarginStyle;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetMargin2( long nPos, USHORT nMarginStyle )
+{
+ DBG_ASSERT( (nPos >= mpData->nMargin1) ||
+ (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) ||
+ (mpData->nMargin2Style & RULER_STYLE_INVISIBLE),
+ "Ruler::SetMargin2() - Margin2 < Margin1" );
+
+ if ( (mpData->nMargin2 != nPos) || (mpData->nMargin2Style != nMarginStyle) )
+ {
+ mpData->nMargin2 = nPos;
+ mpData->nMargin2Style = nMarginStyle;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetLines( USHORT n, const RulerLine* pLineAry )
+{
+ // Testen, ob sich was geaendert hat
+ if ( mpData->nLines == n )
+ {
+ USHORT i = n;
+ const RulerLine* pAry1 = mpData->pLines;
+ const RulerLine* pAry2 = pLineAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ // Neue Werte setzen und neu ausgeben
+ BOOL bMustUpdate;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ bMustUpdate = TRUE;
+ else
+ bMustUpdate = FALSE;
+
+ // Alte Linien loeschen
+ if ( bMustUpdate )
+ ImplInvertLines();
+
+ // Neue Daten setzen
+ if ( !n || !pLineAry )
+ {
+ if ( !mpData->pLines )
+ return;
+ delete[] mpData->pLines;
+ mpData->nLines = 0;
+ mpData->pLines = NULL;
+ }
+ else
+ {
+ if ( mpData->nLines != n )
+ {
+ delete[] mpData->pLines;
+ mpData->nLines = n;
+ mpData->pLines = new RulerLine[n];
+ }
+
+ memcpy( mpData->pLines, pLineAry, n*sizeof( RulerLine ) );
+
+ // Linien neu ausgeben
+ if ( bMustUpdate )
+ ImplInvertLines();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetArrows( USHORT n, const RulerArrow* pArrowAry )
+{
+ if ( !n || !pArrowAry )
+ {
+ if ( !mpData->pArrows )
+ return;
+ delete[] mpData->pArrows;
+ mpData->nArrows = 0;
+ mpData->pArrows = NULL;
+ }
+ else
+ {
+ if ( mpData->nArrows != n )
+ {
+ delete[] mpData->pArrows;
+ mpData->nArrows = n;
+ mpData->pArrows = new RulerArrow[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerArrow* pAry1 = mpData->pArrows;
+ const RulerArrow* pAry2 = pArrowAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nWidth != pAry2->nWidth) ||
+ (pAry1->nLogWidth != pAry2->nLogWidth) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pArrows, pArrowAry, n*sizeof( RulerArrow ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetBorders( USHORT n, const RulerBorder* pBrdAry )
+{
+ if ( !n || !pBrdAry )
+ {
+ if ( !mpData->pBorders )
+ return;
+ delete[] mpData->pBorders;
+ mpData->nBorders = 0;
+ mpData->pBorders = NULL;
+ }
+ else
+ {
+ if ( mpData->nBorders != n )
+ {
+ delete[] mpData->pBorders;
+ mpData->nBorders = n;
+ mpData->pBorders = new RulerBorder[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerBorder* pAry1 = mpData->pBorders;
+ const RulerBorder* pAry2 = pBrdAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nWidth != pAry2->nWidth) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pBorders, pBrdAry, n*sizeof( RulerBorder ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetIndents( USHORT n, const RulerIndent* pIndentAry )
+{
+
+ if ( !n || !pIndentAry )
+ {
+ if ( !mpData->pIndents )
+ return;
+ delete[] mpData->pIndents;
+ mpData->nIndents = 0;
+ mpData->pIndents = NULL;
+ }
+ else
+ {
+ if ( mpData->nIndents != n )
+ {
+ delete[] mpData->pIndents;
+ mpData->nIndents = n;
+ mpData->pIndents = new RulerIndent[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerIndent* pAry1 = mpData->pIndents;
+ const RulerIndent* pAry2 = pIndentAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pIndents, pIndentAry, n*sizeof( RulerIndent ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetTabs( USHORT n, const RulerTab* pTabAry )
+{
+ if ( !n || !pTabAry )
+ {
+ if ( !mpData->pTabs )
+ return;
+ delete[] mpData->pTabs;
+ mpData->nTabs = 0;
+ mpData->pTabs = NULL;
+ }
+ else
+ {
+ if ( mpData->nTabs != n )
+ {
+ delete[] mpData->pTabs;
+ mpData->nTabs = n;
+ mpData->pTabs = new RulerTab[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerTab* pAry1 = mpData->pTabs;
+ const RulerTab* pAry2 = pTabAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pTabs, pTabAry, n*sizeof( RulerTab ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetStyle( WinBits nStyle )
+{
+ if ( mnWinStyle != nStyle )
+ {
+ mnWinStyle = nStyle;
+ ImplInitExtraField( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::DrawTab( OutputDevice* pDevice, const Point& rPos, USHORT nStyle )
+{
+ /*const StyleSettings& rStyleSettings =*/ pDevice->GetSettings().GetStyleSettings();
+ Point aPos( rPos );
+ USHORT nTabStyle = nStyle & (RULER_TAB_STYLE | RULER_TAB_RTL);
+
+ pDevice->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ pDevice->SetLineColor();
+ pDevice->SetFillColor( pDevice->GetSettings().GetStyleSettings().GetWindowTextColor() );
+ ImplCenterTabPos( aPos, nTabStyle );
+ ImplDrawRulerTab( pDevice, aPos, nTabStyle, nStyle );
+ pDevice->Pop();
+}
+/* -----------------16.10.2002 15:17-----------------
+ *
+ * --------------------------------------------------*/
+void Ruler::SetTextRTL(BOOL bRTL)
+{
+ if(mpData->bTextRTL != bRTL)
+ {
+ mpData->bTextRTL = bRTL;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplInitExtraField( TRUE );
+ }
+
+}
+long Ruler::GetPageOffset() const { return mpData->nPageOff; }
+long Ruler::GetPageWidth() const { return mpData->nPageWidth; }
+long Ruler::GetNullOffset() const { return mpData->nNullOff; }
+long Ruler::GetMargin1() const { return mpData->nMargin1; }
+USHORT Ruler::GetMargin1Style() const { return mpData->nMargin1Style; }
+long Ruler::GetMargin2() const { return mpData->nMargin2; }
+USHORT Ruler::GetMargin2Style() const { return mpData->nMargin2Style; }
+USHORT Ruler::GetLineCount() const { return mpData->nLines; }
+const RulerLine* Ruler::GetLines() const { return mpData->pLines; }
+USHORT Ruler::GetArrowCount() const { return mpData->nArrows; }
+const RulerArrow* Ruler::GetArrows() const { return mpData->pArrows; }
+USHORT Ruler::GetBorderCount() const { return mpData->nBorders; }
+const RulerBorder* Ruler::GetBorders() const { return mpData->pBorders; }
+USHORT Ruler::GetIndentCount() const { return mpData->nIndents; }
+const RulerIndent* Ruler::GetIndents() const { return mpData->pIndents; }
+
diff --git a/svtools/source/control/scriptedtext.cxx b/svtools/source/control/scriptedtext.cxx
new file mode 100644
index 000000000000..2067e6d245f0
--- /dev/null
+++ b/svtools/source/control/scriptedtext.cxx
@@ -0,0 +1,395 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "scriptedtext.hxx"
+
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+#include <rtl/ustring.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/font.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+
+//_____________________________________________________________________________
+
+class SvtScriptedTextHelper_Impl
+{
+private:
+ OutputDevice& mrOutDevice; /// The output device for drawing the text.
+ Font maLatinFont; /// The font for latin text portions.
+ Font maAsianFont; /// The font for asian text portions.
+ Font maCmplxFont; /// The font for complex text portions.
+ Font maDefltFont; /// The default font of the output device.
+ OUString maText; /// The text.
+
+ vector< sal_Int32 > maPosVec; /// The start position of each text portion.
+ vector< sal_Int16 > maScriptVec; /// The script type of each text portion.
+ vector< sal_Int32 > maWidthVec; /// The output width of each text portion.
+ Size maTextSize; /// The size the text will take in the current output device.
+
+ /** Assignment operator not implemented to prevent usage. */
+ SvtScriptedTextHelper_Impl& operator=( const SvtScriptedTextHelper_Impl& );
+
+ /** Gets the font of the given script type. */
+ const Font& GetFont( sal_uInt16 _nScript ) const;
+ /** Sets a font on the output device depending on the script type. */
+ inline void SetOutDevFont( sal_uInt16 _nScript )
+ { mrOutDevice.SetFont( GetFont( _nScript ) ); }
+ /** Fills maPosVec with positions of all changes of script type.
+ This method expects correctly initialized maPosVec and maScriptVec. */
+ void CalculateSizes();
+ /** Fills maPosVec with positions of all changes of script type and
+ maScriptVec with the script type of each portion. */
+ void CalculateBreaks(
+ const uno::Reference< i18n::XBreakIterator >& _xBreakIter );
+
+public:
+ /** This constructor sets an output device and fonts for all script types. */
+ SvtScriptedTextHelper_Impl(
+ OutputDevice& _rOutDevice,
+ Font* _pLatinFont,
+ Font* _pAsianFont,
+ Font* _pCmplxFont );
+ /** Copy constructor. */
+ SvtScriptedTextHelper_Impl(
+ const SvtScriptedTextHelper_Impl& _rCopy );
+ /** Destructor. */
+ ~SvtScriptedTextHelper_Impl();
+
+ /** Sets new fonts and recalculates the text width. */
+ void SetFonts( Font* _pLatinFont, Font* _pAsianFont, Font* _pCmplxFont );
+ /** Sets a new text and calculates all script breaks and the text width. */
+ void SetText(
+ const OUString& _rText,
+ const uno::Reference< i18n::XBreakIterator >& _xBreakIter );
+
+ /** Returns the previously set text. */
+ const OUString& GetText() const;
+ /** Returns a size struct containing the width and height of the text in the current output device. */
+ const Size& GetTextSize() const;
+
+ /** Draws the text in the current output device. */
+ void DrawText( const Point& _rPos );
+};
+
+
+SvtScriptedTextHelper_Impl::SvtScriptedTextHelper_Impl(
+ OutputDevice& _rOutDevice,
+ Font* _pLatinFont, Font* _pAsianFont, Font* _pCmplxFont ) :
+ mrOutDevice( _rOutDevice ),
+ maLatinFont( _pLatinFont ? *_pLatinFont : _rOutDevice.GetFont() ),
+ maAsianFont( _pAsianFont ? *_pAsianFont : _rOutDevice.GetFont() ),
+ maCmplxFont( _pCmplxFont ? *_pCmplxFont : _rOutDevice.GetFont() ),
+ maDefltFont( _rOutDevice.GetFont() )
+{
+}
+
+SvtScriptedTextHelper_Impl::SvtScriptedTextHelper_Impl( const SvtScriptedTextHelper_Impl& _rCopy ) :
+ mrOutDevice( _rCopy.mrOutDevice ),
+ maLatinFont( _rCopy.maLatinFont ),
+ maAsianFont( _rCopy.maAsianFont ),
+ maCmplxFont( _rCopy.maCmplxFont ),
+ maDefltFont( _rCopy.maDefltFont ),
+ maText( _rCopy.maText ),
+ maPosVec( _rCopy.maPosVec ),
+ maScriptVec( _rCopy.maScriptVec ),
+ maWidthVec( _rCopy.maWidthVec ),
+ maTextSize( _rCopy.maTextSize )
+{
+}
+
+SvtScriptedTextHelper_Impl::~SvtScriptedTextHelper_Impl()
+{
+}
+
+const Font& SvtScriptedTextHelper_Impl::GetFont( sal_uInt16 _nScript ) const
+{
+ switch( _nScript )
+ {
+ case i18n::ScriptType::LATIN: return maLatinFont;
+ case i18n::ScriptType::ASIAN: return maAsianFont;
+ case i18n::ScriptType::COMPLEX: return maCmplxFont;
+ }
+ return maDefltFont;
+}
+
+void SvtScriptedTextHelper_Impl::CalculateSizes()
+{
+ maTextSize.Width() = maTextSize.Height() = 0;
+ maDefltFont = mrOutDevice.GetFont();
+
+ // calculate text portion widths and total width
+ maWidthVec.clear();
+ if( !maPosVec.empty() )
+ {
+ DBG_ASSERT( maPosVec.size() - 1 == maScriptVec.size(),
+ "SvtScriptedTextHelper_Impl::CalculateWidth - invalid vectors" );
+
+ xub_StrLen nThisPos = static_cast< xub_StrLen >( maPosVec[ 0 ] );
+ xub_StrLen nNextPos;
+ sal_Int32 nPosVecSize = maPosVec.size();
+ sal_Int32 nPosVecIndex = 1;
+
+ sal_Int16 nScript;
+ sal_Int32 nScriptVecIndex = 0;
+
+ sal_Int32 nCurrWidth;
+
+ while( nPosVecIndex < nPosVecSize )
+ {
+ nNextPos = static_cast< xub_StrLen >( maPosVec[ nPosVecIndex++ ] );
+ nScript = maScriptVec[ nScriptVecIndex++ ];
+
+ SetOutDevFont( nScript );
+ nCurrWidth = mrOutDevice.GetTextWidth( maText, nThisPos, nNextPos - nThisPos );
+ maWidthVec.push_back( nCurrWidth );
+ maTextSize.Width() += nCurrWidth;
+ nThisPos = nNextPos;
+ }
+ }
+
+ // calculate maximum font height
+ SetOutDevFont( i18n::ScriptType::LATIN );
+ maTextSize.Height() = Max( maTextSize.Height(), mrOutDevice.GetTextHeight() );
+ SetOutDevFont( i18n::ScriptType::ASIAN );
+ maTextSize.Height() = Max( maTextSize.Height(), mrOutDevice.GetTextHeight() );
+ SetOutDevFont( i18n::ScriptType::COMPLEX );
+ maTextSize.Height() = Max( maTextSize.Height(), mrOutDevice.GetTextHeight() );
+
+ mrOutDevice.SetFont( maDefltFont );
+}
+
+void SvtScriptedTextHelper_Impl::CalculateBreaks( const uno::Reference< i18n::XBreakIterator >& _xBreakIter )
+{
+ maPosVec.clear();
+ maScriptVec.clear();
+
+ DBG_ASSERT( _xBreakIter.is(), "SvtScriptedTextHelper_Impl::CalculateBreaks - no break iterator" );
+
+ sal_Int32 nLen = maText.getLength();
+ if( nLen )
+ {
+ if( _xBreakIter.is() )
+ {
+ sal_Int32 nThisPos = 0; // first position of this portion
+ sal_Int32 nNextPos = 0; // first position of next portion
+ sal_Int16 nPortScript; // script type of this portion
+ do
+ {
+ nPortScript = _xBreakIter->getScriptType( maText, nThisPos );
+ nNextPos = _xBreakIter->endOfScript( maText, nThisPos, nPortScript );
+
+ switch( nPortScript )
+ {
+ case i18n::ScriptType::LATIN:
+ case i18n::ScriptType::ASIAN:
+ case i18n::ScriptType::COMPLEX:
+ maPosVec.push_back( nThisPos );
+ maScriptVec.push_back( nPortScript );
+ break;
+ default:
+ {
+/* *** handling of weak characters ***
+- first portion is weak: Use OutputDevice::HasGlyphs() to find the correct font
+- weak portion follows another portion: Script type of preceding portion is used */
+ if( maPosVec.empty() )
+ {
+ sal_Int32 nCharIx = 0;
+ sal_Int32 nNextCharIx = 0;
+ sal_Int16 nScript;
+ do
+ {
+ nScript = i18n::ScriptType::LATIN;
+ while( (nScript != i18n::ScriptType::WEAK) && (nCharIx == nNextCharIx) )
+ {
+ nNextCharIx = mrOutDevice.HasGlyphs( GetFont( nScript ), maText, sal::static_int_cast< USHORT >(nCharIx), sal::static_int_cast< USHORT >(nNextPos - nCharIx) );
+ if( nCharIx == nNextCharIx )
+ ++nScript;
+ }
+ if( nNextCharIx == nCharIx )
+ ++nNextCharIx;
+
+ maPosVec.push_back( nCharIx );
+ maScriptVec.push_back( nScript );
+ nCharIx = nNextCharIx;
+ }
+ while( nCharIx < nNextPos );
+ }
+ // nothing to do for following portions
+ }
+ }
+ nThisPos = nNextPos;
+ }
+ while( (0 <= nThisPos) && (nThisPos < nLen) );
+ }
+ else // no break iterator: whole text LATIN
+ {
+ maPosVec.push_back( 0 );
+ maScriptVec.push_back( i18n::ScriptType::LATIN );
+ }
+
+ // push end position of last portion
+ if( !maPosVec.empty() )
+ maPosVec.push_back( nLen );
+ }
+ CalculateSizes();
+}
+
+void SvtScriptedTextHelper_Impl::SetFonts( Font* _pLatinFont, Font* _pAsianFont, Font* _pCmplxFont )
+{
+ maLatinFont = _pLatinFont ? *_pLatinFont : maDefltFont;
+ maAsianFont = _pAsianFont ? *_pAsianFont : maDefltFont;
+ maCmplxFont = _pCmplxFont ? *_pCmplxFont : maDefltFont;
+ CalculateSizes();
+}
+
+void SvtScriptedTextHelper_Impl::SetText( const OUString& _rText, const uno::Reference< i18n::XBreakIterator >& _xBreakIter )
+{
+ maText = _rText;
+ CalculateBreaks( _xBreakIter );
+}
+
+const OUString& SvtScriptedTextHelper_Impl::GetText() const
+{
+ return maText;
+}
+
+const Size& SvtScriptedTextHelper_Impl::GetTextSize() const
+{
+ return maTextSize;
+}
+
+void SvtScriptedTextHelper_Impl::DrawText( const Point& _rPos )
+{
+ if( !maText.getLength() || maPosVec.empty() )
+ return;
+
+ DBG_ASSERT( maPosVec.size() - 1 == maScriptVec.size(), "SvtScriptedTextHelper_Impl::DrawText - invalid vectors" );
+ DBG_ASSERT( maScriptVec.size() == maWidthVec.size(), "SvtScriptedTextHelper_Impl::DrawText - invalid vectors" );
+
+ maDefltFont = mrOutDevice.GetFont();
+ Point aCurrPos( _rPos );
+ xub_StrLen nThisPos = static_cast< xub_StrLen >( maPosVec[ 0 ] );
+ xub_StrLen nNextPos;
+ sal_Int32 nPosVecSize = maPosVec.size();
+ sal_Int32 nPosVecIndex = 1;
+
+ sal_Int16 nScript;
+ sal_Int32 nVecIndex = 0;
+
+ while( nPosVecIndex < nPosVecSize )
+ {
+ nNextPos = static_cast< xub_StrLen >( maPosVec[ nPosVecIndex++ ] );
+ nScript = maScriptVec[ nVecIndex ];
+
+ SetOutDevFont( nScript );
+ mrOutDevice.DrawText( aCurrPos, maText, nThisPos, nNextPos - nThisPos );
+ aCurrPos.X() += maWidthVec[ nVecIndex++ ];
+ aCurrPos.X() += mrOutDevice.GetTextHeight() / 5; // add 20% of font height as portion spacing
+ nThisPos = nNextPos;
+ }
+ mrOutDevice.SetFont( maDefltFont );
+}
+
+
+//_____________________________________________________________________________
+
+SvtScriptedTextHelper::SvtScriptedTextHelper( OutputDevice& _rOutDevice ) :
+ mpImpl( new SvtScriptedTextHelper_Impl( _rOutDevice, NULL, NULL, NULL ) )
+{
+}
+
+SvtScriptedTextHelper::SvtScriptedTextHelper(
+ OutputDevice& _rOutDevice,
+ Font* _pLatinFont, Font* _pAsianFont, Font* _pCmplxFont ) :
+ mpImpl( new SvtScriptedTextHelper_Impl( _rOutDevice, _pLatinFont, _pAsianFont, _pCmplxFont ) )
+{
+}
+
+SvtScriptedTextHelper::SvtScriptedTextHelper( const SvtScriptedTextHelper& _rCopy ) :
+ mpImpl( new SvtScriptedTextHelper_Impl( *_rCopy.mpImpl ) )
+{
+}
+
+SvtScriptedTextHelper::~SvtScriptedTextHelper()
+{
+ delete mpImpl;
+}
+
+void SvtScriptedTextHelper::SetFonts( Font* _pLatinFont, Font* _pAsianFont, Font* _pCmplxFont )
+{
+ mpImpl->SetFonts( _pLatinFont, _pAsianFont, _pCmplxFont );
+}
+
+void SvtScriptedTextHelper::SetDefaultFont()
+{
+ mpImpl->SetFonts( NULL, NULL, NULL );
+}
+
+void SvtScriptedTextHelper::SetText( const OUString& _rText, const uno::Reference< i18n::XBreakIterator >& _xBreakIter )
+{
+ mpImpl->SetText( _rText, _xBreakIter );
+}
+
+const OUString& SvtScriptedTextHelper::GetText() const
+{
+ return mpImpl->GetText();
+}
+
+sal_Int32 SvtScriptedTextHelper::GetTextWidth() const
+{
+ return mpImpl->GetTextSize().Width();
+}
+
+sal_Int32 SvtScriptedTextHelper::GetTextHeight() const
+{
+ return mpImpl->GetTextSize().Height();
+}
+
+const Size& SvtScriptedTextHelper::GetTextSize() const
+{
+ return mpImpl->GetTextSize();
+}
+
+void SvtScriptedTextHelper::DrawText( const Point& _rPos )
+{
+ mpImpl->DrawText( _rPos );
+}
+
+
+//_____________________________________________________________________________
+
diff --git a/svtools/source/control/scrwin.cxx b/svtools/source/control/scrwin.cxx
new file mode 100644
index 000000000000..eb47d2c780ad
--- /dev/null
+++ b/svtools/source/control/scrwin.cxx
@@ -0,0 +1,572 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SVT_SCRWIN_CXX
+#include <scrwin.hxx>
+
+//===================================================================
+
+void ScrollableWindow::ImpInitialize( ScrollableWindowFlags nFlags )
+{
+ bHandleDragging = (BOOL) ( nFlags & SCRWIN_THUMBDRAGGING );
+ bVCenter = (nFlags & SCRWIN_VCENTER) == SCRWIN_VCENTER;
+ bHCenter = (nFlags & SCRWIN_HCENTER) == SCRWIN_HCENTER;
+ bScrolling = FALSE;
+
+ // set the handlers for the scrollbars
+ aVScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
+ aHScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
+ aVScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
+ aHScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
+
+ nColumnPixW = nLinePixH = GetSettings().GetStyleSettings().GetScrollBarSize();
+}
+
+//-------------------------------------------------------------------
+
+ScrollableWindow::ScrollableWindow( Window* pParent, WinBits nBits,
+ ScrollableWindowFlags nFlags ) :
+ Window( pParent, WinBits(nBits|WB_CLIPCHILDREN) ),
+ aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
+ aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
+ aCornerWin( this )
+{
+ ImpInitialize( nFlags );
+}
+
+//-------------------------------------------------------------------
+
+ScrollableWindow::ScrollableWindow( Window* pParent, const ResId& rId,
+ ScrollableWindowFlags nFlags ) :
+ Window( pParent, rId ),
+ aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
+ aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
+ aCornerWin( this )
+{
+ ImpInitialize( nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollableWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
+ {
+ ScrollBar* pHScrBar;
+ ScrollBar* pVScrBar;
+ if ( aHScroll.IsVisible() )
+ pHScrBar = &aHScroll;
+ else
+ pHScrBar = NULL;
+ if ( aVScroll.IsVisible() )
+ pVScrBar = &aVScroll;
+ else
+ pVScrBar = NULL;
+ if ( HandleScrollCommand( rCEvt, pHScrBar, pVScrBar ) )
+ return;
+ }
+
+ Window::Command( rCEvt );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ Resize();
+ Invalidate();
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
+//-------------------------------------------------------------------
+
+Size __EXPORT ScrollableWindow::GetOutputSizePixel() const
+{
+ Size aSz( Window::GetOutputSizePixel() );
+
+ long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aHScroll.IsVisible() )
+ aSz.Height() -= nTmp;
+ if ( aVScroll.IsVisible() )
+ aSz.Width() -= nTmp;
+ return aSz;
+}
+
+//-------------------------------------------------------------------
+
+Size ScrollableWindow::GetOutputSize() const
+{
+ return PixelToLogic( GetOutputSizePixel() );
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( ScrollableWindow, EndScrollHdl, ScrollBar *, pScroll )
+{
+ // notify the start of scrolling, if not already scrolling
+ if ( !bScrolling )
+ StartScroll(), bScrolling = TRUE;
+
+ // get the delta in logic coordinates
+ Size aDelta( PixelToLogic( Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
+
+ // scroll the window, if this is not already done
+ if ( !bHandleDragging )
+ {
+ if ( pScroll == &aHScroll )
+ Scroll( aDelta.Width(), 0 );
+ else
+ Scroll( 0, aDelta.Height() );
+ }
+
+ // notify the end of scrolling
+ bScrolling = FALSE;
+ EndScroll( aDelta.Width(), aDelta.Height() );
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( ScrollableWindow, ScrollHdl, ScrollBar *, pScroll )
+{
+ // notify the start of scrolling, if not already scrolling
+ if ( !bScrolling )
+ StartScroll(), bScrolling = TRUE;
+
+ if ( bHandleDragging )
+ {
+ // get the delta in logic coordinates
+ Size aDelta( PixelToLogic(
+ Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
+ if ( pScroll == &aHScroll )
+ Scroll( aDelta.Width(), 0 );
+ else
+ Scroll( 0, aDelta.Height() );
+ }
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::Resize()
+{
+ // get the new output-size in pixel
+ Size aOutPixSz = Window::GetOutputSizePixel();
+
+ // determine the size of the output-area and if we need scrollbars
+ const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ BOOL bVVisible = FALSE; // by default no vertical-ScrollBar
+ BOOL bHVisible = FALSE; // by default no horizontal-ScrollBar
+ BOOL bChanged; // determines if a visiblility was changed
+ do
+ {
+ bChanged = FALSE;
+
+ // does we need a vertical ScrollBar
+ if ( aOutPixSz.Width() < aTotPixSz.Width() && !bHVisible )
+ { bHVisible = TRUE;
+ aOutPixSz.Height() -= nScrSize;
+ bChanged = TRUE;
+ }
+
+ // does we need a horizontal ScrollBar
+ if ( aOutPixSz.Height() < aTotPixSz.Height() && !bVVisible )
+ { bVVisible = TRUE;
+ aOutPixSz.Width() -= nScrSize;
+ bChanged = TRUE;
+ }
+
+ }
+ while ( bChanged ); // until no visibility has changed
+
+ // store the old offset and map-mode
+ MapMode aMap( GetMapMode() );
+ Point aOldPixOffset( aPixOffset );
+
+ // justify (right/bottom borders should never exceed the virtual window)
+ Size aPixDelta;
+ if ( aPixOffset.X() < 0 &&
+ aPixOffset.X() + aTotPixSz.Width() < aOutPixSz.Width() )
+ aPixDelta.Width() =
+ aOutPixSz.Width() - ( aPixOffset.X() + aTotPixSz.Width() );
+ if ( aPixOffset.Y() < 0 &&
+ aPixOffset.Y() + aTotPixSz.Height() < aOutPixSz.Height() )
+ aPixDelta.Height() =
+ aOutPixSz.Height() - ( aPixOffset.Y() + aTotPixSz.Height() );
+ if ( aPixDelta.Width() || aPixDelta.Height() )
+ {
+ aPixOffset.X() += aPixDelta.Width();
+ aPixOffset.Y() += aPixDelta.Height();
+ }
+
+ // for axis without scrollbar restore the origin
+ if ( !bVVisible || !bHVisible )
+ {
+ aPixOffset = Point(
+ bHVisible
+ ? aPixOffset.X()
+ : ( bHCenter
+ ? (aOutPixSz.Width()-aTotPixSz.Width()) / 2
+ : 0 ),
+ bVVisible
+ ? aPixOffset.Y()
+ : ( bVCenter
+ ? (aOutPixSz.Height()-aTotPixSz.Height()) / 2
+ : 0 ) );
+ }
+ if ( bHVisible && !aHScroll.IsVisible() )
+ aPixOffset.X() = 0;
+ if ( bVVisible && !aVScroll.IsVisible() )
+ aPixOffset.Y() = 0;
+
+ // select the shifted map-mode
+ if ( aPixOffset != aOldPixOffset )
+ {
+ Window::SetMapMode( MapMode( MAP_PIXEL ) );
+ Window::Scroll(
+ aPixOffset.X() - aOldPixOffset.X(),
+ aPixOffset.Y() - aOldPixOffset.Y() );
+ SetMapMode( aMap );
+ }
+
+ // show or hide scrollbars
+ aVScroll.Show( bVVisible );
+ aHScroll.Show( bHVisible );
+
+ // disable painting in the corner between the scrollbars
+ if ( bVVisible && bHVisible )
+ {
+ aCornerWin.SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()),
+ Size(nScrSize, nScrSize) );
+ aCornerWin.Show();
+ }
+ else
+ aCornerWin.Hide();
+
+ // resize scrollbars and set their ranges
+ if ( bHVisible )
+ {
+ aHScroll.SetPosSizePixel(
+ Point( 0, aOutPixSz.Height() ),
+ Size( aOutPixSz.Width(), nScrSize ) );
+ aHScroll.SetRange( Range( 0, aTotPixSz.Width() ) );
+ aHScroll.SetPageSize( aOutPixSz.Width() );
+ aHScroll.SetVisibleSize( aOutPixSz.Width() );
+ aHScroll.SetLineSize( nColumnPixW );
+ aHScroll.SetThumbPos( -aPixOffset.X() );
+ }
+ if ( bVVisible )
+ {
+ aVScroll.SetPosSizePixel(
+ Point( aOutPixSz.Width(), 0 ),
+ Size( nScrSize,aOutPixSz.Height() ) );
+ aVScroll.SetRange( Range( 0, aTotPixSz.Height() ) );
+ aVScroll.SetPageSize( aOutPixSz.Height() );
+ aVScroll.SetVisibleSize( aOutPixSz.Height() );
+ aVScroll.SetLineSize( nLinePixH );
+ aVScroll.SetThumbPos( -aPixOffset.Y() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::StartScroll()
+{
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::EndScroll( long, long )
+{
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetMapMode( const MapMode& rNewMapMode )
+{
+ MapMode aMap( rNewMapMode );
+ aMap.SetOrigin( aMap.GetOrigin() + PixelToLogic( aPixOffset, aMap ) );
+ Window::SetMapMode( aMap );
+}
+
+//-------------------------------------------------------------------
+
+MapMode ScrollableWindow::GetMapMode() const
+{
+ MapMode aMap( Window::GetMapMode() );
+ aMap.SetOrigin( aMap.GetOrigin() - PixelToLogic( aPixOffset ) );
+ return aMap;
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetTotalSize( const Size& rNewSize )
+{
+ aTotPixSz = LogicToPixel( rNewSize );
+ ScrollableWindow::Resize();
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetVisibleSize( const Size& rNewSize )
+{
+ // get the rectangle, we wish to view
+ Rectangle aWish( Point(0, 0), LogicToPixel(rNewSize) );
+
+ // get maximum rectangle for us from our parent-window (subst our border!)
+ Rectangle aMax( Point(0, 0), GetParent()->GetOutputSizePixel() );
+ aMax.Left() -= ( Window::GetSizePixel().Width() -
+ Window::GetOutputSizePixel().Width() );
+ aMax.Bottom() -= (Window::GetSizePixel().Height() -
+ Window::GetOutputSizePixel().Height());
+
+ Size aWill( aWish.GetIntersection(aMax).GetSize() );
+ BOOL bHScroll = FALSE;
+ const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aWill.Width() < aWish.GetSize().Width() )
+ { bHScroll = TRUE;
+ aWill.Height() =
+ Min( aWill.Height()+nScrSize, aMax.GetSize().Height() );
+ }
+ if ( aWill.Height() < aWish.GetSize().Height() )
+ aWill.Width() =
+ Min( aWill.Width()+nScrSize, aMax.GetSize().Width() );
+ if ( !bHScroll && (aWill.Width() < aWish.GetSize().Width()) )
+ aWill.Height() =
+ Min( aWill.Height()+nScrSize, aMax.GetSize().Height() );
+ Window::SetOutputSizePixel( aWill );
+}
+
+//-------------------------------------------------------------------
+
+BOOL ScrollableWindow::MakeVisible( const Rectangle& rTarget, BOOL bSloppy )
+{
+ Rectangle aTarget;
+ Rectangle aTotRect( Point(0, 0), PixelToLogic( aTotPixSz ) );
+
+ if ( bSloppy )
+ {
+ aTarget = rTarget;
+
+ // at maximum to right border
+ if ( aTarget.Right() > aTotRect.Right() )
+ {
+ long nDelta = aTarget.Right() - aTotRect.Right();
+ aTarget.Left() -= nDelta;
+ aTarget.Right() -= nDelta;
+
+ // too wide?
+ if ( aTarget.Left() < aTotRect.Left() )
+ aTarget.Left() = aTotRect.Left();
+ }
+
+ // at maximum to bottom border
+ if ( aTarget.Bottom() > aTotRect.Bottom() )
+ {
+ long nDelta = aTarget.Bottom() - aTotRect.Bottom();
+ aTarget.Top() -= nDelta;
+ aTarget.Bottom() -= nDelta;
+
+ // too high?
+ if ( aTarget.Top() < aTotRect.Top() )
+ aTarget.Top() = aTotRect.Top();
+ }
+
+ // at maximum to left border
+ if ( aTarget.Left() < aTotRect.Left() )
+ {
+ long nDelta = aTarget.Left() - aTotRect.Left();
+ aTarget.Right() -= nDelta;
+ aTarget.Left() -= nDelta;
+
+ // too wide?
+ if ( aTarget.Right() > aTotRect.Right() )
+ aTarget.Right() = aTotRect.Right();
+ }
+
+ // at maximum to top border
+ if ( aTarget.Top() < aTotRect.Top() )
+ {
+ long nDelta = aTarget.Top() - aTotRect.Top();
+ aTarget.Bottom() -= nDelta;
+ aTarget.Top() -= nDelta;
+
+ // too high?
+ if ( aTarget.Bottom() > aTotRect.Bottom() )
+ aTarget.Bottom() = aTotRect.Bottom();
+ }
+ }
+ else
+ aTarget = rTarget.GetIntersection( aTotRect );
+
+ // is the area already visible?
+ Rectangle aVisArea( GetVisibleArea() );
+ if ( aVisArea.IsInside(rTarget) )
+ return TRUE;
+
+ // is there somewhat to scroll?
+ if ( aVisArea.TopLeft() != aTarget.TopLeft() )
+ {
+ Rectangle aBox( aTarget.GetUnion(aVisArea) );
+ long nDeltaX = ( aBox.Right() - aVisArea.Right() ) +
+ ( aBox.Left() - aVisArea.Left() );
+ long nDeltaY = ( aBox.Top() - aVisArea.Top() ) +
+ ( aBox.Bottom() - aVisArea.Bottom() );
+ Scroll( nDeltaX, nDeltaY );
+ }
+
+ // determine if the target is completely visible
+ return aVisArea.GetWidth() >= aTarget.GetWidth() &&
+ aVisArea.GetHeight() >= aTarget.GetHeight();
+}
+
+//-------------------------------------------------------------------
+
+Rectangle ScrollableWindow::GetVisibleArea() const
+{
+ Point aTopLeft( PixelToLogic( Point() ) );
+ Size aSz( GetOutputSize() );
+ return Rectangle( aTopLeft, aSz );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetLineSize( ULONG nHorz, ULONG nVert )
+{
+ Size aPixSz( LogicToPixel( Size(nHorz, nVert) ) );
+ nColumnPixW = aPixSz.Width();
+ nLinePixH = aPixSz.Height();
+ aVScroll.SetLineSize( nLinePixH );
+ aHScroll.SetLineSize( nColumnPixW );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::Scroll( long nDeltaX, long nDeltaY, USHORT )
+{
+ if ( !bScrolling )
+ StartScroll();
+
+ // get the delta in pixel
+ Size aDeltaPix( LogicToPixel( Size(nDeltaX, nDeltaY) ) );
+ Size aOutPixSz( GetOutputSizePixel() );
+ MapMode aMap( GetMapMode() );
+ Point aNewPixOffset( aPixOffset );
+
+ // scrolling horizontally?
+ if ( nDeltaX != 0 )
+ {
+ aNewPixOffset.X() -= aDeltaPix.Width();
+ if ( ( aOutPixSz.Width() - aNewPixOffset.X() ) > aTotPixSz.Width() )
+ aNewPixOffset.X() = - ( aTotPixSz.Width() - aOutPixSz.Width() );
+ else if ( aNewPixOffset.X() > 0 )
+ aNewPixOffset.X() = 0;
+ }
+
+ // scrolling vertically?
+ if ( nDeltaY != 0 )
+ {
+ aNewPixOffset.Y() -= aDeltaPix.Height();
+ if ( ( aOutPixSz.Height() - aNewPixOffset.Y() ) > aTotPixSz.Height() )
+ aNewPixOffset.Y() = - ( aTotPixSz.Height() - aOutPixSz.Height() );
+ else if ( aNewPixOffset.Y() > 0 )
+ aNewPixOffset.Y() = 0;
+ }
+
+ // recompute the logical scroll units
+ aDeltaPix.Width() = aPixOffset.X() - aNewPixOffset.X();
+ aDeltaPix.Height() = aPixOffset.Y() - aNewPixOffset.Y();
+ Size aDelta( PixelToLogic(aDeltaPix) );
+ nDeltaX = aDelta.Width();
+ nDeltaY = aDelta.Height();
+ aPixOffset = aNewPixOffset;
+
+ // scrolling?
+ if ( nDeltaX != 0 || nDeltaY != 0 )
+ {
+ Update();
+
+ // does the new area overlap the old one?
+ if ( Abs( (int)aDeltaPix.Height() ) < aOutPixSz.Height() ||
+ Abs( (int)aDeltaPix.Width() ) < aOutPixSz.Width() )
+ {
+ // scroll the overlapping area
+ SetMapMode( aMap );
+
+ // never scroll the scrollbars itself!
+ Window::Scroll(-nDeltaX, -nDeltaY,
+ PixelToLogic( Rectangle( Point(0, 0), aOutPixSz ) ) );
+ }
+ else
+ {
+ // repaint all
+ SetMapMode( aMap );
+ Invalidate();
+ }
+
+ Update();
+ }
+
+ if ( !bScrolling )
+ {
+ EndScroll( nDeltaX, nDeltaY );
+ if ( nDeltaX )
+ aHScroll.SetThumbPos( -aPixOffset.X() );
+ if ( nDeltaY )
+ aVScroll.SetThumbPos( -aPixOffset.Y() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::ScrollLines( long nLinesX, long nLinesY )
+{
+ Size aDelta( PixelToLogic( Size( nColumnPixW, nLinePixH ) ) );
+ Scroll( aDelta.Width()*nLinesX, aDelta.Height()*nLinesY );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::ScrollPages( long nPagesX, ULONG nOverlapX,
+ long nPagesY, ULONG nOverlapY )
+{
+ Size aOutSz( GetVisibleArea().GetSize() );
+ Scroll( nPagesX * aOutSz.Width() + (nPagesX>0 ? 1 : -1) * nOverlapX,
+ nPagesY * aOutSz.Height() + (nPagesY>0 ? 1 : -1) * nOverlapY );
+}
+
+
diff --git a/svtools/source/control/stdctrl.cxx b/svtools/source/control/stdctrl.cxx
new file mode 100644
index 000000000000..14c8cade3092
--- /dev/null
+++ b/svtools/source/control/stdctrl.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/stdctrl.hxx>
+
+// =======================================================================
+
+FixedInfo::FixedInfo( Window* pParent, WinBits nWinStyle ) :
+ FixedText( pParent, nWinStyle | WB_INFO )
+{
+}
+
+// -----------------------------------------------------------------------
+
+FixedInfo::FixedInfo( Window* pParent, const ResId& rResId ) :
+ FixedText( pParent, rResId )
+{
+ SetStyle( GetStyle() | WB_INFO );
+}
+
+namespace svt
+{
+ // class svt::SelectableFixedText ----------------------------------------
+
+ SelectableFixedText::SelectableFixedText( Window* pParent, WinBits nWinStyle ) :
+ Edit( pParent, nWinStyle )
+ {
+ Init();
+ }
+
+ // -----------------------------------------------------------------------
+
+ SelectableFixedText::SelectableFixedText( Window* pParent, const ResId& rResId ) :
+ Edit( pParent, rResId )
+ {
+ Init();
+ }
+
+ // -----------------------------------------------------------------------
+
+ SelectableFixedText::~SelectableFixedText()
+ {
+ }
+
+ // -----------------------------------------------------------------------
+
+ void SelectableFixedText::Init()
+ {
+ // no border
+ SetBorderStyle( WINDOW_BORDER_NOBORDER );
+ // read-only
+ SetReadOnly();
+ // make it transparent
+ SetControlBackground();
+ SetBackground();
+ SetPaintTransparent( TRUE );
+ }
+
+ // -----------------------------------------------------------------------
+
+ void SelectableFixedText::LoseFocus()
+ {
+ Edit::LoseFocus();
+ // clear cursor
+ Invalidate();
+ }
+
+} // namespace svt
+
diff --git a/svtools/source/control/stdmenu.cxx b/svtools/source/control/stdmenu.cxx
new file mode 100644
index 000000000000..95b6d3fbd5c6
--- /dev/null
+++ b/svtools/source/control/stdmenu.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <string.h>
+
+#ifndef _APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+
+#include <vcl/i18nhelp.hxx>
+
+#include <ctrltool.hxx>
+#include <stdmenu.hxx>
+
+// ========================================================================
+
+FontNameMenu::FontNameMenu()
+{
+ SetMenuFlags( GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+}
+
+// -----------------------------------------------------------------------
+
+FontNameMenu::~FontNameMenu()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::Select()
+{
+ maCurName = GetItemText( GetCurItemId() );
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::Highlight()
+{
+ XubString aTempName = maCurName;
+ maCurName = GetItemText( GetCurItemId() );
+ maHighlightHdl.Call( this );
+ maCurName = aTempName;
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::Fill( const FontList* pList )
+{
+ // clear menu
+ Clear();
+
+ // add fonts
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+ // more than 100 fonts reduces the speed of opening the menu.
+ // So only the first 100 fonts will be displayed.
+ USHORT nFontCount = ::std::min( pList->GetFontNameCount(), static_cast< USHORT >(100) );
+ for ( USHORT i = 0; i < nFontCount; i++ )
+ {
+ const XubString& rName = pList->GetFontName( i ).GetName();
+
+ // sort with the I18nHelper
+ USHORT j = GetItemCount();
+ while ( j )
+ {
+ XubString aText = GetItemText( GetItemId( j-1 ) );
+ if ( rI18nHelper.CompareString( rName, aText ) > 0 )
+ break;
+ j--;
+ }
+ InsertItem( i+1, rName, MIB_RADIOCHECK | MIB_AUTOCHECK, j );
+ }
+
+ SetCurName( maCurName );
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::SetCurName( const XubString& rName )
+{
+ maCurName = rName;
+
+ // Menueintrag checken
+ USHORT nChecked = 0;
+ USHORT nItemCount = GetItemCount();
+ for( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = GetItemId( i );
+
+ if ( IsItemChecked( nItemId ) )
+ nChecked = nItemId;
+
+ XubString aText = GetItemText( nItemId );
+ if ( aText == maCurName )
+ {
+ CheckItem( nItemId, TRUE );
+ return;
+ }
+ }
+
+ if ( nChecked )
+ CheckItem( nChecked, FALSE );
+}
+
+// ========================================================================
+
+FontStyleMenu::FontStyleMenu()
+{
+ SetMenuFlags( GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+}
+
+// -----------------------------------------------------------------------
+
+FontStyleMenu::~FontStyleMenu()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::Select()
+{
+ USHORT nCurId = GetCurItemId();
+
+ if ( (nCurId >= FONTSTYLEMENU_FIRSTID) && (nCurId <= FONTSTYLEMENU_LASTID) )
+ {
+ maCurStyle = GetItemText( nCurId );
+ maSelectHdl.Call( this );
+ }
+ else
+ PopupMenu::Select();
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::Highlight()
+{
+ USHORT nCurId = GetCurItemId();
+
+ if ( (nCurId >= FONTSTYLEMENU_FIRSTID) && (nCurId <= FONTSTYLEMENU_LASTID) )
+ {
+ XubString aTempName = maCurStyle;
+ maCurStyle = GetItemText( nCurId );
+ maHighlightHdl.Call( this );
+ maCurStyle = aTempName;
+ }
+ else
+ PopupMenu::Highlight();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontStyleMenu::ImplIsAlreadyInserted( const XubString& rStyleName, USHORT nCount )
+{
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ if ( GetItemText( i+FONTSTYLEMENU_FIRSTID ) == rStyleName )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::Fill( const XubString& rName, const FontList* pList )
+{
+ USHORT nItemId = GetItemId( 0 );
+ while ( (nItemId >= FONTSTYLEMENU_FIRSTID) &&
+ (nItemId <= FONTSTYLEMENU_LASTID) )
+ {
+ RemoveItem( 0 );
+ nItemId = GetItemId( 0 );
+ }
+
+ // Existiert ein Font mit diesem Namen
+ sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
+ if ( hFontInfo )
+ {
+ XubString aStyleText;
+ USHORT nPos = 0;
+ USHORT nId = FONTSTYLEMENU_FIRSTID;
+ FontWeight eLastWeight = WEIGHT_DONTKNOW;
+ FontItalic eLastItalic = ITALIC_NONE;
+ FontWidth eLastWidth = WIDTH_DONTKNOW;
+ BOOL bNormal = FALSE;
+ BOOL bItalic = FALSE;
+ BOOL bBold = FALSE;
+ BOOL bBoldItalic = FALSE;
+ BOOL bInsert = FALSE;
+ FontInfo aInfo;
+ while ( hFontInfo )
+ {
+ aInfo = pList->GetFontInfo( hFontInfo );
+
+ FontWeight eWeight = aInfo.GetWeight();
+ FontItalic eItalic = aInfo.GetItalic();
+ FontWidth eWidth = aInfo.GetWidthType();
+ // Only if the attributes are different, we insert the
+ // Font to avoid double Entries in different languages
+ if ( (eWeight != eLastWeight) || (eItalic != eLastItalic) ||
+ (eWidth != eLastWidth) )
+ {
+ if ( bInsert )
+ {
+ InsertItem( nId, aStyleText,
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+
+ if ( eWeight <= WEIGHT_NORMAL )
+ {
+ if ( eItalic != ITALIC_NONE )
+ bItalic = TRUE;
+ else
+ bNormal = TRUE;
+ }
+ else
+ {
+ if ( eItalic != ITALIC_NONE )
+ bBoldItalic = TRUE;
+ else
+ bBold = TRUE;
+ }
+
+ // For wrong StyleNames we replace this with the correct once
+ aStyleText = pList->GetStyleName( aInfo );
+ bInsert = !ImplIsAlreadyInserted( aStyleText, nPos );
+ if ( !bInsert )
+ {
+ aStyleText = pList->GetStyleName( eWeight, eItalic );
+ bInsert = !ImplIsAlreadyInserted( aStyleText, nPos );
+ }
+
+ eLastWeight = eWeight;
+ eLastItalic = eItalic;
+ eLastWidth = eWidth;
+ }
+ else
+ {
+ if ( bInsert )
+ {
+ // If we have two names for the same attributes
+ // we prefer the translated standard names
+ const XubString& rAttrStyleText = pList->GetStyleName( eWeight, eItalic );
+ if ( rAttrStyleText != aStyleText )
+ {
+ XubString aTempStyleText = pList->GetStyleName( aInfo );
+ if ( rAttrStyleText == aTempStyleText )
+ aStyleText = rAttrStyleText;
+ bInsert = !ImplIsAlreadyInserted( aStyleText, nPos );
+ }
+ }
+ }
+
+ if ( !bItalic && (aStyleText == pList->GetItalicStr()) )
+ bItalic = TRUE;
+ else if ( !bBold && (aStyleText == pList->GetBoldStr()) )
+ bBold = TRUE;
+ else if ( !bBoldItalic && (aStyleText == pList->GetBoldItalicStr()) )
+ bBoldItalic = TRUE;
+
+ hFontInfo = pList->GetNextFontInfo( hFontInfo );
+ }
+
+ if ( bInsert )
+ {
+ InsertItem( nId, aStyleText,
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+
+ // Bestimmte Styles als Nachbildung
+ if ( bNormal )
+ {
+ if ( !bItalic )
+ {
+ InsertItem( nId, pList->GetItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+ if ( !bBold )
+ {
+ InsertItem( nId, pList->GetBoldStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+ }
+ if ( !bBoldItalic )
+ {
+ if ( bNormal || bItalic || bBold )
+ {
+ InsertItem( nId, pList->GetBoldItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+ }
+ }
+ else
+ {
+ // Wenn Font nicht, dann Standard-Styles einfuegen
+ InsertItem( FONTSTYLEMENU_FIRSTID, pList->GetNormalStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ InsertItem( FONTSTYLEMENU_FIRSTID+1, pList->GetItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ InsertItem( FONTSTYLEMENU_FIRSTID+2, pList->GetBoldStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ InsertItem( FONTSTYLEMENU_FIRSTID+3, pList->GetBoldItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ }
+
+ SetCurStyle( maCurStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::SetCurStyle( const XubString& rStyle )
+{
+ maCurStyle = rStyle;
+
+ // Menueintrag checken
+ USHORT nChecked = 0;
+ USHORT nItemCount = GetItemCount();
+ for( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = GetItemId( i );
+
+ if ( (nItemId < FONTSTYLEMENU_FIRSTID) ||
+ (nItemId > FONTSTYLEMENU_LASTID) )
+ break;
+
+ if ( IsItemChecked( nItemId ) )
+ nChecked = nItemId;
+
+ XubString aText = GetItemText( nItemId );
+ if ( aText == maCurStyle )
+ {
+ CheckItem( nItemId, TRUE );
+ return;
+ }
+ }
+
+ if ( nChecked )
+ CheckItem( nChecked, FALSE );
+}
+
+// ========================================================================
+
+FontSizeMenu::FontSizeMenu()
+: mpHeightAry( NULL )
+, mnCurHeight( 100 )
+{
+ SetMenuFlags( GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+}
+
+// -----------------------------------------------------------------------
+
+FontSizeMenu::~FontSizeMenu()
+{
+ if ( mpHeightAry )
+ delete[] mpHeightAry;
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::Select()
+{
+ const USHORT nCurItemId = GetCurItemId();
+ mnCurHeight = mpHeightAry[ nCurItemId - 1 ];
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::Highlight()
+{
+ const long nTempHeight = mnCurHeight;
+ const USHORT nCurItemId = GetCurItemId();
+ if ( !nCurItemId )
+ mnCurHeight = 0;
+ else
+ {
+ //sal_Int32 nValue = GetItemText( nCurItemId ).ToInt32();
+ mnCurHeight = mpHeightAry[ nCurItemId - 1 ];
+ }
+ maHighlightHdl.Call( this );
+ mnCurHeight = nTempHeight;
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::Fill( const FontInfo& rInfo, const FontList* pList )
+{
+ Clear();
+
+ // setup font size array
+ if ( mpHeightAry )
+ delete[] mpHeightAry;
+
+ const long* pTempAry;
+ const long* pAry = pList->GetSizeAry( rInfo );
+ USHORT nSizeCount = 0;
+ while ( pAry[nSizeCount] )
+ nSizeCount++;
+
+ USHORT nPos = 0;
+
+ // first insert font size names (for simplified/traditional chinese)
+ FontSizeNames aFontSizeNames( Application::GetSettings().GetUILanguage() );
+ mpHeightAry = new long[nSizeCount+aFontSizeNames.Count()];
+ if ( !aFontSizeNames.IsEmpty() )
+ {
+ if ( pAry == pList->GetStdSizeAry() )
+ {
+ // for scalable fonts all font size names
+ ULONG nCount = aFontSizeNames.Count();
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ String aSizeName = aFontSizeNames.GetIndexName( i );
+ long nSize = aFontSizeNames.GetIndexSize( i );
+ mpHeightAry[nPos] = nSize;
+ nPos++; // Id is nPos+1
+ InsertItem( nPos, aSizeName, MIB_RADIOCHECK | MIB_AUTOCHECK );
+ }
+ }
+ else
+ {
+ // for fixed size fonts only selectable font size names
+ pTempAry = pAry;
+ while ( *pTempAry )
+ {
+ String aSizeName = aFontSizeNames.Size2Name( *pTempAry );
+ if ( aSizeName.Len() )
+ {
+ mpHeightAry[nPos] = *pTempAry;
+ nPos++; // Id is nPos+1
+ InsertItem( nPos, aSizeName, MIB_RADIOCHECK | MIB_AUTOCHECK );
+ }
+ pTempAry++;
+ }
+ }
+ }
+
+ // then insert numerical font size values
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+ pTempAry = pAry;
+ while ( *pTempAry )
+ {
+ mpHeightAry[nPos] = *pTempAry;
+ nPos++; // Id is nPos+1
+ InsertItem( nPos, rI18nHelper.GetNum( *pTempAry, 1, TRUE, FALSE ), MIB_RADIOCHECK | MIB_AUTOCHECK );
+ pTempAry++;
+ }
+
+ SetCurHeight( mnCurHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::SetCurHeight( long nHeight )
+{
+ mnCurHeight = nHeight;
+
+ // check menue item
+ XubString aHeight = Application::GetSettings().GetUILocaleI18nHelper().GetNum( nHeight, 1, TRUE, FALSE );
+ USHORT nChecked = 0;
+ USHORT nItemCount = GetItemCount();
+ for( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = GetItemId( i );
+
+ if ( mpHeightAry[i] == nHeight )
+ {
+ CheckItem( nItemId, TRUE );
+ return;
+ }
+
+ if ( IsItemChecked( nItemId ) )
+ nChecked = nItemId;
+ }
+
+ if ( nChecked )
+ CheckItem( nChecked, FALSE );
+}
diff --git a/svtools/source/control/svxbox.cxx b/svtools/source/control/svxbox.cxx
new file mode 100644
index 000000000000..d1ea47d110cd
--- /dev/null
+++ b/svtools/source/control/svxbox.cxx
@@ -0,0 +1,617 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/svxbox.hxx>
+#include <unotools/charclass.hxx>
+
+// -----------------------------------------------------------------------
+
+SV_IMPL_PTRARR(SvxEntryLst, SvxBoxEntry*)
+
+/*--------------------------------------------------------------------
+ Beschreibung: Ein ListboxElement
+ --------------------------------------------------------------------*/
+
+SvxBoxEntry::SvxBoxEntry() :
+ nId(LISTBOX_ENTRY_NOTFOUND),
+ bModified(FALSE),
+ bNew(FALSE)
+{
+}
+
+
+SvxBoxEntry::SvxBoxEntry(const String& aNam, USHORT nIdx) :
+ aName(aNam),
+ nId(nIdx),
+ bModified(FALSE),
+ bNew(FALSE)
+{
+}
+
+
+SvxBoxEntry::SvxBoxEntry(const SvxBoxEntry& rOld) :
+ aName(rOld.aName),
+ nId(rOld.nId),
+ bModified(rOld.bModified),
+ bNew(rOld.bNew)
+{
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung:
+ --------------------------------------------------------------------*/
+
+SvxListBox::SvxListBox(Window* pParent, WinBits nBits) :
+ ListBox(pParent, nBits)
+{
+ InitListBox();
+}
+
+
+SvxListBox::SvxListBox(Window* pParent, const ResId& rId):
+ ListBox(pParent, rId)
+{
+ InitListBox();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Basisklasse Dtor
+ --------------------------------------------------------------------*/
+
+__EXPORT SvxListBox::~SvxListBox()
+{
+ aEntryLst.DeleteAndDestroy(0, aEntryLst.Count());
+ aDelEntryLst.DeleteAndDestroy(0, aDelEntryLst.Count());
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Evtl. Liste aus der Ressource beachten
+ --------------------------------------------------------------------*/
+
+void SvxListBox::InitListBox()
+{
+ // Verwaltung fuer die Stringlist aus der Resource aufbauen
+ USHORT nSize = GetEntryCount();
+ for(USHORT i=0; i < nSize; ++i)
+ { const SvxBoxEntry* pTmp = new SvxBoxEntry(ListBox::GetEntry(i), i);
+ const SvxBoxEntry* &rpTmp = pTmp;
+ aEntryLst.Insert(rpTmp, aEntryLst.Count());
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: neue Eintraege verwalten
+ --------------------------------------------------------------------*/
+
+void SvxListBox::InsertNewEntry(const SvxBoxEntry& rEntry)
+{
+ SvxBoxEntry* pNew = new SvxBoxEntry(rEntry);
+ pNew->bNew = TRUE;
+ InsertSorted(pNew);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Eintrag in die ListBox aufnehmen
+ --------------------------------------------------------------------*/
+
+void SvxListBox::InsertEntry(const SvxBoxEntry& rEntry, USHORT nPos)
+{
+ if(nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ SvxBoxEntry* pEntry = new SvxBoxEntry(rEntry);
+ ListBox::InsertEntry(pEntry->aName, nPos);
+ //const SvxBoxEntry* &rpEntry = pEntry;
+ aEntryLst.C40_INSERT(SvxBoxEntry, pEntry, nPos);
+ }
+ else
+ InsertSorted(new SvxBoxEntry(rEntry));
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Eintrag aus der Liste loeschen
+ --------------------------------------------------------------------*/
+
+void SvxListBox::RemoveEntry(USHORT nPos)
+{
+ if(nPos >= aEntryLst.Count())
+ return;
+
+ // Altes Element austragen
+ SvxBoxEntry* pEntry = aEntryLst[nPos];
+ aEntryLst.Remove(nPos, 1);
+ ListBox::RemoveEntry(nPos);
+
+ // keine neuen Eintraege in die Liste mit aufnehmen
+ if(pEntry->bNew)
+ return;
+
+ // in DeleteListe eintragen
+ aDelEntryLst.C40_INSERT(SvxBoxEntry, pEntry, aDelEntryLst.Count());
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Eintrag ueber konkretes Obkjekt loeschen
+ --------------------------------------------------------------------*/
+
+void SvxListBox::RemoveEntry(const SvxBoxEntry& rEntry)
+{
+ USHORT nPos = ListBox::GetEntryPos(rEntry.aName);
+ RemoveEntry(nPos);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Listen loeschen und Anzeige loeschen
+ --------------------------------------------------------------------*/
+
+void SvxListBox::Clear()
+{
+ ListBox::Clear();
+ aEntryLst.DeleteAndDestroy(0, aEntryLst.Count());
+ aDelEntryLst.DeleteAndDestroy(0, aDelEntryLst.Count());
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Position by Name
+ --------------------------------------------------------------------*/
+
+USHORT SvxListBox::GetEntryPos(const SvxBoxEntry& rEntry) const
+{
+ return ListBox::GetEntryPos(rEntry.aName);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Rund um die Entries
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxListBox::GetSvxBoxEntry(USHORT nPos) const
+{
+ if(nPos < aEntryLst.Count())
+ return *aEntryLst[nPos];
+ else
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: aktullen Eintrag zurueckgeben
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxListBox::GetSelectSvxBoxEntry(USHORT nSelId) const
+{
+ String aName(ListBox::GetSelectEntry(nSelId));
+
+ if(aName.Len() > 0)
+ {
+ for (USHORT i=0; i < aEntryLst.Count(); i++)
+ {
+ if(aEntryLst[i]->aName == aName )
+ return *aEntryLst[i];
+ }
+ }
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: modifizierte Eintraege
+ --------------------------------------------------------------------*/
+
+USHORT SvxListBox::GetModifiedCount() const
+{
+ USHORT nMod = 0;
+ USHORT nSize = aEntryLst.Count();
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bModified)
+ nMod++;
+ }
+ return nMod;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Modifizierte Eintraege behandeln
+ --------------------------------------------------------------------*/
+
+void SvxListBox::ModifyEntry(USHORT nPos, const String& rName)
+{
+ if(nPos >= aEntryLst.Count())
+ return;
+
+ SvxBoxEntry* pEntry = aEntryLst[nPos];
+ aEntryLst.Remove(nPos, 1);
+ aEntryLst[nPos]->aName = rName;
+ aEntryLst[nPos]->bModified = TRUE;
+ ListBox::RemoveEntry(nPos);
+
+ InsertSorted(pEntry);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: alle modifizierten Eintraege bahandeln
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxListBox::GetModifiedEntry(USHORT nPos) const
+{
+ USHORT nSize = aEntryLst.Count();
+ USHORT nMod = 0;
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bModified)
+ { if(nMod == nPos)
+ return *aEntryLst[i];
+ nMod++;
+ }
+ }
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: geloeschte Eintraege
+ --------------------------------------------------------------------*/
+
+USHORT SvxListBox::GetRemovedCount() const
+{
+ return aDelEntryLst.Count();
+}
+
+
+const SvxBoxEntry& SvxListBox::GetRemovedEntry(USHORT nPos) const
+{
+ if(nPos < aDelEntryLst.Count())
+ return *aDelEntryLst[nPos];
+
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Neue Entries begutachten
+ --------------------------------------------------------------------*/
+
+USHORT SvxListBox::GetNewCount() const
+{
+ USHORT nNew = 0;
+ USHORT nSize = aEntryLst.Count();
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bNew)
+ nNew++;
+ }
+ return nNew;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Alle neuen Eintraege ueberpruefen
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxListBox::GetNewEntry(USHORT nPos) const
+{
+ USHORT nSize = aEntryLst.Count();
+ USHORT nNew = 0;
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bNew)
+ { if(nNew == nPos)
+ return *aEntryLst[i];
+ nNew++;
+ }
+ }
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Sortiert einfuegen
+ --------------------------------------------------------------------*/
+
+void SvxListBox::InsertSorted(SvxBoxEntry* pEntry)
+{
+ ListBox::InsertEntry(pEntry->aName);
+ USHORT nPos = ListBox::GetEntryPos(pEntry->aName);
+ aEntryLst.C40_INSERT(SvxBoxEntry, pEntry, nPos);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: ComboBoxen mit Verwaltungseinheit
+ --------------------------------------------------------------------*/
+
+SvxComboBox::SvxComboBox(Window* pParent, WinBits nBits, USHORT nStyleBits) :
+ ComboBox(pParent, nBits),
+ nStyle(nStyleBits)
+{
+ InitComboBox();
+}
+
+
+SvxComboBox::SvxComboBox(Window* pParent, const ResId& rId, USHORT nStyleBits ):
+ ComboBox(pParent, rId),
+ nStyle(nStyleBits)
+{
+ InitComboBox();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Basisklasse Dtor
+ --------------------------------------------------------------------*/
+
+__EXPORT SvxComboBox::~SvxComboBox()
+{
+ aEntryLst.DeleteAndDestroy(0, aEntryLst.Count());
+ aDelEntryLst.DeleteAndDestroy(0, aDelEntryLst.Count());
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Evtl. Liste aus der Ressource beachten
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::InitComboBox()
+{
+ // Verwaltung fuer die Stringlist aus der Resource aufbauen
+ USHORT nSize = GetEntryCount();
+ for(USHORT i=0; i < nSize; ++i)
+ { const SvxBoxEntry* pTmp = new SvxBoxEntry(ComboBox::GetEntry(i), i);
+ const SvxBoxEntry* &rpTmp = pTmp;
+ aEntryLst.Insert(rpTmp, aEntryLst.Count());
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: neue Eintraege verwalten
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::InsertNewEntry(const SvxBoxEntry& rEntry)
+{
+ SvxBoxEntry* pNew = new SvxBoxEntry(rEntry);
+ pNew->bNew = TRUE;
+ InsertSorted(pNew);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Eintrag in die ComboBox aufnehmen
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::InsertEntry(const SvxBoxEntry& rEntry)
+{
+ InsertSorted(new SvxBoxEntry(rEntry));
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Eintrag aus der Liste loeschen
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::RemoveEntry(USHORT nPos)
+{
+ if(nPos >= aEntryLst.Count())
+ return;
+
+ // Altes Element austragen
+ SvxBoxEntry* pEntry = aEntryLst[nPos];
+ aEntryLst.Remove(nPos, 1);
+ ComboBox::RemoveEntry(nPos);
+
+ // keine neuen Eintraege in die Liste mit aufnehmen
+ if(pEntry->bNew)
+ return;
+
+ // in DeleteListe eintragen
+ aDelEntryLst.C40_INSERT(SvxBoxEntry, pEntry, aDelEntryLst.Count());
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Eintrag ueber konkretes Obkjekt loeschen
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::RemoveEntry(const SvxBoxEntry& rEntry)
+{
+ USHORT nPos = ComboBox::GetEntryPos(rEntry.aName);
+ RemoveEntry(nPos);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Listen loeschen und Anzeige loeschen
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::Clear()
+{
+ ComboBox::Clear();
+ aEntryLst.DeleteAndDestroy(0, aEntryLst.Count());
+ aDelEntryLst.DeleteAndDestroy(0, aDelEntryLst.Count());
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Position by Name
+ --------------------------------------------------------------------*/
+
+USHORT SvxComboBox::GetEntryPos(const SvxBoxEntry& rEntry) const
+{
+ return ComboBox::GetEntryPos(rEntry.aName);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Rund um die Entries
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxComboBox::GetEntry(USHORT nPos) const
+{
+ if(nPos < aEntryLst.Count())
+ return *aEntryLst[nPos];
+ else
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: modifizierte Eintraege
+ --------------------------------------------------------------------*/
+
+USHORT SvxComboBox::GetModifiedCount() const
+{
+ USHORT nMod = 0;
+ USHORT nSize = aEntryLst.Count();
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bModified)
+ nMod++;
+ }
+ return nMod;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Modifizierte Eintraege behandeln
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::ModifyEntry(USHORT nPos, const String& rName)
+{
+ if(nPos >= aEntryLst.Count())
+ return;
+
+ SvxBoxEntry* pEntry = aEntryLst[nPos];
+ aEntryLst.Remove(nPos, 1);
+ aEntryLst[nPos]->aName = rName;
+ aEntryLst[nPos]->bModified = TRUE;
+ ComboBox::RemoveEntry(nPos);
+
+ InsertSorted(pEntry);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: alle modifizierten Eintraege bahandeln
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxComboBox::GetModifiedEntry(USHORT nPos) const
+{
+ USHORT nSize = aEntryLst.Count();
+ USHORT nMod = 0;
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bModified)
+ { if(nMod == nPos)
+ return *aEntryLst[i];
+ nMod++;
+ }
+ }
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: geloeschte Eintraege
+ --------------------------------------------------------------------*/
+
+USHORT SvxComboBox::GetRemovedCount() const
+{
+ return aDelEntryLst.Count();
+}
+
+
+const SvxBoxEntry& SvxComboBox::GetRemovedEntry(USHORT nPos) const
+{
+ if(nPos < aDelEntryLst.Count())
+ return *aDelEntryLst[nPos];
+
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Neue Entries begutachten
+ --------------------------------------------------------------------*/
+
+USHORT SvxComboBox::GetNewCount() const
+{
+ USHORT nNew = 0;
+ USHORT nSize = aEntryLst.Count();
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bNew)
+ nNew++;
+ }
+ return nNew;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Alle neuen Eintraege ueberpruefen
+ --------------------------------------------------------------------*/
+
+const SvxBoxEntry& SvxComboBox::GetNewEntry(USHORT nPos) const
+{
+ USHORT nSize = aEntryLst.Count();
+ USHORT nNew = 0;
+ for(USHORT i=0; i < nSize; ++i)
+ { if(aEntryLst[i]->bNew)
+ { if(nNew == nPos)
+ return *aEntryLst[i];
+ nNew++;
+ }
+ }
+ return aDefault;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Sortiert einfuegen
+ --------------------------------------------------------------------*/
+
+void SvxComboBox::InsertSorted(SvxBoxEntry* pEntry)
+{
+ ComboBox::InsertEntry(pEntry->aName);
+ USHORT nPos = ComboBox::GetEntryPos(pEntry->aName);
+ aEntryLst.C40_INSERT(SvxBoxEntry, pEntry, nPos);
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Je nach Option bestimmte Zeichen ausblenden
+ --------------------------------------------------------------------*/
+
+void __EXPORT SvxComboBox::KeyInput( const KeyEvent& rKEvt )
+{
+ sal_Unicode cChar = rKEvt.GetCharCode();
+
+ if(nStyle & SVX_CBS_FILENAME)
+ {
+#if defined UNX
+ if( cChar == sal_Unicode( '/' ) || cChar == sal_Unicode( ' ' ) )
+ return;
+#else
+ if( cChar == sal_Unicode( ':' ) || cChar == sal_Unicode( '\\' ) ||
+ cChar == sal_Unicode( '.' ) || cChar == sal_Unicode( ' ' ) )
+ return;
+#endif
+ }
+ ComboBox::KeyInput(rKEvt);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Text nach Option konvertieren
+ --------------------------------------------------------------------*/
+
+String SvxComboBox::GetText() const
+{
+ String aTxt(ComboBox::GetText());
+ CharClass aCharClass( Application::GetSettings().GetLocale() );
+
+ if(nStyle & SVX_CBS_LOWER)
+ return aCharClass.lower(aTxt);
+
+ if(nStyle & SVX_CBS_UPPER)
+ return aCharClass.upper(aTxt);
+
+ return aTxt;
+}
+
+
diff --git a/svtools/source/control/tabbar.cxx b/svtools/source/control/tabbar.cxx
new file mode 100755
index 000000000000..2ad81da40716
--- /dev/null
+++ b/svtools/source/control/tabbar.cxx
@@ -0,0 +1,2735 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "tabbar.hxx"
+#include <tools/time.hxx>
+#include <tools/debug.hxx>
+#include <tools/poly.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/button.hxx>
+#include <vcl/edit.hxx>
+#include "svtaccessiblefactory.hxx"
+
+#include <limits>
+
+// =======================================================================
+
+#define TABBAR_OFFSET_X 7
+#define TABBAR_OFFSET_X2 2
+#define TABBAR_DRAG_SCROLLOFF 5
+#define TABBAR_MINSIZE 5
+
+const USHORT ADDNEWPAGE_AREAWIDTH = 10;
+
+// =======================================================================
+
+struct ImplTabBarItem
+{
+ USHORT mnId;
+ TabBarPageBits mnBits;
+ XubString maText;
+ XubString maHelpText;
+ Rectangle maRect;
+ long mnWidth;
+ ULONG mnHelpId;
+ BOOL mbShort;
+ BOOL mbSelect;
+ BOOL mbEnable;
+ Color maTabBgColor;
+ bool IsDefaultTabBgColor() const { return maTabBgColor == Color(COL_AUTO) ? TRUE : FALSE; };
+ Color maTabTextColor;
+ bool IsDefaultTabTextColor() const { return maTabTextColor == Color(COL_AUTO) ? TRUE : FALSE; };
+
+ ImplTabBarItem( USHORT nItemId, const XubString& rText,
+ TabBarPageBits nPageBits ) :
+ maText( rText )
+ {
+ mnId = nItemId;
+ mnBits = nPageBits;
+ mnWidth = 0;
+ mnHelpId = 0;
+ mbShort = FALSE;
+ mbSelect = FALSE;
+ mbEnable = TRUE;
+ maTabBgColor = Color( COL_AUTO );
+ maTabTextColor = Color( COL_AUTO );
+ }
+};
+
+DECLARE_LIST( ImplTabBarList, ImplTabBarItem* )
+
+// =======================================================================
+
+// -----------------
+// - ImplTabButton -
+// -----------------
+
+class ImplTabButton : public PushButton
+{
+public:
+ ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) :
+ PushButton( pParent, nWinStyle | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS ) {}
+
+ TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+};
+
+// =======================================================================
+
+long ImplTabButton::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( GetParent()->IsInEditMode() )
+ {
+ GetParent()->EndEditMode();
+ return TRUE;
+ }
+ }
+
+ return PushButton::PreNotify( rNEvt );
+}
+
+// =======================================================================
+
+// ----------------
+// - ImplTabSizer -
+// ----------------
+
+class ImplTabSizer : public Window
+{
+public:
+ ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 );
+
+ TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
+
+private:
+ void ImplTrack( const Point& rScreenPos );
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+ virtual void Paint( const Rectangle& rRect );
+
+ Point maStartPos;
+ long mnStartWidth;
+};
+
+// -----------------------------------------------------------------------
+
+ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle & WB_3DLOOK )
+{
+ SetPointer( Pointer( POINTER_HSIZEBAR ) );
+ SetSizePixel( Size( 7, 0 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::ImplTrack( const Point& rScreenPos )
+{
+ TabBar* pParent = GetParent();
+ long nDiff = rScreenPos.X() - maStartPos.X();
+ pParent->mnSplitSize = mnStartWidth + (pParent->IsMirrored() ? -nDiff : nDiff);
+ if ( pParent->mnSplitSize < TABBAR_MINSIZE )
+ pParent->mnSplitSize = TABBAR_MINSIZE;
+ pParent->Split();
+ pParent->Update();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( GetParent()->IsInEditMode() )
+ {
+ GetParent()->EndEditMode();
+ return;
+ }
+
+ if ( rMEvt.IsLeft() )
+ {
+ maStartPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
+ mnStartWidth = GetParent()->GetSizePixel().Width();
+ StartTracking();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( rTEvt.IsTrackingCanceled() )
+ ImplTrack( maStartPos );
+ GetParent()->mnSplitSize = 0;
+ }
+ else
+ ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::Paint( const Rectangle& )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ DecorationView aDecoView( this );
+ long nOffX = 0;
+ Size aOutputSize = GetOutputSizePixel();
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) );
+ nOffX++;
+ aOutputSize.Width()--;
+ }
+ aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER );
+}
+
+// =======================================================================
+
+// Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar
+
+// --------------
+// - TabBarEdit -
+// --------------
+
+class TabBarEdit : public Edit
+{
+private:
+ Timer maLoseFocusTimer;
+ BOOL mbPostEvt;
+
+ DECL_LINK( ImplEndEditHdl, void* );
+ DECL_LINK( ImplEndTimerHdl, void* );
+
+public:
+ TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 );
+
+ TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
+
+ void SetPostEvent() { mbPostEvt = TRUE; }
+ void ResetPostEvent() { mbPostEvt = FALSE; }
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void LoseFocus();
+};
+
+// -----------------------------------------------------------------------
+
+TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) :
+ Edit( pParent, nWinStyle )
+{
+ mbPostEvt = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBarEdit::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ if ( !pKEvt->GetKeyCode().GetModifier() )
+ {
+ if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
+ {
+ if ( !mbPostEvt )
+ {
+ if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
+ mbPostEvt = TRUE;
+ }
+ return TRUE;
+ }
+ else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE )
+ {
+ if ( !mbPostEvt )
+ {
+ if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)TRUE ) )
+ mbPostEvt = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ }
+
+ return Edit::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBarEdit::LoseFocus()
+{
+ if ( !mbPostEvt )
+ {
+ if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
+ mbPostEvt = TRUE;
+ }
+
+ Edit::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel )
+{
+ ResetPostEvent();
+ maLoseFocusTimer.Stop();
+
+ // We need this query, because the edit get a losefous event,
+ // when it shows the context menu or the insert symbol dialog
+ if ( !HasFocus() && HasChildPathFocus( TRUE ) )
+ {
+ maLoseFocusTimer.SetTimeout( 30 );
+ maLoseFocusTimer.SetTimeoutHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) );
+ maLoseFocusTimer.Start();
+ }
+ else
+ GetParent()->EndEditMode( pCancel != 0 );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabBarEdit, ImplEndTimerHdl, void*, EMPTYARG )
+{
+ if ( HasFocus() )
+ return 0;
+
+ // We need this query, because the edit get a losefous event,
+ // when it shows the context menu or the insert symbol dialog
+ if ( HasChildPathFocus( TRUE ) )
+ maLoseFocusTimer.Start();
+ else
+ GetParent()->EndEditMode( TRUE );
+
+ return 0;
+}
+
+// =======================================================================
+struct TabBar_Impl
+{
+ ImplTabSizer* mpSizer;
+ ::svt::AccessibleFactoryAccess maAccessibleFactory;
+
+ TabBar_Impl()
+ :mpSizer( NULL )
+ {
+ }
+ ~TabBar_Impl()
+ {
+ delete mpSizer;
+ }
+};
+
+// =======================================================================
+
+const sal_uInt16 TabBar::APPEND = ::std::numeric_limits<sal_uInt16>::max();
+const sal_uInt16 TabBar::PAGE_NOT_FOUND = ::std::numeric_limits<sal_uInt16>::max();
+
+void TabBar::ImplInit( WinBits nWinStyle )
+{
+ mpItemList = new ImplTabBarList;
+ mpFirstBtn = NULL;
+ mpPrevBtn = NULL;
+ mpNextBtn = NULL;
+ mpLastBtn = NULL;
+ mpImpl = new TabBar_Impl;
+ mpEdit = NULL;
+ mnMaxPageWidth = 0;
+ mnCurMaxWidth = 0;
+ mnOffX = 0;
+ mnOffY = 0;
+ mnLastOffX = 0;
+ mnSplitSize = 0;
+ mnSwitchTime = 0;
+ mnWinStyle = nWinStyle;
+ mnCurPageId = 0;
+ mnFirstPos = 0;
+ mnDropPos = 0;
+ mnSwitchId = 0;
+ mnEditId = 0;
+ mbFormat = TRUE;
+ mbFirstFormat = TRUE;
+ mbSizeFormat = TRUE;
+ mbAutoMaxWidth = TRUE;
+ mbInSwitching = FALSE;
+ mbAutoEditMode = FALSE;
+ mbEditCanceled = FALSE;
+ mbDropPos = FALSE;
+ mbInSelect = FALSE;
+ mbSelColor = FALSE;
+ mbSelTextColor = FALSE;
+ mbMirrored = FALSE;
+
+ if ( nWinStyle & WB_3DTAB )
+ mnOffY++;
+
+ ImplInitControls();
+ SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
+ ImplInitSettings( TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+TabBar::TabBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+TabBar::~TabBar()
+{
+ EndEditMode( TRUE );
+
+ // Controls loeschen
+ if ( mpPrevBtn )
+ delete mpPrevBtn;
+ if ( mpNextBtn )
+ delete mpNextBtn;
+ if ( mpFirstBtn )
+ delete mpFirstBtn;
+ if ( mpLastBtn )
+ delete mpLastBtn;
+ delete mpImpl;
+
+ // Alle Items loeschen
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Itemlist loeschen
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplInitSettings( BOOL bFont, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aToolFont;
+ aToolFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aToolFont.Merge( GetControlFont() );
+ aToolFont.SetWeight( WEIGHT_BOLD );
+ SetZoomedPointFont( aToolFont );
+
+ // Font in der groesse Anpassen, wenn Fenster zu klein?
+ while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
+ {
+ Font aFont = GetFont();
+ if ( aFont.GetHeight() <= 6 )
+ break;
+ aFont.SetHeight( aFont.GetHeight()-1 );
+ SetFont( aFont );
+ }
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor,
+ Color& rSelectColor, Color& rSelectTextColor )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( IsControlBackground() )
+ rFaceColor = GetControlBackground();
+ else
+ rFaceColor = rStyleSettings.GetInactiveTabColor();
+ if ( IsControlForeground() )
+ rFaceTextColor = GetControlForeground();
+ else
+ rFaceTextColor = rStyleSettings.GetButtonTextColor();
+ if ( mbSelColor )
+ rSelectColor = maSelColor;
+ else
+ rSelectColor = rStyleSettings.GetActiveTabColor();
+ if ( mbSelTextColor )
+ rSelectTextColor = maSelTextColor;
+ else
+ rSelectTextColor = rStyleSettings.GetWindowTextColor();
+
+ // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
+ // selektierten Tabs in 3D erscheinen sollen
+ if ( mnWinStyle & WB_3DTAB )
+ {
+ Color aTempColor = rFaceColor;
+ rFaceColor = rSelectColor;
+ rSelectColor = aTempColor;
+ aTempColor = rFaceTextColor;
+ rFaceTextColor = rSelectTextColor;
+ rSelectTextColor = rFaceTextColor;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::ImplCalcWidth()
+{
+ // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
+ // wenn der Font geaendert wurde
+ if ( !mbSizeFormat )
+ return FALSE;
+
+ // Breiten der Tabs mit dem fetten Font ermitteln
+ Font aFont = GetFont();
+ if ( aFont.GetWeight() != WEIGHT_BOLD )
+ {
+ aFont.SetWeight( WEIGHT_BOLD );
+ SetFont( aFont );
+ }
+
+ if ( mnMaxPageWidth )
+ mnCurMaxWidth = mnMaxPageWidth;
+ else if ( mbAutoMaxWidth )
+ {
+ mnCurMaxWidth = mnLastOffX-mnOffX-
+ TABBAR_OFFSET_X-TABBAR_OFFSET_X-
+ TABBAR_OFFSET_X2-TABBAR_OFFSET_X2-TABBAR_OFFSET_X2;
+ if ( mnCurMaxWidth < 1 )
+ mnCurMaxWidth = 1;
+ }
+ else
+ mnCurMaxWidth = 0;
+
+ BOOL bChanged = FALSE;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ long nNewWidth = GetTextWidth( pItem->maText );
+ if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) )
+ {
+ pItem->mbShort = TRUE;
+ nNewWidth = mnCurMaxWidth;
+ }
+ else
+ pItem->mbShort = FALSE;
+ nNewWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
+ if ( pItem->mnWidth != nNewWidth )
+ {
+ pItem->mnWidth = nNewWidth;
+ if ( !pItem->maRect.IsEmpty() )
+ bChanged = TRUE;
+ }
+ pItem = mpItemList->Next();
+ }
+ mbSizeFormat = FALSE;
+ mbFormat = TRUE;
+ return bChanged;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplFormat()
+{
+ ImplCalcWidth();
+
+ if ( !mbFormat )
+ return;
+
+ USHORT n = 0;
+ long x = mnOffX;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
+ // gesetzt
+ if ( (n+1 < mnFirstPos) || (x > mnLastOffX) )
+ pItem->maRect.SetEmpty();
+ else
+ {
+ // Etwas von der Tab vor der ersten sichtbaren Page
+ // muss auch zu sehen sein
+ if ( n+1 == mnFirstPos )
+ pItem->maRect.Left() = x-pItem->mnWidth;
+ else
+ {
+ pItem->maRect.Left() = x;
+ x += pItem->mnWidth;
+ }
+ pItem->maRect.Right() = x+TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
+ pItem->maRect.Bottom() = maWinSize.Height()-1;
+
+ if( mbMirrored )
+ {
+ long nTmp = mnOffX + mnLastOffX - pItem->maRect.Right();
+ pItem->maRect.Right() = mnOffX + mnLastOffX - pItem->maRect.Left();
+ pItem->maRect.Left() = nTmp;
+ }
+ }
+
+ n++;
+ pItem = mpItemList->Next();
+ }
+
+ mbFormat = FALSE;
+
+ // Button enablen/disablen
+ ImplEnableControls();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::ImplGetLastFirstPos()
+{
+ USHORT nCount = (USHORT)(mpItemList->Count());
+ if ( !nCount || mbSizeFormat || mbFormat )
+ return 0;
+
+ USHORT nLastFirstPos = nCount-1;
+ long nWinWidth = mnLastOffX-mnOffX-TABBAR_OFFSET_X-ADDNEWPAGE_AREAWIDTH;
+ long nWidth = mpItemList->GetObject( nLastFirstPos )->mnWidth;
+ while ( nLastFirstPos && (nWidth < nWinWidth) )
+ {
+ nLastFirstPos--;
+ nWidth += mpItemList->GetObject( nLastFirstPos )->mnWidth;
+ }
+ if ( (nLastFirstPos != (USHORT)(mpItemList->Count()-1)) &&
+ (nWidth > nWinWidth) )
+ nLastFirstPos++;
+ return nLastFirstPos;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplInitControls()
+{
+ if ( mnWinStyle & WB_SIZEABLE )
+ {
+ if ( !mpImpl->mpSizer )
+ mpImpl->mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) );
+ mpImpl->mpSizer->Show();
+ }
+ else
+ {
+ DELETEZ( mpImpl->mpSizer );
+ }
+
+ Link aLink = LINK( this, TabBar, ImplClickHdl );
+
+ if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) )
+ {
+ if ( !mpPrevBtn )
+ {
+ mpPrevBtn = new ImplTabButton( this, WB_REPEAT );
+ mpPrevBtn->SetClickHdl( aLink );
+ }
+ mpPrevBtn->SetSymbol( mbMirrored ? SYMBOL_NEXT : SYMBOL_PREV );
+ mpPrevBtn->Show();
+
+ if ( !mpNextBtn )
+ {
+ mpNextBtn = new ImplTabButton( this, WB_REPEAT );
+ mpNextBtn->SetClickHdl( aLink );
+ }
+ mpNextBtn->SetSymbol( mbMirrored ? SYMBOL_PREV : SYMBOL_NEXT );
+ mpNextBtn->Show();
+ }
+ else
+ {
+ DELETEZ( mpPrevBtn );
+ DELETEZ( mpNextBtn );
+ }
+
+ if ( mnWinStyle & WB_SCROLL )
+ {
+ if ( !mpFirstBtn )
+ {
+ mpFirstBtn = new ImplTabButton( this );
+ mpFirstBtn->SetClickHdl( aLink );
+ }
+ mpFirstBtn->SetSymbol( mbMirrored ? SYMBOL_LAST : SYMBOL_FIRST );
+ mpFirstBtn->Show();
+
+ if ( !mpLastBtn )
+ {
+ mpLastBtn = new ImplTabButton( this );
+ mpLastBtn->SetClickHdl( aLink );
+ }
+ mpLastBtn->SetSymbol( mbMirrored ? SYMBOL_FIRST : SYMBOL_LAST );
+ mpLastBtn->Show();
+ }
+ else
+ {
+ DELETEZ( mpFirstBtn );
+ DELETEZ( mpLastBtn );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplEnableControls()
+{
+ if ( mbSizeFormat || mbFormat )
+ return;
+
+ // Buttons enablen/disblen
+ BOOL bEnableBtn = mnFirstPos > 0;
+ if ( mpFirstBtn )
+ mpFirstBtn->Enable( bEnableBtn );
+ if ( mpPrevBtn )
+ mpPrevBtn->Enable( bEnableBtn );
+
+ bEnableBtn = mnFirstPos < ImplGetLastFirstPos();
+ if ( mpNextBtn )
+ mpNextBtn->Enable( bEnableBtn );
+ if ( mpLastBtn )
+ mpLastBtn->Enable( bEnableBtn );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplShowPage( USHORT nPos )
+{
+ // Breite berechnen
+ long nWidth = GetOutputSizePixel().Width();
+ if ( nWidth >= TABBAR_OFFSET_X )
+ nWidth -= TABBAR_OFFSET_X;
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( nPos < mnFirstPos )
+ SetFirstPageId( pItem->mnId );
+ else if ( pItem->maRect.Right() > nWidth )
+ {
+ while ( pItem->maRect.Right() > nWidth )
+ {
+ USHORT nNewPos = mnFirstPos+1;
+ SetFirstPageId( GetPageId( nNewPos ) );
+ ImplFormat();
+ if ( nNewPos != mnFirstPos )
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn )
+{
+ EndEditMode();
+
+ USHORT nNewPos = mnFirstPos;
+
+ if ( pBtn == mpFirstBtn )
+ nNewPos = 0;
+ else if ( pBtn == mpPrevBtn )
+ {
+ if ( mnFirstPos )
+ nNewPos = mnFirstPos-1;
+ }
+ else if ( pBtn == mpNextBtn )
+ {
+ USHORT nCount = GetPageCount();
+ if ( mnFirstPos < nCount )
+ nNewPos = mnFirstPos+1;
+ }
+ else
+ {
+ USHORT nCount = GetPageCount();
+ if ( nCount )
+ nNewPos = nCount-1;
+ }
+
+ if ( nNewPos != mnFirstPos )
+ SetFirstPageId( GetPageId( nNewPos ) );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeaveWindow() )
+ mbInSelect = FALSE;
+
+ Window::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht
+ // ausfuehren
+ if ( IsInEditMode() )
+ {
+ EndEditMode();
+ return;
+ }
+
+ ImplTabBarItem* pItem;
+ USHORT nSelId = GetPageId( rMEvt.GetPosPixel() );
+
+ if ( !rMEvt.IsLeft() )
+ {
+ Window::MouseButtonDown( rMEvt );
+ if ( (nSelId > 0) && (nSelId != mnCurPageId) )
+ {
+ USHORT nPos = GetPagePos( nSelId );
+ pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable )
+ {
+ if ( ImplDeactivatePage() )
+ {
+ SetCurPageId( nSelId );
+ Update();
+ ImplActivatePage();
+ ImplSelect();
+ }
+ mbInSelect = TRUE;
+ }
+ }
+ return;
+ }
+
+ if ( rMEvt.IsMod2() && mbAutoEditMode && nSelId )
+ {
+ if ( StartEditMode( nSelId ) )
+ return;
+ }
+
+ if ( (rMEvt.GetMode() & (MOUSE_MULTISELECT | MOUSE_RANGESELECT)) && (rMEvt.GetClicks() == 1) )
+ {
+ if ( nSelId )
+ {
+ USHORT nPos = GetPagePos( nSelId );
+ BOOL bSelectTab = FALSE;
+ pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable )
+ {
+ if ( (rMEvt.GetMode() & MOUSE_MULTISELECT) && (mnWinStyle & WB_MULTISELECT) )
+ {
+ if ( nSelId != mnCurPageId )
+ {
+ SelectPage( nSelId, !IsPageSelected( nSelId ) );
+ bSelectTab = TRUE;
+ }
+ }
+ else if ( mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT) )
+ {
+ bSelectTab = TRUE;
+ USHORT n;
+ BOOL bSelect;
+ USHORT nCurPos = GetPagePos( mnCurPageId );
+ if ( nPos <= nCurPos )
+ {
+ // Alle Tabs bis zur angeklickten Tab deselektieren
+ // und alle Tabs von der angeklickten Tab bis
+ // zur aktuellen Position selektieren
+ n = 0;
+ while ( n < nCurPos )
+ {
+ pItem = mpItemList->GetObject( n );
+ if ( n < nPos )
+ bSelect = FALSE;
+ else
+ bSelect = TRUE;
+
+ if ( pItem->mbSelect != bSelect )
+ {
+ pItem->mbSelect = bSelect;
+ if ( !pItem->maRect.IsEmpty() )
+ Invalidate( pItem->maRect );
+ }
+
+ n++;
+ }
+ }
+
+ if ( nPos >= nCurPos )
+ {
+ // Alle Tabs von der aktuellen bis zur angeklickten
+ // Tab selektieren und alle Tabs von der angeklickten
+ // Tab bis zur letzten Tab deselektieren
+ USHORT nCount = (USHORT)mpItemList->Count();
+ n = nCurPos;
+ while ( n < nCount )
+ {
+ pItem = mpItemList->GetObject( n );
+
+ if ( n <= nPos )
+ bSelect = TRUE;
+ else
+ bSelect = FALSE;
+
+ if ( pItem->mbSelect != bSelect )
+ {
+ pItem->mbSelect = bSelect;
+ if ( !pItem->maRect.IsEmpty() )
+ Invalidate( pItem->maRect );
+ }
+
+ n++;
+ }
+ }
+ }
+
+ // Gegebenenfalls muss die selektierte Tab gescrollt werden
+ if ( bSelectTab )
+ {
+ ImplShowPage( nPos );
+ Update();
+ ImplSelect();
+ }
+ }
+ else
+ ImplShowPage( nPos );
+ mbInSelect = TRUE;
+
+ return;
+ }
+ }
+ else if ( rMEvt.GetClicks() == 2 )
+ {
+ // Gegebenenfalls den Double-Click-Handler rufen
+ if ( !rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)) )
+ {
+ USHORT nOldCurId = mnCurPageId;
+ mnCurPageId = nSelId;
+ DoubleClick();
+ // Abfrage, da im DoubleClick-Handler die aktuelle Seite
+ // umgeschaltet werden konnte
+ if ( mnCurPageId == nSelId )
+ mnCurPageId = nOldCurId;
+ }
+
+ return;
+ }
+ else
+ {
+ if ( nSelId )
+ {
+ // Nur Select ausfuehren, wenn noch nicht aktuelle Page
+ if ( nSelId != mnCurPageId )
+ {
+ USHORT nPos = GetPagePos( nSelId );
+ pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable )
+ {
+ if ( !pItem->mbSelect )
+ {
+ // Muss invalidiert werden
+ BOOL bUpdate = FALSE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ bUpdate = TRUE;
+
+ // Alle selektierten Items deselektieren
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
+ {
+ pItem->mbSelect = FALSE;
+ if ( bUpdate )
+ Invalidate( pItem->maRect );
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+
+ if ( ImplDeactivatePage() )
+ {
+ SetCurPageId( nSelId );
+ Update();
+ ImplActivatePage();
+ ImplSelect();
+ }
+ }
+ else
+ ImplShowPage( nPos );
+ mbInSelect = TRUE;
+ }
+
+ return;
+ }
+ }
+
+ Window::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ mbInSelect = FALSE;
+ Window::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Paint( const Rectangle& )
+{
+ // Items berechnen und ausgeben
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ ImplTabBarItem* pItem;
+
+ // kein Item, dann auch nichts zu tun
+ if ( nItemCount )
+ {
+ // TabBar muss formatiert sein
+ ImplFormat();
+
+ // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
+ // sichtbar wird
+ if ( mbFirstFormat )
+ {
+ mbFirstFormat = FALSE;
+
+ if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos )
+ {
+ pItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
+ if ( pItem->maRect.IsEmpty() )
+ {
+ // mbDropPos setzen (bzw. misbrauchen) um Invalidate()
+ // zu unterbinden
+ mbDropPos = TRUE;
+ SetFirstPageId( mnCurPageId );
+ mbDropPos = FALSE;
+ if ( mnFirstPos != 0 )
+ ImplFormat();
+ }
+ }
+ }
+ }
+
+ // Farben ermitteln
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aFaceColor;
+ Color aSelectColor;
+ Color aFaceTextColor;
+ Color aSelectTextColor;
+ ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
+
+ // Font selektieren
+ Font aFont = GetFont();
+ Font aLightFont = aFont;
+ //aLightFont.SetWeight( WEIGHT_LIGHT ); //TODO Make font weight light on custom color only?
+ aLightFont.SetWeight( WEIGHT_NORMAL );
+
+ // #i36013# exclude push buttons from painting area
+ Rectangle aClipRect( Point( mnOffX, 0 ), Point( mnLastOffX, GetOutputHeightPixel() - 1 ) );
+ SetClipRegion( Region( aClipRect ) );
+
+ // Bei Border oben und unten einen Strich extra malen
+ if ( (mnWinStyle & WB_BORDER) || (mnWinStyle & WB_TOPBORDER) )
+ {
+ Size aOutputSize = GetOutputSizePixel();
+
+ // Bei 3D-Tabs wird auch der Border in 3D gemalt
+ if ( mnWinStyle & WB_3DTAB )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( mnOffX, 0 ), Point( aOutputSize.Width(), 0 ) );
+ }
+
+ // Border malen (Strich oben und Strich unten)
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( mnOffX, mnOffY ), Point( aOutputSize.Width()-1, mnOffY ) );
+ }
+ else
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+
+ // Items ausgeben
+ if ( nItemCount )
+ {
+ // letzten sichtbaren Eintrag suchen
+ USHORT n = mnFirstPos+1;
+ if ( n >= nItemCount )
+ n = nItemCount-1;
+ pItem = mpItemList->Seek( n );
+ while ( pItem )
+ {
+ if ( !pItem->maRect.IsEmpty() )
+ {
+ n++;
+ pItem = mpItemList->Next();
+ }
+ else
+ break;
+ }
+
+ // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
+ if ( pItem )
+ n--;
+ else if ( n >= nItemCount )
+ n = nItemCount-1;
+ pItem = mpItemList->Seek( n );
+ ImplTabBarItem* pCurItem = NULL;
+ while ( pItem )
+ {
+ // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
+ if ( !pCurItem && (pItem->mnId == mnCurPageId) )
+ {
+ pCurItem = pItem;
+ pItem = mpItemList->Prev();
+ if ( !pItem )
+ pItem = pCurItem;
+ continue;
+ }
+
+ if ( !pItem->maRect.IsEmpty() )
+ {
+ Rectangle aRect = pItem->maRect;
+
+ // Aktuelle Page wird mit einem fetten Font ausgegeben
+ if ( pItem->mnId == mnCurPageId )
+ SetFont( aFont );
+ else
+ SetFont( aLightFont );
+
+ // Je nach Status die richtige FillInBrush setzen
+ // Set the correct FillInBrush depending upon status
+ if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
+ {
+ // Currently selected Tab
+ SetFillColor( aSelectColor );
+ SetTextColor( aSelectTextColor );
+ }
+ else
+ {
+ if ( !pItem->IsDefaultTabBgColor() && !rStyleSettings.GetHighContrastMode() )
+ {
+ SetFillColor( pItem->maTabBgColor );
+ SetTextColor( pItem->maTabTextColor );
+ } else {
+ SetFillColor( aFaceColor );
+ SetTextColor( aFaceTextColor );
+ }
+ }
+
+ // Muss Font Kursiv geschaltet werden
+ if ( pItem->mnBits & TPB_SPECIAL )
+ {
+ SetTextColor( Color( COL_LIGHTBLUE ) );
+ }
+
+ // Position der Page berechnen
+ Point aPos0 = Point( aRect.Left(), mnOffY );
+ Point aPos1 = Point( aRect.Left()+TABBAR_OFFSET_X, aRect.Bottom() );
+ Point aPos2 = Point( aRect.Right()-TABBAR_OFFSET_X, aRect.Bottom() );
+ Point aPos3 = Point( aRect.Right(), mnOffY );
+
+ // Zuerst geben wir das Polygon gefuellt aus
+ Polygon aPoly( 4 );
+ aPoly[0] = aPos0;
+ aPoly[1] = aPos1;
+ aPoly[2] = aPos2;
+ aPoly[3] = aPos3;
+ DrawPolygon( aPoly );
+
+ // Danach den Text zentiert ausgeben
+ XubString aText = pItem->maText;
+ if ( pItem->mbShort )
+ aText = GetEllipsisString( aText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS );
+ Size aRectSize = aRect.GetSize();
+ long nTextWidth = GetTextWidth( aText );
+ long nTextHeight = GetTextHeight();
+ Point aTxtPos( aRect.Left()+(aRectSize.Width()-nTextWidth)/2,
+ (aRectSize.Height()-nTextHeight)/2 );
+ if ( pItem->IsDefaultTabBgColor() || (!pItem->mbSelect) )
+ {
+ if ( !pItem->mbEnable )
+ DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) );
+ else
+ DrawText( aTxtPos, aText );
+ }
+ // Jetzt im Inhalt den 3D-Effekt ausgeben
+ aPos0.X()++;
+ aPos1.X()++;
+ aPos2.X()--;
+ aPos3.X()--;
+
+ // If this is the current tab, draw the left inner shadow the default color,
+ // otherwise make it the same as the custom background color
+ if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) {
+ SetLineColor( rStyleSettings.GetLightColor() );
+ } else {
+ if ( !pItem->IsDefaultTabBgColor() && ! rStyleSettings.GetHighContrastMode() )
+ {
+ SetLineColor( pItem->maTabBgColor );
+ } else {
+ SetLineColor( rStyleSettings.GetLightColor() );
+ }
+ }
+ // Draw the left side of the tab
+ DrawLine( aPos0, aPos1 );
+
+ if ( !pItem->mbSelect && (pItem->mnId != mnCurPageId) )
+ {
+ // Draw the top inner shadow
+ // ToDo: Change from this static color to tab custom bg color
+ DrawLine( Point( aPos0.X(), aPos0.Y()+1 ),
+ Point( aPos3.X(), aPos3.Y()+1 ) );
+ }
+
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( aPos2, aPos3 );
+ aPos1.X()--;
+ aPos1.Y()--;
+ aPos2.Y()--;
+ if ( !pItem->IsDefaultTabBgColor() && ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) )
+ {
+ SetLineColor( pItem->maTabBgColor );
+ DrawLine( Point(aPos1.X()-1, aPos1.Y()-1), Point(aPos2.X(), aPos2.Y()-1) );
+ }
+ DrawLine( aPos1, aPos2 );
+
+ // draw a small 2px sliver of the original background color at the bottom of the selected tab
+
+ if ( !pItem->IsDefaultTabBgColor() )
+ {
+ if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) || rStyleSettings.GetHighContrastMode() ) {
+ SetLineColor( pItem->maTabBgColor );
+ DrawLine( Point(aPos1.X()-1, aPos1.Y()-1), Point(aPos2.X(), aPos2.Y()-1) );
+ if ( !pItem->mbEnable )
+ DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) );
+ else
+ DrawText( aTxtPos, aText );
+ }
+ }
+
+ // Da etwas uebermalt werden konnte, muessen wir die Polygon-
+ // umrandung nocheinmal ausgeben
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ SetFillColor();
+ DrawPolygon( aPoly );
+
+ // Beim dem aktuellen Tab die restlichten Ausgaben vornehmen und
+ // die Schleife abbrechen, da die aktuelle Tab als letztes
+ // ausgegeben wird
+ if ( pItem == pCurItem )
+ {
+ // Beim aktuellen Item muss der oberstes Strich geloescht
+ // werden
+ SetLineColor();
+ SetFillColor( aSelectColor );
+ Rectangle aDelRect( aPos0, aPos3 );
+ DrawRect( aDelRect );
+ if ( mnWinStyle & WB_3DTAB )
+ {
+ aDelRect.Top()--;
+ DrawRect( aDelRect );
+ }
+
+ break;
+ }
+
+ pItem = mpItemList->Prev();
+ }
+ else
+ {
+ if ( pItem == pCurItem )
+ break;
+
+ pItem = NULL;
+ }
+
+ if ( !pItem )
+ pItem = pCurItem;
+ }
+ }
+
+ // Font wieder herstellen
+ SetFont( aFont );
+ // remove clip region
+ SetClipRegion();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Resize()
+{
+ Size aNewSize = GetOutputSizePixel();
+
+ long nSizerWidth = 0;
+ long nButtonWidth = 0;
+
+ // Sizer anordnen
+ if ( mpImpl->mpSizer )
+ {
+ Size aSizerSize = mpImpl->mpSizer->GetSizePixel();
+ Point aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 );
+ Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
+ mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
+ nSizerWidth = aSizerSize.Width();
+ }
+
+ // Scroll-Buttons anordnen
+ long nHeight = aNewSize.Height();
+ // Font in der groesse Anpassen?
+ ImplInitSettings( TRUE, FALSE );
+
+ long nX = mbMirrored ? (aNewSize.Width()-nHeight) : 0;
+ long nXDiff = mbMirrored ? -nHeight : nHeight;
+
+ Size aBtnSize( nHeight, nHeight );
+ if ( mpFirstBtn )
+ {
+ mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nXDiff;
+ nButtonWidth += nHeight;
+ }
+ if ( mpPrevBtn )
+ {
+ mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nXDiff;
+ nButtonWidth += nHeight;
+ }
+ if ( mpNextBtn )
+ {
+ mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nXDiff;
+ nButtonWidth += nHeight;
+ }
+ if ( mpLastBtn )
+ {
+ mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nXDiff;
+ nButtonWidth += nHeight;
+ }
+
+ // Groesse merken
+ maWinSize = aNewSize;
+
+ if( mbMirrored )
+ {
+ mnOffX = nSizerWidth;
+ mnLastOffX = maWinSize.Width() - nButtonWidth - 1;
+ }
+ else
+ {
+ mnOffX = nButtonWidth;
+ mnLastOffX = maWinSize.Width() - nSizerWidth - 1;
+ }
+
+ // Neu formatieren
+ mbSizeFormat = TRUE;
+ if ( IsReallyVisible() )
+ {
+ if ( ImplCalcWidth() )
+ Invalidate();
+ ImplFormat();
+ }
+
+ // Button enablen/disablen
+ ImplEnableControls();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ XubString aStr = GetHelpText( nItemId );
+ if ( aStr.Len() )
+ {
+ Rectangle aItemRect = GetPageRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ return;
+ }
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId, this );
+ return;
+ }
+ }
+
+ // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
+ // wenn dieser abgeschnitten oder nicht voll sichtbar ist
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ USHORT nPos = GetPagePos( nItemId );
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mbShort ||
+ (pItem->maRect.Right()-TABBAR_OFFSET_X-5 > mnLastOffX) )
+ {
+ Rectangle aItemRect = GetPageRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ XubString aStr = mpItemList->GetObject( nPos )->maText;
+ if ( aStr.Len() )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ return;
+ }
+ }
+ }
+ }
+
+ Window::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( (mbSizeFormat || mbFormat) && mpItemList->Count() )
+ ImplFormat();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ Invalidate();
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_MIRRORING )
+ {
+ // reacts on calls of EnableRTL, have to mirror all child controls
+ if( mpFirstBtn ) mpFirstBtn->EnableRTL( IsRTLEnabled() );
+ if( mpPrevBtn ) mpPrevBtn->EnableRTL( IsRTLEnabled() );
+ if( mpNextBtn ) mpNextBtn->EnableRTL( IsRTLEnabled() );
+ if( mpLastBtn ) mpLastBtn->EnableRTL( IsRTLEnabled() );
+ if( mpImpl->mpSizer ) mpImpl->mpSizer->EnableRTL( IsRTLEnabled() );
+ if( mpEdit ) mpEdit->EnableRTL( IsRTLEnabled() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplSelect()
+{
+ Select();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Split()
+{
+ maSplitHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplActivatePage()
+{
+ ActivatePage();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ActivatePage()
+{
+ maActivatePageHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::ImplDeactivatePage()
+{
+ long nRet = DeactivatePage();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::DeactivatePage()
+{
+ if ( maDeactivatePageHdl.IsSet() )
+ return maDeactivatePageHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::StartRenaming()
+{
+ if ( maStartRenamingHdl.IsSet() )
+ return maStartRenamingHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::AllowRenaming()
+{
+ if ( maAllowRenamingHdl.IsSet() )
+ return maAllowRenamingHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EndRenaming()
+{
+ maEndRenamingHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Mirror()
+{
+
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::InsertPage( USHORT nPageId, const XubString& rText,
+ TabBarPageBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
+ DBG_ASSERT( GetPagePos( nPageId ) == PAGE_NOT_FOUND,
+ "TabBar::InsertPage(): PageId already exists" );
+ DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
+
+ // PageItem anlegen und in die Item-Liste eintragen
+ ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
+ mpItemList->Insert( pItem, nPos );
+ mbSizeFormat = TRUE;
+
+ // CurPageId gegebenenfalls setzen
+ if ( !mnCurPageId )
+ mnCurPageId = nPageId;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
+}
+
+// -----------------------------------------------------------------------
+
+Color TabBar::GetTabBgColor( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->maTabBgColor;
+ else
+ return Color( COL_AUTO );
+}
+
+void TabBar::SetTabBgColor( USHORT nPageId, const Color& aTabBgColor )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ ImplTabBarItem* pItem;
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ pItem = mpItemList->GetObject( nPos );
+ if ( aTabBgColor != Color( COL_AUTO ) )
+ {
+ pItem->maTabBgColor = aTabBgColor;
+ if ( aTabBgColor.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
+ pItem->maTabTextColor = Color( COL_WHITE );
+ else
+ pItem->maTabTextColor = Color( COL_BLACK );
+ }
+ else
+ {
+ pItem->maTabBgColor = Color( COL_AUTO );
+ pItem->maTabTextColor = Color( COL_AUTO );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::RemovePage( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Existiert Item
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ if ( mnCurPageId == nPageId )
+ mnCurPageId = 0;
+
+ // Testen, ob erste sichtbare Seite verschoben werden muss
+ if ( mnFirstPos > nPos )
+ mnFirstPos--;
+
+ // Item-Daten loeschen
+ delete mpItemList->Remove( nPos );
+ mbFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MovePage( USHORT nPageId, USHORT nNewPos )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ Pair aPair( nPos, nNewPos );
+
+ if ( nPos < nNewPos )
+ nNewPos--;
+
+ if ( nPos == nNewPos )
+ return;
+
+ // Existiert Item
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ // TabBar-Item in der Liste verschieben
+ ImplTabBarItem* pItem = mpItemList->Remove( nPos );
+ mpItemList->Insert( pItem, nNewPos );
+ mbFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Clear()
+{
+ // Alle Items loeschen
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Item-Daten loeschen
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+ mbSizeFormat = TRUE;
+ mnCurPageId = 0;
+ mnFirstPos = 0;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, (void*) PAGE_NOT_FOUND );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EnablePage( USHORT nPageId, BOOL bEnable )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable != bEnable )
+ {
+ pItem->mbEnable = bEnable;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate( pItem->maRect );
+
+ CallEventListeners( bEnable ? VCLEVENT_TABBAR_PAGEENABLED : VCLEVENT_TABBAR_PAGEDISABLED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::IsPageEnabled( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->mbEnable;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetPageBits( USHORT nPageId, TabBarPageBits nBits )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mnBits != nBits )
+ {
+ pItem->mnBits = nBits;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate( pItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TabBarPageBits TabBar::GetPageBits( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->mnBits;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPageCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPageId( USHORT nPos ) const
+{
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPagePos( USHORT nPageId ) const
+{
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nPageId )
+ return (USHORT)mpItemList->GetCurPos();
+
+ pItem = mpItemList->Next();
+ }
+
+ return PAGE_NOT_FOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPageId( const Point& rPos ) const
+{
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->maRect.IsInside( rPos ) )
+ return pItem->mnId;
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle TabBar::GetPageRect( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->maRect;
+ else
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetCurPageId( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Wenn Item nicht existiert, dann nichts machen
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
+ // jetzt nichts mehr machen
+ if ( nPageId == mnCurPageId )
+ return;
+
+ // Muss invalidiert werden
+ BOOL bUpdate = FALSE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ bUpdate = TRUE;
+
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ ImplTabBarItem* pOldItem;
+
+ if ( mnCurPageId )
+ pOldItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
+ else
+ pOldItem = NULL;
+
+ // Wenn Page nicht selektiert, dann vorher selektierte Seite
+ // deselktieren, wenn dies die einzige selektierte Seite ist
+ if ( !pItem->mbSelect && pOldItem )
+ {
+ USHORT nSelPageCount = GetSelectPageCount();
+ if ( nSelPageCount == 1 )
+ pOldItem->mbSelect = FALSE;
+ pItem->mbSelect = TRUE;
+ }
+
+ mnCurPageId = nPageId;
+ mbFormat = TRUE;
+
+ // Dafuer sorgen, das aktuelle Page sichtbar wird
+ if ( IsReallyVisible() )
+ {
+ if ( nPos < mnFirstPos )
+ SetFirstPageId( nPageId );
+ else
+ {
+ // sichtbare Breite berechnen
+ long nWidth = mnLastOffX;
+ if ( nWidth > TABBAR_OFFSET_X )
+ nWidth -= TABBAR_OFFSET_X;
+ if ( nWidth > ADDNEWPAGE_AREAWIDTH )
+ nWidth -= ADDNEWPAGE_AREAWIDTH;
+
+ if ( pItem->maRect.IsEmpty() )
+ ImplFormat();
+
+ while ( (mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) ||
+ pItem->maRect.IsEmpty() )
+ {
+ USHORT nNewPos = mnFirstPos+1;
+ // Dafuer sorgen, das min. die aktuelle TabPages als
+ // erste TabPage sichtbar ist
+ if ( nNewPos >= nPos )
+ {
+ SetFirstPageId( nPageId );
+ break;
+ }
+ else
+ SetFirstPageId( GetPageId( nNewPos ) );
+ ImplFormat();
+ // Falls erste Seite nicht weitergeschaltet wird, dann
+ // koennen wir abbrechen
+ if ( nNewPos != mnFirstPos )
+ break;
+ }
+ }
+ }
+
+ // Leiste neu ausgeben
+ if ( bUpdate )
+ {
+ Invalidate( pItem->maRect );
+ if ( pOldItem )
+ Invalidate( pOldItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MakeVisible( USHORT nPageId )
+{
+ if ( !IsReallyVisible() )
+ return;
+
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Wenn Item nicht existiert, dann nichts machen
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ if ( nPos < mnFirstPos )
+ SetFirstPageId( nPageId );
+ else
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ // sichtbare Breite berechnen
+ long nWidth = mnLastOffX;
+ if ( nWidth > TABBAR_OFFSET_X )
+ nWidth -= TABBAR_OFFSET_X;
+
+ if ( mbFormat || pItem->maRect.IsEmpty() )
+ {
+ mbFormat = TRUE;
+ ImplFormat();
+ }
+
+ while ( (pItem->maRect.Right() > nWidth) ||
+ pItem->maRect.IsEmpty() )
+ {
+ USHORT nNewPos = mnFirstPos+1;
+ // Dafuer sorgen, das min. die aktuelle TabPages als
+ // erste TabPage sichtbar ist
+ if ( nNewPos >= nPos )
+ {
+ SetFirstPageId( nPageId );
+ break;
+ }
+ else
+ SetFirstPageId( GetPageId( nNewPos ) );
+ ImplFormat();
+ // Falls erste Seite nicht weitergeschaltet wird, dann
+ // koennen wir abbrechen
+ if ( nNewPos != mnFirstPos )
+ break;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetFirstPageId( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Wenn Item nicht existiert, dann FALSE zurueckgeben
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ if ( nPos != mnFirstPos )
+ {
+ // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
+ // moeglich sichtbar sind
+ ImplFormat();
+ USHORT nLastFirstPos = ImplGetLastFirstPos();
+ USHORT nNewPos;
+ if ( nPos > nLastFirstPos )
+ nNewPos = nLastFirstPos;
+ else
+ nNewPos = nPos;
+
+ if ( nNewPos != mnFirstPos )
+ {
+ mnFirstPos = nNewPos;
+ mbFormat = TRUE;
+
+ // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
+ // dieses Flag gesetzt ist, wird direkt gepaintet)
+ if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos )
+ Invalidate();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SelectPage( USHORT nPageId, BOOL bSelect )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbSelect != bSelect )
+ {
+ pItem->mbSelect = bSelect;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate( pItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SelectPageRange( BOOL bSelect, USHORT nStartPos, USHORT nEndPos )
+{
+ Rectangle aPaintRect;
+ USHORT nPos = nStartPos;
+ ImplTabBarItem* pItem = mpItemList->Seek( nPos );
+ while ( pItem && (nPos <= nEndPos) )
+ {
+ if ( (pItem->mbSelect != bSelect) && (pItem->mnId != mnCurPageId) )
+ {
+ pItem->mbSelect = bSelect;
+ aPaintRect.Union( pItem->maRect );
+ }
+
+ nPos++;
+ pItem = mpItemList->Next();
+ }
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() && !aPaintRect.IsEmpty() )
+ Invalidate( aPaintRect );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetSelectPage( USHORT nSelIndex ) const
+{
+ USHORT nSelected = 0;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect )
+ nSelected++;
+
+ if ( nSelected == nSelIndex )
+ return pItem->mnId;
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetSelectPageCount() const
+{
+ USHORT nSelected = 0;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect )
+ nSelected++;
+
+ pItem = mpItemList->Next();
+ }
+
+ return nSelected;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::IsPageSelected( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->mbSelect;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::StartEditMode( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( mpEdit || (nPos == PAGE_NOT_FOUND) || (mnLastOffX < 8) )
+ return FALSE;
+
+ mnEditId = nPageId;
+ if ( StartRenaming() )
+ {
+ ImplShowPage( nPos );
+ ImplFormat();
+ Update();
+
+ mpEdit = new TabBarEdit( this, WB_CENTER );
+ Rectangle aRect = GetPageRect( mnEditId );
+ long nX = aRect.Left()+TABBAR_OFFSET_X+(TABBAR_OFFSET_X2/2);
+ long nWidth = aRect.GetWidth()-(TABBAR_OFFSET_X*2)-TABBAR_OFFSET_X2;
+ if ( mnEditId != GetCurPageId() )
+ nX += 1;
+ if ( nX+nWidth > mnLastOffX )
+ nWidth = mnLastOffX-nX;
+ if ( nWidth < 3 )
+ {
+ nX = aRect.Left();
+ nWidth = aRect.GetWidth();
+ }
+ mpEdit->SetText( GetPageText( mnEditId ) );
+ mpEdit->SetPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 );
+ Font aFont = GetPointFont();
+ Color aForegroundColor;
+ Color aBackgroundColor;
+ Color aFaceColor;
+ Color aSelectColor;
+ Color aFaceTextColor;
+ Color aSelectTextColor;
+ ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
+ if ( mnEditId != GetCurPageId() )
+ aFont.SetWeight( WEIGHT_LIGHT );
+ if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) )
+ {
+ aForegroundColor = aSelectTextColor;
+ aBackgroundColor = aSelectColor;
+ }
+ else
+ {
+ aForegroundColor = aFaceTextColor;
+ aBackgroundColor = aFaceColor;
+ }
+ if ( GetPageBits( mnEditId ) & TPB_SPECIAL )
+ aForegroundColor = Color( COL_LIGHTBLUE );
+ mpEdit->SetControlFont( aFont );
+ mpEdit->SetControlForeground( aForegroundColor );
+ mpEdit->SetControlBackground( aBackgroundColor );
+ mpEdit->GrabFocus();
+ mpEdit->SetSelection( Selection( 0, mpEdit->GetText().Len() ) );
+ mpEdit->Show();
+ return TRUE;
+ }
+ else
+ {
+ mnEditId = 0;
+ return FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EndEditMode( BOOL bCancel )
+{
+ if ( mpEdit )
+ {
+ // call hdl
+ BOOL bEnd = TRUE;
+ mbEditCanceled = bCancel;
+ maEditText = mpEdit->GetText();
+ mpEdit->SetPostEvent();
+ if ( !bCancel )
+ {
+ long nAllowRenaming = AllowRenaming();
+ if ( nAllowRenaming == TABBAR_RENAMING_YES )
+ SetPageText( mnEditId, maEditText );
+ else if ( nAllowRenaming == TABBAR_RENAMING_NO )
+ bEnd = FALSE;
+ else // nAllowRenaming == TABBAR_RENAMING_CANCEL
+ mbEditCanceled = TRUE;
+ }
+
+ // renaming not allowed, than reset edit data
+ if ( !bEnd )
+ {
+ mpEdit->ResetPostEvent();
+ mpEdit->GrabFocus();
+ }
+ else
+ {
+ // close edit and call end hdl
+ delete mpEdit;
+ mpEdit = NULL;
+ EndRenaming();
+ mnEditId = 0;
+ }
+
+ // reset
+ maEditText.Erase();
+ mbEditCanceled = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetMirrored( BOOL bMirrored )
+{
+ if( mbMirrored != bMirrored )
+ {
+ mbMirrored = bMirrored;
+ mbSizeFormat = TRUE;
+ ImplInitControls(); // for button images
+ Resize(); // recalculates control positions
+ Mirror();
+ }
+}
+
+void TabBar::SetEffectiveRTL( BOOL bRTL )
+{
+ SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() );
+}
+
+BOOL TabBar::IsEffectiveRTL() const
+{
+ return IsMirrored() != Application::GetSettings().GetLayoutRTL();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetMaxPageWidth( long nMaxWidth )
+{
+ if ( mnMaxPageWidth != nMaxWidth )
+ {
+ mnMaxPageWidth = nMaxWidth;
+ mbSizeFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectColor()
+{
+ if ( mbSelColor )
+ {
+ maSelColor = Color( COL_TRANSPARENT );
+ mbSelColor = FALSE;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectColor( const Color& rColor )
+{
+ if ( rColor.GetTransparency() )
+ {
+ if ( mbSelColor )
+ {
+ maSelColor = Color( COL_TRANSPARENT );
+ mbSelColor = FALSE;
+ Invalidate();
+ }
+ }
+ else
+ {
+ if ( maSelColor != rColor )
+ {
+ maSelColor = rColor;
+ mbSelColor = TRUE;
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectTextColor()
+{
+ if ( mbSelTextColor )
+ {
+ maSelTextColor = Color( COL_TRANSPARENT );
+ mbSelTextColor = FALSE;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectTextColor( const Color& rColor )
+{
+ if ( rColor.GetTransparency() )
+ {
+ if ( mbSelTextColor )
+ {
+ maSelTextColor = Color( COL_TRANSPARENT );
+ mbSelTextColor = FALSE;
+ Invalidate();
+ }
+ }
+ else
+ {
+ if ( maSelTextColor != rColor )
+ {
+ maSelTextColor = rColor;
+ mbSelTextColor = TRUE;
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetPageText( USHORT nPageId, const XubString& rText )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ mpItemList->GetObject( nPos )->maText = rText;
+ mbSizeFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+
+ CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString TabBar::GetPageText( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->maText;
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetHelpText( USHORT nPageId, const XubString& rText )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ mpItemList->GetObject( nPos )->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+XubString TabBar::GetHelpText( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetHelpId( USHORT nPageId, ULONG nHelpId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG TabBar::GetHelpId( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != PAGE_NOT_FOUND )
+ return mpItemList->GetObject( nPos )->mnHelpId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::GetMinSize() const
+{
+ long nMinSize = TABBAR_MINSIZE + TABBAR_OFFSET_X;
+ if ( mnWinStyle & WB_MINSCROLL )
+ nMinSize += mpPrevBtn->GetSizePixel().Width()*2;
+ else if ( mnWinStyle & WB_SCROLL )
+ nMinSize += mpFirstBtn->GetSizePixel().Width()*4;
+ return nMinSize;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
+{
+ if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) )
+ return FALSE;
+
+ // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
+ // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
+ // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
+ // dies nur bei einer Mausaktion.
+ // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
+ // da der Select schon den Bereich gescrollt haben kann
+ if ( rCEvt.IsMouseEvent() && !mbInSelect )
+ {
+ USHORT nSelId = GetPageId( rCEvt.GetMousePosPixel() );
+
+ // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
+ if ( !nSelId )
+ return FALSE;
+
+ // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
+ // Seite setzen und Select rufen.
+ if ( !IsPageSelected( nSelId ) )
+ {
+ if ( ImplDeactivatePage() )
+ {
+ SetCurPageId( nSelId );
+ Update();
+ ImplActivatePage();
+ ImplSelect();
+ }
+ else
+ return FALSE;
+ }
+ }
+ mbInSelect = FALSE;
+
+ Region aRegion;
+
+ // Region zuweisen
+ rRegion = aRegion;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::ShowDropPos( const Point& rPos )
+{
+ ImplTabBarItem* pItem;
+ USHORT nDropId;
+ USHORT nNewDropPos;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ short nScroll = 0;
+
+ if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF )
+ {
+ pItem = mpItemList->GetObject( mpItemList->Count()-1 );
+ if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
+ nNewDropPos = (USHORT)mpItemList->Count();
+ else
+ {
+ nNewDropPos = mnFirstPos+1;
+ nScroll = 1;
+ }
+ }
+ else if ( (rPos.X() <= mnOffX) ||
+ (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) )
+ {
+ if ( mnFirstPos )
+ {
+ nNewDropPos = mnFirstPos;
+ nScroll = -1;
+ }
+ else
+ nNewDropPos = 0;
+ }
+ else
+ {
+ nDropId = GetPageId( rPos );
+ if ( nDropId )
+ {
+ nNewDropPos = GetPagePos( nDropId );
+ if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) )
+ nScroll = -1;
+ }
+ else
+ nNewDropPos = nItemCount;
+ }
+
+ if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll )
+ return mnDropPos;
+
+ if ( mbDropPos )
+ HideDropPos();
+ mbDropPos = TRUE;
+ mnDropPos = nNewDropPos;
+
+ if ( nScroll )
+ {
+ USHORT nOldFirstPos = mnFirstPos;
+ SetFirstPageId( GetPageId( mnFirstPos+nScroll ) );
+
+ // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
+ if ( nOldFirstPos != mnFirstPos )
+ {
+ Rectangle aRect( mnOffX, 0, mnLastOffX, maWinSize.Height() );
+ SetFillColor( GetBackground().GetColor() );
+ DrawRect( aRect );
+ Paint( aRect );
+ }
+ }
+
+ // Drop-Position-Pfeile ausgeben
+ Color aBlackColor( COL_BLACK );
+ long nX;
+ long nY = (maWinSize.Height()/2)-1;
+ USHORT nCurPos = GetPagePos( mnCurPageId );
+
+ SetLineColor( aBlackColor );
+ if ( mnDropPos < nItemCount )
+ {
+ pItem = mpItemList->GetObject( mnDropPos );
+ nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
+ if ( mnDropPos == nCurPos )
+ nX--;
+ else
+ nX++;
+ if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
+ SetLineColor( pItem->maTabTextColor );
+ DrawLine( Point( nX, nY ), Point( nX, nY ) );
+ DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) );
+ DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) );
+ SetLineColor( aBlackColor );
+ }
+ if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
+ {
+ pItem = mpItemList->GetObject( mnDropPos-1 );
+ nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
+ if ( mnDropPos == nCurPos )
+ nX++;
+ if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
+ SetLineColor( pItem->maTabTextColor );
+ DrawLine( Point( nX, nY ), Point( nX, nY ) );
+ DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) );
+ DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) );
+ }
+
+ return mnDropPos;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::HideDropPos()
+{
+ if ( mbDropPos )
+ {
+ ImplTabBarItem* pItem;
+ long nX;
+ long nY1 = (maWinSize.Height()/2)-3;
+ long nY2 = nY1 + 5;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+
+ if ( mnDropPos < nItemCount )
+ {
+ pItem = mpItemList->GetObject( mnDropPos );
+ nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
+ // Paint direkt aufrufen, da bei Drag and Drop kein Paint
+ // moeglich
+ Rectangle aRect( nX-1, nY1, nX+3, nY2 );
+ Region aRegion( aRect );
+ SetClipRegion( aRegion );
+ Paint( aRect );
+ SetClipRegion();
+ }
+ if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
+ {
+ pItem = mpItemList->GetObject( mnDropPos-1 );
+ nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
+ // Paint direkt aufrufen, da bei Drag and Drop kein Paint
+ // moeglich
+ Rectangle aRect( nX-2, nY1, nX+1, nY2 );
+ Region aRegion( aRect );
+ SetClipRegion( aRegion );
+ Paint( aRect );
+ SetClipRegion();
+ }
+
+ mbDropPos = FALSE;
+ mnDropPos = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::SwitchPage( const Point& rPos )
+{
+ BOOL bSwitch = FALSE;
+ USHORT nSwitchId = GetPageId( rPos );
+ if ( !nSwitchId )
+ EndSwitchPage();
+ else
+ {
+ if ( nSwitchId != mnSwitchId )
+ {
+ mnSwitchId = nSwitchId;
+ mnSwitchTime = Time::GetSystemTicks();
+ }
+ else
+ {
+ // Erst nach 500 ms umschalten
+ if ( mnSwitchId != GetCurPageId() )
+ {
+ if ( Time::GetSystemTicks() > mnSwitchTime+500 )
+ {
+ mbInSwitching = TRUE;
+ if ( ImplDeactivatePage() )
+ {
+ SetCurPageId( mnSwitchId );
+ Update();
+ ImplActivatePage();
+ ImplSelect();
+ bSwitch = TRUE;
+ }
+ mbInSwitching = FALSE;
+ }
+ }
+ }
+ }
+
+ return bSwitch;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EndSwitchPage()
+{
+ mnSwitchTime = 0;
+ mnSwitchId = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetStyle( WinBits nStyle )
+{
+ mnWinStyle = nStyle;
+ ImplInitControls();
+ // Evt. Controls neu anordnen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+Size TabBar::CalcWindowSizePixel() const
+{
+ long nWidth = 0;
+
+ if ( mpItemList->Count() )
+ {
+ ((TabBar*)this)->ImplCalcWidth();
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ nWidth += pItem->mnWidth;
+ pItem = mpItemList->Next();
+ }
+ nWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
+ }
+
+ return Size( nWidth, GetSettings().GetStyleSettings().GetScrollBarSize() );
+}
+// -----------------------------------------------------------------------
+
+Rectangle TabBar::GetPageArea() const
+{
+ return Rectangle( Point( mnOffX, mnOffY ), Size( mnLastOffX-mnOffX+1, GetSizePixel().Height()-mnOffY ) );
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabBar::CreateAccessible()
+{
+ return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar( *this );
+}
+
+// -----------------------------------------------------------------------
diff --git a/svtools/source/control/taskbar.cxx b/svtools/source/control/taskbar.cxx
new file mode 100644
index 000000000000..e84c934ef0d8
--- /dev/null
+++ b/svtools/source/control/taskbar.cxx
@@ -0,0 +1,594 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#include <tools/debug.hxx>
+
+#ifndef _VCL_FLOATWIN_HXX
+#include <vcl/floatwin.hxx>
+#endif
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+class ImplTaskBarFloat : public FloatingWindow
+{
+public:
+ TaskBar* mpTaskBar;
+
+public:
+ ImplTaskBarFloat( TaskBar* pTaskBar );
+};
+
+// -----------------------------------------------------------------------
+
+ImplTaskBarFloat::ImplTaskBarFloat( TaskBar* pTaskBar ) :
+ FloatingWindow( pTaskBar, 0 )
+{
+ mpTaskBar = pTaskBar;
+}
+
+// =======================================================================
+
+#define TASKBAR_BORDER 2
+#define TASKBAR_OFFSIZE 3
+#define TASKBAR_OFFX 2
+#define TASKBAR_OFFY 1
+#define TASKBAR_BUTTONOFF 5
+#define TASKBAR_AUTOHIDE_HEIGHT 2
+
+// =======================================================================
+
+TaskBar::TaskBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, WB_3DLOOK )
+{
+ mpButtonBar = NULL;
+ mpTaskToolBox = NULL;
+ mpStatusBar = NULL;
+ mnStatusWidth = 0;
+ mnOldStatusWidth = 0;
+ mnLines = 1;
+ mnWinBits = nWinStyle;
+ mbStatusText = FALSE;
+ mbShowItems = FALSE;
+ mbAutoHide = FALSE;
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+TaskBar::~TaskBar()
+{
+ if ( mpButtonBar )
+ delete mpButtonBar;
+ if ( mpTaskToolBox )
+ delete mpTaskToolBox;
+ if ( mpStatusBar )
+ delete mpStatusBar;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::ImplNewHeight( long nNewHeight )
+{
+ long nOldHeight = GetSizePixel().Height();
+ if ( nNewHeight != nOldHeight )
+ {
+ long nY = GetPosPixel().Y()-(nNewHeight-nOldHeight);
+ SetPosSizePixel( 0, nY, 0, nNewHeight,
+ WINDOW_POSSIZE_Y | WINDOW_POSSIZE_HEIGHT );
+ TaskResize();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::TaskResize()
+{
+ maTaskResizeHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+TaskButtonBar* TaskBar::CreateButtonBar()
+{
+ return new TaskButtonBar( this );
+}
+
+// -----------------------------------------------------------------------
+
+TaskToolBox* TaskBar::CreateTaskToolBox()
+{
+ return new TaskToolBox( this );
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusBar* TaskBar::CreateTaskStatusBar()
+{
+ return new TaskStatusBar( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( mnWinBits & WB_SIZEABLE )
+ {
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+
+ if ( pTempTaskToolBox && pTempStatusBar )
+ {
+ long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ long nMouseX = rMEvt.GetPosPixel().X();
+ PointerStyle ePtrStyle;
+ if ( (nMouseX >= nStatusX-1) && (nMouseX <= nStatusX+3) )
+ ePtrStyle = POINTER_HSIZEBAR;
+ else
+ ePtrStyle = POINTER_ARROW;
+ Pointer aPtr( ePtrStyle );
+ SetPointer( aPtr );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && (mnWinBits & WB_SIZEABLE) )
+ {
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+
+ if ( pTempTaskToolBox && pTempStatusBar )
+ {
+ long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ long nMouseX = rMEvt.GetPosPixel().X();
+ if ( (nMouseX >= nStatusX-1) && (nMouseX <= nStatusX+3) )
+ {
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ if ( mnStatusWidth )
+ {
+ mnStatusWidth = 0;
+ Resize();
+ }
+ }
+ else
+ {
+ StartTracking();
+ mnOldStatusWidth = mnStatusWidth;
+ mnMouseOff = nMouseX-nStatusX;
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ mnStatusWidth = mnOldStatusWidth;
+ Resize();
+ Update();
+ }
+ }
+ else
+ {
+ Size aSize = GetOutputSizePixel();
+
+ long nMouseX = rTEvt.GetMouseEvent().GetPosPixel().X()-mnMouseOff;
+ if ( nMouseX < 0 )
+ nMouseX = 0;
+ long nMaxX = aSize.Width()-TASKBAR_OFFX-TASKBAR_OFFSIZE-1;
+ if ( nMouseX > nMaxX )
+ nMouseX = nMaxX;
+ mnStatusWidth = aSize.Width()-nMouseX-TASKBAR_OFFX-TASKBAR_OFFSIZE;
+ Resize();
+ Update();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Paint( const Rectangle& rRect )
+{
+ if ( mnWinBits & (WB_BORDER | WB_SIZEABLE) )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Size aSize = GetOutputSizePixel();
+ long nY = 0;
+
+ if ( mnWinBits & WB_BORDER )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( 0, 0 ), Point( aSize.Width()-1, 0 ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( 0, 1 ), Point( aSize.Width()-1, 1 ) );
+ nY += 2;
+ }
+
+ if ( (mnWinBits & WB_SIZEABLE) )
+ {
+ //TaskButtonBar* pTempButtonBar = GetButtonBar();
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+
+ if ( pTempTaskToolBox && pTempStatusBar )
+ {
+ long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ if ( nStatusX > 0 )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( nStatusX, nY ), Point( nStatusX, aSize.Height()-1 ) );
+ nStatusX++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( nStatusX, nY ), Point( nStatusX, aSize.Height()-1 ) );
+ }
+ }
+ }
+ }
+
+ Window::Paint( rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Resize()
+{
+ if ( !IsReallyShown() )
+ return;
+
+ TaskButtonBar* pTempButtonBar = GetButtonBar();
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+ Point aToolPos( TASKBAR_OFFX, 0 );
+ Size aSize = GetOutputSizePixel();
+ Size aStatusSize;
+ Size aToolSize( aSize.Width()-(TASKBAR_OFFX*2), 0 );
+ long nOldStatusX = -1;
+ long nNewStatusX = -1;
+ long nTaskHeight = aSize.Height() - (TASKBAR_OFFY*2);
+
+ if ( mnWinBits & WB_BORDER )
+ {
+ nTaskHeight -= TASKBAR_BORDER;
+ aToolPos.Y() += TASKBAR_BORDER;
+ }
+
+ if ( pTempButtonBar )
+ {
+ USHORT i = 0;
+ BOOL bVisibleItems = FALSE;
+ while ( i < pTempButtonBar->GetItemCount() )
+ {
+ if ( pTempButtonBar->IsItemVisible( pTempButtonBar->GetItemId( i ) ) )
+ {
+ bVisibleItems = TRUE;
+ break;
+ }
+ i++;
+ }
+ if ( mbStatusText || !bVisibleItems )
+ pTempButtonBar->Hide();
+ else
+ {
+ Size aButtonBarSize = pTempButtonBar->CalcWindowSizePixel();
+ if ( pTempButtonBar->GetItemCount() )
+ nTaskHeight = aButtonBarSize.Height();
+ else
+ aButtonBarSize.Height() = nTaskHeight;
+ Point aTempPos = aToolPos;
+ aTempPos.Y() += (aSize.Height()-aButtonBarSize.Height()-aTempPos.Y())/2;
+ pTempButtonBar->SetPosSizePixel( aTempPos, aButtonBarSize );
+ pTempButtonBar->Show();
+ aToolPos.X() += aButtonBarSize.Width()+TASKBAR_BUTTONOFF;
+ }
+ }
+
+ if ( pTempStatusBar )
+ {
+ aStatusSize = pTempStatusBar->CalcWindowSizePixel();
+ if ( mnStatusWidth )
+ aStatusSize.Width() = mnStatusWidth;
+ if ( !pTempTaskToolBox || mbStatusText )
+ aStatusSize.Width() = aSize.Width();
+ long nMaxHeight = aSize.Height()-(TASKBAR_OFFY*2);
+ if ( mnWinBits & WB_BORDER )
+ nMaxHeight -= TASKBAR_BORDER;
+ if ( nMaxHeight+2 > aStatusSize.Height() )
+ aStatusSize.Height() = nMaxHeight;
+ Point aPos( aSize.Width()-aStatusSize.Width(), 0 );
+ if ( pTempTaskToolBox && (mnWinBits & WB_SIZEABLE) && !mbStatusText )
+ {
+ long nMinToolWidth = aToolPos.X()+50;
+ if ( aPos.X() < nMinToolWidth )
+ {
+ aStatusSize.Width() -= nMinToolWidth-aPos.X();
+ aPos.X() = nMinToolWidth;
+ }
+ }
+ if ( aPos.X() < 0 )
+ {
+ aStatusSize.Width() = aSize.Width();
+ aPos.X() = 0;
+ }
+ if ( mnWinBits & WB_BORDER )
+ aPos.Y() += TASKBAR_BORDER;
+ aPos.Y() += (aSize.Height()-aStatusSize.Height()-aPos.Y())/2;
+ if ( mnWinBits & WB_SIZEABLE )
+ {
+ if ( pTempTaskToolBox )
+ {
+ nOldStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ nNewStatusX = aPos.X()-TASKBAR_OFFSIZE-2;
+ }
+ }
+ pTempStatusBar->SetPosSizePixel( aPos, aStatusSize );
+ pTempStatusBar->Show();
+ aToolSize.Width() = aPos.X()-aToolPos.X()-TASKBAR_OFFX;
+ if ( mnWinBits & WB_SIZEABLE )
+ aToolSize.Width() -= (TASKBAR_OFFSIZE*2)-2;
+ }
+
+ if ( pTempTaskToolBox )
+ {
+ if ( aToolSize.Width() <= 24 )
+ pTempTaskToolBox->Hide();
+ else
+ {
+ aToolSize.Height() = pTempTaskToolBox->CalcWindowSizePixel().Height();
+ if ( pTempTaskToolBox->GetItemCount() )
+ nTaskHeight = aToolSize.Height();
+ else
+ aToolSize.Height() = nTaskHeight;
+ aToolPos.Y() += (aSize.Height()-aToolSize.Height()-aToolPos.Y())/2;
+ pTempTaskToolBox->SetPosSizePixel( aToolPos, aToolSize );
+ pTempTaskToolBox->Show();
+ }
+ }
+
+ if ( nOldStatusX != nNewStatusX )
+ {
+ if ( nOldStatusX > 0 )
+ {
+ Rectangle aRect( nOldStatusX, 0, nOldStatusX+2, aSize.Height()-1 );
+ Invalidate( aRect );
+ }
+ if ( nNewStatusX > 0 )
+ {
+ Rectangle aRect( nNewStatusX, 0, nNewStatusX+2, aSize.Height()-1 );
+ Invalidate( aRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ Format();
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_FORMAT )
+ {
+ ImplInitSettings();
+ ImplNewHeight( CalcWindowSizePixel().Height() );
+ Format();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ // Asyncronen StateChanged ausloesen, damit sich die
+ // TaskBar an die neuen Groessen der Child-Fenster
+ // orientieren kann
+ PostStateChanged( STATE_CHANGE_FORMAT );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Format()
+{
+ ImplNewHeight( CalcWindowSizePixel().Height() );
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::SetLines( USHORT nLines )
+{
+ mnLines = nLines;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::EnableAutoHide( BOOL bAutoHide )
+{
+ mbAutoHide = bAutoHide;
+
+ if ( mbAutoHide )
+ {
+ ImplNewHeight( TASKBAR_AUTOHIDE_HEIGHT );
+ }
+ else
+ {
+ ImplNewHeight( CalcWindowSizePixel().Height() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::ShowStatusText( const String& rText )
+{
+ if ( mpStatusBar )
+ {
+ if ( !mbStatusText )
+ {
+ mbStatusText = TRUE;
+ if ( mpStatusBar->AreItemsVisible() )
+ {
+ mbShowItems = TRUE;
+ mpStatusBar->HideItems();
+ }
+ else
+ mbShowItems = TRUE;
+ maOldText = mpStatusBar->GetText();
+ Resize();
+ mpStatusBar->SetText( rText );
+ Update();
+ mpStatusBar->Update();
+ }
+ else
+ mpStatusBar->SetText( rText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::HideStatusText()
+{
+ if ( mbStatusText && mpStatusBar )
+ {
+ mbStatusText = FALSE;
+ mpStatusBar->SetText( maOldText );
+ Resize();
+ if ( mbShowItems )
+ mpStatusBar->ShowItems();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size TaskBar::CalcWindowSizePixel() const
+{
+ TaskButtonBar* pTempButtonBar = GetButtonBar();
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+ Size aSize;
+ long nTempHeight;
+
+ if ( pTempButtonBar && pTempButtonBar->GetItemCount() )
+ aSize.Height() = pTempButtonBar->CalcWindowSizePixel().Height()+(TASKBAR_OFFY*2);
+ if ( pTempTaskToolBox && pTempTaskToolBox->GetItemCount() )
+ {
+ nTempHeight = pTempTaskToolBox->CalcWindowSizePixel().Height()+(TASKBAR_OFFY*2);
+ if ( nTempHeight > aSize.Height() )
+ aSize.Height() = nTempHeight;
+ }
+ if ( pTempStatusBar )
+ {
+ nTempHeight = pTempStatusBar->GetSizePixel().Height();
+ if ( nTempHeight > aSize.Height() )
+ aSize.Height() = nTempHeight;
+ }
+
+ if ( mnWinBits & WB_BORDER )
+ aSize.Height() += TASKBAR_BORDER;
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+TaskButtonBar* TaskBar::GetButtonBar() const
+{
+ if ( !mpButtonBar )
+ ((TaskBar*)this)->mpButtonBar = ((TaskBar*)this)->CreateButtonBar();
+ return mpButtonBar;
+}
+
+// -----------------------------------------------------------------------
+
+TaskToolBox* TaskBar::GetTaskToolBox() const
+{
+ if ( !mpTaskToolBox )
+ ((TaskBar*)this)->mpTaskToolBox = ((TaskBar*)this)->CreateTaskToolBox();
+ return mpTaskToolBox;
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusBar* TaskBar::GetStatusBar() const
+{
+ if ( !mpStatusBar )
+ {
+ ((TaskBar*)this)->mpStatusBar = ((TaskBar*)this)->CreateTaskStatusBar();
+ if ( mpStatusBar )
+ mpStatusBar->mpNotifyTaskBar = (TaskBar*)this;
+ }
+ return mpStatusBar;
+}
diff --git a/svtools/source/control/taskbox.cxx b/svtools/source/control/taskbox.cxx
new file mode 100644
index 000000000000..8e5ff6de8def
--- /dev/null
+++ b/svtools/source/control/taskbox.cxx
@@ -0,0 +1,352 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <vcl/image.hxx>
+#include <vcl/help.hxx>
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+#define TASKBOX_TASKOFF 3
+
+// =======================================================================
+
+struct ImplTaskItem
+{
+ Image maImage;
+ XubString maText;
+};
+
+DECLARE_LIST( ImplTaskItemList, ImplTaskItem* )
+
+// =======================================================================
+
+TaskToolBox::TaskToolBox( Window* pParent, WinBits nWinStyle ) :
+ ToolBox( pParent, nWinStyle | WB_SCROLL | WB_3DLOOK )
+{
+ mpItemList = new ImplTaskItemList;
+ mnMaxTextWidth = 0;
+ mnActiveItemId = 0;
+ mnTaskItem = 0;
+ mnSmallItem = TOOLBOX_ITEM_NOTFOUND;
+ mbMinActivate = FALSE;
+
+ SetAlign( WINDOWALIGN_BOTTOM );
+ SetButtonType( BUTTON_SYMBOLTEXT );
+}
+
+// -----------------------------------------------------------------------
+
+TaskToolBox::~TaskToolBox()
+{
+ ImplTaskItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ActivateTaskItem( USHORT nItemId, BOOL bMinActivate )
+{
+ if ( nItemId )
+ {
+ if ( nItemId != mnActiveItemId )
+ {
+ if ( mnActiveItemId )
+ CheckItem( mnActiveItemId, FALSE );
+ CheckItem( nItemId );
+ mnActiveItemId = nItemId;
+ }
+ else
+ {
+ if ( !bMinActivate )
+ return;
+
+ mbMinActivate = TRUE;
+ }
+
+ mnTaskItem = nItemId-1;
+ ActivateTask();
+ mnTaskItem = 0;
+ mbMinActivate = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ActivateTask()
+{
+ maActivateTaskHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ContextMenu()
+{
+ maContextMenuHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsRight() )
+ ToolBox::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::Resize()
+{
+ mnOldItemCount = mpItemList->Count();
+ mnUpdatePos = (USHORT)mnOldItemCount;
+ mnUpdateNewPos = TOOLBOX_ITEM_NOTFOUND;
+ ImplFormatTaskToolBox();
+ ToolBox::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ USHORT nItemId = GetItemId( rCEvt.GetMousePosPixel() );
+// Dies machen wir nicht mehr, da es von zu vielen als stoerend empfunden wurde
+// ActivateTaskItem( nItemId );
+ mnTaskItem = nItemId-1;
+
+ maContextMenuPos = rCEvt.GetMousePosPixel();
+ ContextMenu();
+ maContextMenuPos = Point();
+ mnTaskItem = 0;
+ }
+ else
+ ToolBox::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ USHORT nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+
+ if ( nItemId )
+ {
+ ImplTaskItem* pItem = mpItemList->GetObject( nItemId-1 );
+ if ( pItem )
+ {
+ if ( pItem->maText != GetItemText( nItemId ) )
+ {
+ Rectangle aItemRect = GetItemRect( nItemId );
+ if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ Help::ShowQuickHelp( this, aItemRect, pItem->maText );
+ else
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, pItem->maText );
+ }
+ else
+ Help::ShowQuickHelp( this, Rectangle(), String() );
+ return;
+ }
+ }
+ }
+
+ ToolBox::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::Select()
+{
+ USHORT nItemId = GetCurItemId();
+ ActivateTaskItem( nItemId, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ImplFormatTaskToolBox()
+{
+ if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
+ {
+ // Eintraege aus der Liste entfernen
+ while ( mpItemList->Count() > mnUpdatePos )
+ delete mpItemList->Remove( (ULONG)mnUpdatePos );
+ mnUpdateNewPos = mnUpdatePos;
+ }
+
+ // Maximale Itemgroesse berechnen
+ long nOldMaxTextWidth = mnMaxTextWidth;
+ mnMaxTextWidth = 70;
+ if ( mpItemList->Count() )
+ {
+ long nWinSize = GetOutputSizePixel().Width()-8;
+ long nItemSize = mpItemList->GetObject(0)->maImage.GetSizePixel().Width()+7+TASKBOX_TASKOFF+2;
+ nWinSize -= mpItemList->Count()*nItemSize;
+ if ( nWinSize > 0 )
+ nWinSize /= mpItemList->Count();
+ else
+ nWinSize = 0;
+ if ( nWinSize < mnMaxTextWidth )
+ mnMaxTextWidth = nWinSize;
+ if ( (mnMaxTextWidth < nOldMaxTextWidth) ||
+ ((mnMaxTextWidth-nOldMaxTextWidth > 3) &&
+ (mnSmallItem != TOOLBOX_ITEM_NOTFOUND)) )
+ {
+ mnSmallItem = TOOLBOX_ITEM_NOTFOUND;
+ mnUpdateNewPos = 0;
+ }
+ }
+
+ // Eintraege aus der ToolBox entfernen, die ersetzt werden
+ USHORT nBtnPos = (mnUpdateNewPos*2);
+ while ( nBtnPos < GetItemCount() )
+ RemoveItem( nBtnPos );
+ if ( mnUpdateNewPos <= (mnActiveItemId-1) )
+ mnActiveItemId = 0;
+
+ // Neue Eintrage einfuegen
+ USHORT i = mnUpdateNewPos;
+ while ( i < mpItemList->Count() )
+ {
+ ImplTaskItem* pItem = mpItemList->GetObject( i );
+
+ // Textlaenge berechnen
+ XubString aText = pItem->maText;
+ if ( !aText.Len() )
+ aText = ' ';
+ long nTxtWidth = GetTextWidth( aText );
+ if ( nTxtWidth > mnMaxTextWidth )
+ {
+ if ( mnSmallItem == TOOLBOX_ITEM_NOTFOUND )
+ mnSmallItem = i;
+ // 3 == Len of "..."
+ aText.AppendAscii( "..." );
+ do
+ {
+ aText.Erase( aText.Len()-3-1, 1 );
+ nTxtWidth = GetTextWidth( aText );
+ }
+ while ( (nTxtWidth > mnMaxTextWidth) && (aText.Len() > 3) );
+ }
+
+ USHORT nItemId = i+1;
+ if ( aText.EqualsAscii( "..." ) )
+ InsertItem( nItemId, pItem->maImage, TIB_LEFT );
+ else
+ InsertItem( nItemId, pItem->maImage, aText, TIB_LEFT );
+ InsertSeparator( TOOLBOX_APPEND, TASKBOX_TASKOFF );
+ i++;
+ }
+
+ if ( mnUpdateNewPos != 0 )
+ mnMaxTextWidth = nOldMaxTextWidth;
+
+ if ( mnNewActivePos+1 != mnActiveItemId )
+ {
+ if ( mnActiveItemId )
+ CheckItem( mnActiveItemId, FALSE );
+ mnActiveItemId = mnNewActivePos+1;
+ CheckItem( mnActiveItemId );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::StartUpdateTask()
+{
+ mnOldItemCount = mpItemList->Count();
+ mnUpdatePos = 0;
+ mnUpdateNewPos = TOOLBOX_ITEM_NOTFOUND;
+ mnNewActivePos = 0xFFFE;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::UpdateTask( const Image& rImage, const String& rText,
+ BOOL bActive )
+{
+ ImplTaskItem* pItem = mpItemList->GetObject( mnUpdatePos );
+ if ( pItem )
+ {
+ if ( (pItem->maText != rText) || (pItem->maImage != rImage) )
+ {
+ // Eintraege aus der Liste entfernen
+ while ( mpItemList->Count() > mnUpdatePos )
+ delete mpItemList->Remove( (ULONG)mnUpdatePos );
+ pItem = NULL;
+ }
+ }
+
+ if ( !pItem )
+ {
+ if ( mnUpdatePos < mnUpdateNewPos )
+ mnUpdateNewPos = mnUpdatePos;
+
+ pItem = new ImplTaskItem;
+ pItem->maImage = rImage;
+ pItem->maText = rText;
+ mpItemList->Insert( pItem, LIST_APPEND );
+ }
+
+ if ( bActive )
+ mnNewActivePos = mnUpdatePos;
+
+ mnUpdatePos++;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::EndUpdateTask()
+{
+ if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
+ {
+ // Eintraege aus der Liste entfernen
+ while ( mpItemList->Count() > mnUpdatePos )
+ delete mpItemList->Remove( (ULONG)mnUpdatePos );
+ mnUpdateNewPos = mnUpdatePos;
+ }
+
+ ImplFormatTaskToolBox();
+}
+
diff --git a/svtools/source/control/taskmisc.cxx b/svtools/source/control/taskmisc.cxx
new file mode 100644
index 000000000000..4c9fda217258
--- /dev/null
+++ b/svtools/source/control/taskmisc.cxx
@@ -0,0 +1,380 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <vcl/help.hxx>
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+TaskButtonBar::TaskButtonBar( Window* pParent, WinBits nWinStyle ) :
+ ToolBox( pParent, nWinStyle | WB_3DLOOK )
+{
+ SetAlign( WINDOWALIGN_BOTTOM );
+ SetButtonType( BUTTON_SYMBOLTEXT );
+}
+
+// -----------------------------------------------------------------------
+
+TaskButtonBar::~TaskButtonBar()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void TaskButtonBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ ToolBox::RequestHelp( rHEvt );
+}
+
+// =======================================================================
+
+WindowArrange::WindowArrange()
+{
+ mpWinList = new List;
+}
+
+// -----------------------------------------------------------------------
+
+WindowArrange::~WindowArrange()
+{
+ delete mpWinList;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplCeilSqareRoot( USHORT nVal )
+{
+ USHORT i;
+
+ // Ueberlauf verhindern
+ if ( nVal > 0xFE * 0xFE )
+ return 0xFE;
+
+ for ( i=0; i*i < nVal; i++ )
+ {}
+
+ return i;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplPosSizeWindow( Window* pWindow,
+ long nX, long nY, long nWidth, long nHeight )
+{
+ if ( nWidth < 32 )
+ nWidth = 32;
+ if ( nHeight < 24 )
+ nHeight = 24;
+ pWindow->SetPosSizePixel( nX, nY, nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplTile( const Rectangle& rRect )
+{
+ USHORT nCount = (USHORT)mpWinList->Count();
+ if ( nCount < 3 )
+ {
+ ImplVert( rRect );
+ return;
+ }
+
+ USHORT i;
+ USHORT j;
+ USHORT nCols;
+ USHORT nRows;
+ USHORT nActRows;
+ USHORT nOffset;
+ long nOverWidth;
+ long nOverHeight;
+ Window* pWindow;
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectY = nY;
+ long nRectWidth = nWidth;
+ long nRectHeight = nHeight;
+ long nTempWidth;
+ long nTempHeight;
+
+ nCols = ImplCeilSqareRoot( nCount );
+ nOffset = (nCols*nCols) - nCount;
+ if ( nOffset >= nCols )
+ {
+ nRows = nCols -1;
+ nOffset = nOffset - nCols;
+ }
+ else
+ nRows = nCols;
+
+ nWidth /= nCols;
+ if ( nWidth < 1 )
+ nWidth = 1;
+ nOverWidth = nRectWidth-(nWidth*nCols);
+
+ pWindow = (Window*)mpWinList->First();
+ for ( i = 0; i < nCols; i++ )
+ {
+ if ( i < nOffset )
+ nActRows = nRows - 1;
+ else
+ nActRows = nRows;
+
+ nTempWidth = nWidth;
+ if ( nOverWidth > 0 )
+ {
+ nTempWidth++;
+ nOverWidth--;
+ }
+
+ nHeight = nRectHeight / nActRows;
+ if ( nHeight < 1 )
+ nHeight = 1;
+ nOverHeight = nRectHeight-(nHeight*nActRows);
+ for ( j = 0; j < nActRows; j++ )
+ {
+ // Ueberhang verteilen
+ nTempHeight = nHeight;
+ if ( nOverHeight > 0 )
+ {
+ nTempHeight++;
+ nOverHeight--;
+ }
+ ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nTempHeight );
+ nY += nTempHeight;
+
+ pWindow = (Window*)mpWinList->Next();
+ if ( !pWindow )
+ break;
+ }
+
+ nX += nWidth;
+ nY = nRectY;
+
+ if ( !pWindow )
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplHorz( const Rectangle& rRect )
+{
+ long nCount = (long)mpWinList->Count();
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectHeight = nHeight;
+ long nOver;
+ long nTempHeight;
+ Window* pWindow;
+
+ nHeight /= nCount;
+ if ( nHeight < 1 )
+ nHeight = 1;
+ nOver = nRectHeight - (nCount*nHeight);
+ pWindow = (Window*)mpWinList->First();
+ while ( pWindow )
+ {
+ nTempHeight = nHeight;
+ if ( nOver > 0 )
+ {
+ nTempHeight++;
+ nOver--;
+ }
+ ImplPosSizeWindow( pWindow, nX, nY, nWidth, nTempHeight );
+ nY += nTempHeight;
+
+ pWindow = (Window*)mpWinList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplVert( const Rectangle& rRect )
+{
+ long nCount = (long)mpWinList->Count();
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectWidth = nWidth;
+ long nOver;
+ long nTempWidth;
+ Window* pWindow;
+
+ nWidth /= nCount;
+ if ( nWidth < 1 )
+ nWidth = 1;
+ nOver = nRectWidth - (nCount*nWidth);
+ pWindow = (Window*)mpWinList->First();
+ while ( pWindow )
+ {
+ nTempWidth = nWidth;
+ if ( nOver > 0 )
+ {
+ nTempWidth++;
+ nOver--;
+ }
+ ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nHeight );
+ nX += nTempWidth;
+
+ pWindow = (Window*)mpWinList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplCascade( const Rectangle& rRect )
+{
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectWidth = nWidth;
+ long nRectHeight = nHeight;
+ long nOff;
+ long nCascadeWins;
+ sal_Int32 nLeftBorder;
+ sal_Int32 nTopBorder;
+ sal_Int32 nRightBorder;
+ sal_Int32 nBottomBorder;
+ long nStartOverWidth;
+ long nStartOverHeight;
+ long nOverWidth = 0;
+ long nOverHeight = 0;
+ long nTempX;
+ long nTempY;
+ long nTempWidth;
+ long nTempHeight;
+ long i;
+ Window* pWindow;
+ Window* pTempWindow;
+
+ // Border-Fenster suchen um den Versatz zu ermitteln
+ pTempWindow = (Window*)mpWinList->First();
+ pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ while ( !nTopBorder )
+ {
+ Window* pBrdWin = pTempWindow->GetWindow( WINDOW_REALPARENT );
+ if ( !pBrdWin || (pBrdWin->GetWindow( WINDOW_CLIENT ) != pTempWindow) )
+ break;
+ pTempWindow = pBrdWin;
+ pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ }
+ if ( !nTopBorder )
+ nTopBorder = 22;
+ nOff = nTopBorder;
+
+ nCascadeWins = nRectHeight / 3 / nOff;
+ if ( !nCascadeWins )
+ nCascadeWins = 1;
+ nWidth -= nCascadeWins*nOff;
+ nHeight -= nCascadeWins*nOff;
+ if ( nWidth < 1 )
+ nWidth = 1;
+ if ( nHeight < 1 )
+ nHeight = 1;
+
+ nStartOverWidth = nRectWidth-(nWidth+(nCascadeWins*nOff));
+ nStartOverHeight = nRectHeight-(nHeight+(nCascadeWins*nOff));
+
+ i = 0;
+ pWindow = (Window*)mpWinList->First();
+ while ( pWindow )
+ {
+ if ( !i )
+ {
+ nOverWidth = nStartOverWidth;
+ nOverHeight = nStartOverHeight;
+ }
+
+ // Position
+ nTempX = nX + (i*nOff);
+ nTempY = nY + (i*nOff);
+
+ // Ueberhang verteilen
+ nTempWidth = nWidth;
+ if ( nOverWidth > 0 )
+ {
+ nTempWidth++;
+ nOverWidth--;
+ }
+ nTempHeight = nHeight;
+ if ( nOverHeight > 0 )
+ {
+ nTempHeight++;
+ nOverHeight--;
+ }
+
+ ImplPosSizeWindow( pWindow, nTempX, nTempY, nTempWidth, nTempHeight );
+
+ if ( i < nCascadeWins )
+ i++;
+ else
+ i = 0;
+
+ pWindow = (Window*)mpWinList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::Arrange( USHORT nType, const Rectangle& rRect )
+{
+ if ( !mpWinList->Count() )
+ return;
+
+ switch ( nType )
+ {
+ case WINDOWARRANGE_TILE:
+ ImplTile( rRect );
+ break;
+ case WINDOWARRANGE_HORZ:
+ ImplHorz( rRect );
+ break;
+ case WINDOWARRANGE_VERT:
+ ImplVert( rRect );
+ break;
+ case WINDOWARRANGE_CASCADE:
+ ImplCascade( rRect );
+ break;
+ }
+}
+
diff --git a/svtools/source/control/taskstat.cxx b/svtools/source/control/taskstat.cxx
new file mode 100644
index 000000000000..2fdab63be37f
--- /dev/null
+++ b/svtools/source/control/taskstat.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_svtools.hxx"
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <tools/date.hxx>
+#include <vcl/image.hxx>
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/calendarwrapper.hxx>
+
+#include <unotools/syslocale.hxx>
+#include <taskbar.hxx>
+
+// =======================================================================
+
+#define TASKSTATUSBAR_CLOCXOFFX 3
+#define TASKSTATUSBAR_IMAGEOFFX 1
+
+// =======================================================================
+
+struct ImplTaskSBFldItem
+{
+ TaskStatusFieldItem maItem;
+ USHORT mnId;
+ long mnOffX;
+};
+
+DECLARE_LIST( ImplTaskSBItemList, ImplTaskSBFldItem* )
+
+// =======================================================================
+
+BOOL ITaskStatusNotify::MouseButtonDown( USHORT, const MouseEvent& )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::MouseButtonUp( USHORT, const MouseEvent& )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::MouseMove( USHORT, const MouseEvent& )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::Command( USHORT, const CommandEvent& )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::UpdateHelp( USHORT )
+{
+ return FALSE;
+}
+
+// =======================================================================
+
+TaskStatusFieldItem::TaskStatusFieldItem()
+{
+ mpNotify = NULL;
+ mnFlags = 0;
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusFieldItem::TaskStatusFieldItem( const TaskStatusFieldItem& rItem ) :
+ mpNotify( rItem.mpNotify ),
+ maImage( rItem.maImage ),
+ maQuickHelpText( rItem.maQuickHelpText ),
+ maHelpText( rItem.maHelpText ),
+ mnFlags( rItem.mnFlags )
+{
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusFieldItem::TaskStatusFieldItem( ITaskStatusNotify* pNotify,
+ const Image& rImage,
+ const XubString& rQuickHelpText,
+ const XubString& rHelpText,
+ USHORT nFlags ) :
+ mpNotify( pNotify ),
+ maImage( rImage ),
+ maQuickHelpText( rQuickHelpText ),
+ maHelpText( rHelpText ),
+ mnFlags( nFlags )
+{
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusFieldItem::~TaskStatusFieldItem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+const TaskStatusFieldItem& TaskStatusFieldItem::operator=( const TaskStatusFieldItem& rItem )
+{
+ mpNotify = rItem.mpNotify;
+ maImage = rItem.maImage;
+ maQuickHelpText = rItem.maQuickHelpText;
+ maHelpText = rItem.maHelpText;
+ mnFlags = rItem.mnFlags;
+ return *this;
+}
+
+// =======================================================================
+
+TaskStatusBar::TaskStatusBar( Window* pParent, WinBits nWinStyle ) :
+ StatusBar( pParent, nWinStyle | WB_3DLOOK ),
+ maTime( 0, 0, 0 )
+{
+ mpFieldItemList = NULL;
+ mpNotifyTaskBar = NULL;
+ mpNotify = NULL;
+ mnClockWidth = 0;
+ mnItemWidth = 0;
+ mnFieldWidth = 0;
+ mnFieldFlags = 0;
+ mbFlashItems = FALSE;
+ mbOutInterval = FALSE;
+
+ maTimer.SetTimeoutHdl( LINK( this, TaskStatusBar, ImplTimerHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusBar::~TaskStatusBar()
+{
+ if ( mpFieldItemList )
+ {
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpFieldItemList->Next();
+ }
+
+ delete mpFieldItemList;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TaskStatusBar, ImplTimerHdl, Timer*, EMPTYARG )
+{
+ BOOL bUpdate = ImplUpdateClock();
+ if ( ImplUpdateFlashItems() )
+ bUpdate = TRUE;
+ if ( bUpdate )
+ SetItemData( TASKSTATUSBAR_STATUSFIELDID, NULL );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplTaskSBFldItem* TaskStatusBar::ImplGetFieldItem( USHORT nItemId ) const
+{
+ if ( !mpFieldItemList )
+ return NULL;
+
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return pItem;
+
+ pItem = mpFieldItemList->Next();
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplTaskSBFldItem* TaskStatusBar::ImplGetFieldItem( const Point& rPos, BOOL& rFieldRect ) const
+{
+ if ( GetItemId( rPos ) == TASKSTATUSBAR_STATUSFIELDID )
+ {
+ rFieldRect = TRUE;
+
+ if ( mpFieldItemList )
+ {
+ long nX = rPos.X()-GetItemRect( TASKSTATUSBAR_STATUSFIELDID ).Left();
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ if ( nX < pItem->mnOffX+pItem->maItem.GetImage().GetSizePixel().Width() )
+ return pItem;
+
+ pItem = mpFieldItemList->Next();
+ }
+ }
+ }
+ else
+ rFieldRect = FALSE;
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::ImplUpdateClock()
+{
+ if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
+ {
+ Time aTime;
+ maTimer.SetTimeout( ((long)60000)-((aTime.GetSec()*1000)+(aTime.Get100Sec()*10)) );
+ if ( (aTime.GetMin() != maTime.GetMin()) ||
+ (aTime.GetHour() != maTime.GetHour()) )
+ {
+ maTime = aTime;
+ maTimeText = SvtSysLocale().GetLocaleData().getTime( aTime, FALSE, FALSE );
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::ImplUpdateFlashItems()
+{
+ if ( mbFlashItems )
+ {
+ if ( mbOutInterval )
+ {
+ maTimer.SetTimeout( 900 );
+ mbOutInterval = FALSE;
+ }
+ else
+ {
+ maTimer.SetTimeout( 700 );
+ mbOutInterval = TRUE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::ImplUpdateField( BOOL bItems )
+{
+ maTimer.Stop();
+
+ if ( bItems )
+ {
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ mnItemWidth = 0;
+ mbFlashItems = FALSE;
+ mbOutInterval = FALSE;
+ while ( pItem )
+ {
+ mnItemWidth += TASKSTATUSBAR_IMAGEOFFX;
+ pItem->mnOffX = mnItemWidth;
+ mnItemWidth += pItem->maItem.GetImage().GetSizePixel().Width();
+ if ( pItem->maItem.GetFlags() & TASKSTATUSFIELDITEM_FLASH )
+ mbFlashItems = TRUE;
+
+ pItem = mpFieldItemList->Next();
+ }
+ }
+ else
+ {
+ if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
+ {
+ XubString aStr = SvtSysLocale().GetLocaleData().getTime( Time( 23, 59, 59 ), FALSE, FALSE );
+ mnClockWidth = GetTextWidth( aStr )+(TASKSTATUSBAR_CLOCXOFFX*2);
+ }
+ else
+ mnClockWidth = 0;
+ }
+
+ long nNewWidth = mnItemWidth+mnClockWidth;
+ if ( mnItemWidth && !mnClockWidth )
+ nNewWidth += TASKSTATUSBAR_IMAGEOFFX;
+ if ( nNewWidth != mnFieldWidth )
+ {
+ RemoveItem( TASKSTATUSBAR_STATUSFIELDID );
+
+ if ( mnItemWidth || mnClockWidth )
+ {
+ mnFieldWidth = nNewWidth;
+ long nOffset = GetItemOffset( TASKSTATUSBAR_STATUSFIELDID );
+ USHORT nItemPos = GetItemPos( TASKSTATUSBAR_STATUSFIELDID );
+ InsertItem( TASKSTATUSBAR_STATUSFIELDID, nNewWidth, SIB_RIGHT | SIB_IN | SIB_USERDRAW, nOffset, nItemPos );
+ }
+ else
+ mnFieldWidth = 0;
+
+ if ( mpNotifyTaskBar )
+ mpNotifyTaskBar->Resize();
+ }
+ else
+ SetItemData( TASKSTATUSBAR_STATUSFIELDID, NULL );
+
+ if ( mbFlashItems || (mnFieldFlags & TASKSTATUSFIELD_CLOCK) )
+ {
+ ImplUpdateClock();
+ mbOutInterval = TRUE;
+ ImplUpdateFlashItems();
+ maTimer.Start();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->MouseButtonDown( nItemId, rMEvt );
+
+ if ( bBaseClass )
+ StatusBar::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->MouseButtonUp( nItemId, rMEvt );
+
+ if ( bBaseClass )
+ StatusBar::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::MouseMove( const MouseEvent& rMEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->MouseMove( nItemId, rMEvt );
+
+ if ( bBaseClass )
+ StatusBar::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::Command( const CommandEvent& rCEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rCEvt.GetMousePosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->Command( nItemId, rCEvt );
+
+ if ( bBaseClass )
+ StatusBar::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ BOOL bFieldRect;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), bFieldRect );
+ if ( bFieldRect )
+ {
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ pNotify->UpdateHelp( nItemId );
+
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ Rectangle aItemRect = GetItemRect( TASKSTATUSBAR_STATUSFIELDID );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ if ( pItem )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ XubString aStr = pItem->maItem.GetHelpText();
+ if ( !aStr.Len() )
+ aStr = pItem->maItem.GetQuickHelpText();
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ }
+ else
+ Help::ShowQuickHelp( this, aItemRect, pItem->maItem.GetQuickHelpText() );
+ }
+ else
+ {
+ SvtSysLocale aSL;
+ const LocaleDataWrapper& rLDW = aSL.GetLocaleData();
+ CalendarWrapper aCal( rLDW.getServiceFactory());
+ aCal.loadDefaultCalendar( rLDW.getLoadedLocale());
+ XubString aStr = rLDW.getLongDate( Date(), aCal );
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ }
+ return;
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ if ( pItem )
+ {
+ ULONG nHelpId = pItem->maItem.GetHelpId();
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId, this );
+ return;
+ }
+ }
+ }
+ }
+
+ StatusBar::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ if ( rUDEvt.GetItemId() == TASKSTATUSBAR_STATUSFIELDID )
+ {
+ OutputDevice* pDev = rUDEvt.GetDevice();
+ Rectangle aRect = rUDEvt.GetRect();
+
+ if ( mpFieldItemList )
+ {
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ if ( !mbOutInterval || !(pItem->maItem.GetFlags() & TASKSTATUSFIELDITEM_FLASH) )
+ {
+ const Image& rImage = pItem->maItem.GetImage();
+ Size aImgSize = rImage.GetSizePixel();
+ pDev->DrawImage( Point( aRect.Left()+pItem->mnOffX,
+ aRect.Top()+((aRect.GetHeight()-aImgSize.Width())/2) ),
+ rImage );
+ }
+
+ pItem = mpFieldItemList->Next();
+ }
+ }
+
+ if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
+ {
+ long nX = mnItemWidth+TASKSTATUSBAR_CLOCXOFFX;
+ Point aPos = GetItemTextPos( TASKSTATUSBAR_STATUSFIELDID );
+ aPos.X() = aRect.Left()+nX;
+ pDev->DrawText( aPos, maTimeText );
+ }
+ }
+ else
+ StatusBar::UserDraw( rUDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::InsertStatusField( long, USHORT,
+ USHORT nFlags )
+{
+ mnFieldFlags = nFlags;
+ ImplUpdateField( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::SetFieldFlags( USHORT nFlags )
+{
+ if ( mnFieldFlags != nFlags )
+ {
+ mnFieldFlags = nFlags;
+ ImplUpdateField( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::AddStatusFieldItem( USHORT nItemId, const TaskStatusFieldItem& rItem,
+ USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "TaskStatusBar::AddStatusFieldItem() - Item is 0" );
+ DBG_ASSERT( !ImplGetFieldItem( nItemId ), "TaskStatusBar::AddStatusFieldItem() - Item-Id already exist" );
+
+ if ( !mpFieldItemList )
+ mpFieldItemList = new ImplTaskSBItemList;
+
+ ImplTaskSBFldItem* pItem = new ImplTaskSBFldItem;
+ pItem->maItem = rItem;
+ pItem->mnId = nItemId;
+ pItem->mnOffX = 0;
+ mpFieldItemList->Insert( pItem, (ULONG)nPos );
+
+ ImplUpdateField( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::ModifyStatusFieldItem( USHORT nItemId, const TaskStatusFieldItem& rItem )
+{
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
+ if ( pItem )
+ {
+ BOOL bUpdate = (pItem->maItem.GetImage() != rItem.GetImage()) ||
+ (pItem->maItem.GetFlags() != rItem.GetFlags());
+ pItem->maItem = rItem;
+ if ( bUpdate )
+ ImplUpdateField( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::RemoveStatusFieldItem( USHORT nItemId )
+{
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
+ if ( pItem )
+ {
+ mpFieldItemList->Remove( pItem );
+ delete pItem;
+ ImplUpdateField( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::GetStatusFieldItem( USHORT nItemId, TaskStatusFieldItem& rItem ) const
+{
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
+ if ( pItem )
+ {
+ rItem = pItem->maItem;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx
new file mode 100644
index 000000000000..f0bd192fc02c
--- /dev/null
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -0,0 +1,1805 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <vcl/dockwin.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/image.hxx>
+#include <vcl/taskpanelist.hxx>
+#include <vcl/toolbox.hxx>
+
+#include "svtools/valueset.hxx"
+#include "svtools/toolbarmenu.hxx"
+#include "toolbarmenuimp.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::accessibility;
+
+namespace svtools {
+
+// --------------------------------------------------------------------
+
+static Window* GetTopMostParentSystemWindow( Window* pWindow )
+{
+ OSL_ASSERT( pWindow );
+ if ( pWindow )
+ {
+ // ->manually search topmost system window
+ // required because their might be another system window between this and the top window
+ pWindow = pWindow->GetParent();
+ SystemWindow* pTopMostSysWin = NULL;
+ while ( pWindow )
+ {
+ if ( pWindow->IsSystemWindow() )
+ pTopMostSysWin = (SystemWindow*)pWindow;
+ pWindow = pWindow->GetParent();
+ }
+ pWindow = pTopMostSysWin;
+ OSL_ASSERT( pWindow );
+ return pWindow;
+ }
+
+ return NULL;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenuEntry::init( int nEntryId, MenuItemBits nBits )
+{
+ mnEntryId = nEntryId;
+ mnBits = nBits;
+
+ mbHasText = false;
+ mbHasImage = false;
+ mbChecked = false;
+ mbEnabled = true;
+
+ mpControl = NULL;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ maText = rText;
+ mbHasText = true;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ maImage = rImage;
+ mbHasImage = true;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ maText = rText;
+ mbHasText = true;
+
+ maImage = rImage;
+ mbHasImage = true;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ if( pControl )
+ {
+ mpControl = pControl;
+ mpControl->Show();
+ }
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::~ToolbarMenuEntry()
+{
+ if( mxAccContext.is() )
+ {
+ Reference< XComponent > xComponent( mxAccContext, UNO_QUERY );
+ if( xComponent.is() )
+ xComponent->dispose();
+ mxAccContext.clear();
+ }
+ delete mpControl;
+}
+
+// --------------------------------------------------------------------
+
+const Reference< XAccessibleContext >& ToolbarMenuEntry::GetAccessible( bool bCreate /* = false */ )
+{
+ if( !mxAccContext.is() && bCreate )
+ {
+ if( mpControl )
+ {
+ mxAccContext = Reference< XAccessibleContext >( mpControl->GetAccessible( TRUE ), UNO_QUERY );
+ }
+ else
+ {
+ mxAccContext = Reference< XAccessibleContext >( new ToolbarMenuEntryAcc( this ) );
+ }
+ }
+
+ return mxAccContext;
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 ToolbarMenuEntry::getAccessibleChildCount() throw (RuntimeException)
+{
+ if( mpControl )
+ {
+ const Reference< XAccessibleContext >& xContext = GetAccessible( true );
+ if( xContext.is() )
+ {
+ return xContext->getAccessibleChildCount();
+ }
+ }
+ return 1;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XAccessible > ToolbarMenuEntry::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const Reference< XAccessibleContext >& xContext = GetAccessible( true );
+ if( mpControl )
+ {
+ if( xContext.is() )
+ {
+ return xContext->getAccessibleChild(index);
+ }
+ }
+ else if( index == 0 )
+ {
+ Reference< XAccessible > xRet( xContext, UNO_QUERY );
+ if( xRet.is() )
+ return xRet;
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu_Impl::ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame )
+: mrMenu( rMenu )
+, mxFrame( xFrame )
+, mxServiceManager( ::comphelper::getProcessServiceFactory() )
+, mnCheckPos(0)
+, mnImagePos(0)
+, mnTextPos(0)
+, mnHighlightedEntry(-1)
+, mnSelectedEntry(-1)
+, mnLastColumn(0)
+{
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu_Impl::~ToolbarMenu_Impl()
+{
+ setAccessible( 0 );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::setAccessible( ToolbarMenuAcc* pAccessible )
+{
+ if( mxAccessible.get() != pAccessible )
+ {
+ if( mxAccessible.is() )
+ mxAccessible->dispose();
+
+ mxAccessible.set( pAccessible );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenu_Impl::fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
+{
+ if( mxAccessible.is() )
+ mxAccessible->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+bool ToolbarMenu_Impl::hasAccessibleListeners()
+{
+ return( mxAccessible.is() && mxAccessible->HasAccessibleListeners() );
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 ToolbarMenu_Impl::getAccessibleChildCount() throw (RuntimeException)
+{
+ sal_Int32 nCount = 0;
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ if( pEntry->mpControl )
+ {
+ nCount += pEntry->getAccessibleChildCount();
+ }
+ else
+ {
+ nCount += 1;
+ }
+ }
+ }
+
+ return nCount;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ const sal_Int32 nCount = pEntry->getAccessibleChildCount();
+ if( index < nCount )
+ {
+ return pEntry->getAccessibleChild( index );
+ }
+ index -= nCount;
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry && (pEntry->mpControl == pControl) )
+ {
+ return pEntry->getAccessibleChild( childIndex );
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ const sal_Int32 nCount = pEntry->getAccessibleChildCount();
+ if( nChildIndex < nCount )
+ {
+ if( pEntry->mpControl )
+ {
+ Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ xSel->selectAccessibleChild(nChildIndex);
+ }
+ else if( pEntry->mnEntryId != TITLE_ID )
+ {
+ mrMenu.implSelectEntry( nEntry );
+ }
+ return;
+ }
+ nChildIndex -= nCount;
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+sal_Bool ToolbarMenu_Impl::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ const sal_Int32 nCount = pEntry->getAccessibleChildCount();
+ if( nChildIndex < nCount )
+ {
+ if( mnHighlightedEntry == nEntry )
+ {
+ if( pEntry->mpControl )
+ {
+ Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ xSel->isAccessibleChildSelected(nChildIndex);
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ nChildIndex -= nCount;
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::clearAccessibleSelection()
+{
+ if( mnHighlightedEntry != -1 )
+ {
+ mrMenu.implHighlightEntry( mnHighlightedEntry, false );
+ mnHighlightedEntry = -1;
+ }
+}
+
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::notifyHighlightedEntry()
+{
+ if( hasAccessibleListeners() )
+ {
+ ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry );
+ if( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
+ {
+ Any aNew;
+ Any aOld( mxOldSelection );
+ if( pEntry->mpControl )
+ {
+ sal_Int32 nChildIndex = 0;
+ // todo: if other controls than ValueSet are allowed, addapt this code
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl );
+ if( pValueSet )
+ nChildIndex = static_cast< sal_Int32 >( pValueSet->GetItemPos( pValueSet->GetSelectItemId() ) );
+
+ if( nChildIndex >= pEntry->getAccessibleChildCount() )
+ return;
+
+ aNew <<= getAccessibleChild( pEntry->mpControl, nChildIndex );
+ }
+ else
+ {
+ aNew <<= pEntry->GetAccessible(true);
+ }
+
+ fireAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOld, aNew );
+ fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOld, aNew );
+ fireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), Any( AccessibleStateType::FOCUSED ) );
+ aNew >>= mxOldSelection;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu_Impl::implGetEntry( int nEntry ) const
+{
+ if( (nEntry < 0) || (nEntry >= (int)maEntryVector.size() ) )
+ return NULL;
+
+ return maEntryVector[nEntry];
+}
+
+
+// --------------------------------------------------------------------
+
+IMPL_LINK( ToolbarMenu, HighlightHdl, Control *, pControl )
+{
+ (void)pControl;
+ mpImpl->notifyHighlightedEntry();
+ return 0;
+}
+
+// ====================================================================
+
+ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, WinBits nBits )
+: DockingWindow(pParentWindow, nBits)
+{
+ implInit(rFrame);
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, const ResId& rResId )
+: DockingWindow(pParentWindow, rResId)
+{
+ implInit(rFrame);
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implInit(const Reference< XFrame >& rFrame)
+{
+ mpImpl = new ToolbarMenu_Impl( *this, rFrame );
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetControlBackground( rStyleSettings.GetMenuColor() );
+
+ initWindow();
+
+ Window* pWindow = GetTopMostParentSystemWindow( this );
+ if ( pWindow )
+ ((SystemWindow *)pWindow)->GetTaskPaneList()->AddWindow( this );
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu::~ToolbarMenu()
+{
+ Window* pWindow = GetTopMostParentSystemWindow( this );
+ if ( pWindow )
+ ((SystemWindow *)pWindow)->GetTaskPaneList()->RemoveWindow( this );
+
+ if ( mpImpl->mxStatusListener.is() )
+ {
+ mpImpl->mxStatusListener->dispose();
+ mpImpl->mxStatusListener.clear();
+ }
+
+ // delete all menu entries
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ delete mpImpl->maEntryVector[nEntry];
+ }
+
+ delete mpImpl;
+}
+
+// --------------------------------------------------------------------
+
+int ToolbarMenu::getSelectedEntryId() const
+{
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnSelectedEntry );
+ return pEntry ? pEntry->mnEntryId : -1;
+}
+
+// --------------------------------------------------------------------
+
+int ToolbarMenu::getHighlightedEntryId() const
+{
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
+ return pEntry ? pEntry->mnEntryId : -1;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::checkEntry( int nEntryId, bool bChecked )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->mbChecked != bChecked )
+ {
+ pEntry->mbChecked = bChecked;
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool ToolbarMenu::isEntryChecked( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ return pEntry && pEntry->mbChecked;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::enableEntry( int nEntryId, bool bEnable )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->mbEnabled != bEnable )
+ {
+ pEntry->mbEnabled = bEnable;
+ if( pEntry->mpControl )
+ {
+ pEntry->mpControl->Enable( bEnable );
+
+ // hack for the valueset to make it paint itself anew
+ pEntry->mpControl->Resize();
+ }
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool ToolbarMenu::isEntryEnabled( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ return pEntry && pEntry->mbEnabled;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::setEntryText( int nEntryId, const String& rStr )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->maText != rStr )
+ {
+ pEntry->maText = rStr;
+ mpImpl->maSize = implCalcSize();
+ if( IsVisible() )
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+const String& ToolbarMenu::getEntryText( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry )
+ return pEntry->maText;
+ else
+ {
+ static String aEmptyStr;
+ return aEmptyStr;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::setEntryImage( int nEntryId, const Image& rImage )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->maImage != rImage )
+ {
+ pEntry->maImage = rImage;
+ mpImpl->maSize = implCalcSize();
+ if( IsVisible() )
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+const Image& ToolbarMenu::getEntryImage( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry )
+ return pEntry->maImage;
+ else
+ {
+ static Image aEmptyImage;
+ return aEmptyImage;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::initWindow()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ SetPointFont( rStyleSettings.GetMenuFont() );
+ SetBackground( Wallpaper( GetControlBackground() ) );
+ SetTextColor( rStyleSettings.GetMenuTextColor() );
+ SetTextFillColor();
+ SetLineColor();
+
+ mpImpl->maSize = implCalcSize();
+}
+
+// --------------------------------------------------------------------
+
+Size ToolbarMenu::implCalcSize()
+{
+ const long nFontHeight = GetTextHeight();
+ long nExtra = nFontHeight/4;
+
+ Size aSz;
+ Size aMaxImgSz;
+ long nMaxTextWidth = 0;
+ long nMinMenuItemHeight = nFontHeight+2;
+ sal_Bool bCheckable = sal_False;
+
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+ const bool bUseImages = rSettings.GetUseImagesInMenus();
+
+ // get maximum image size
+ if( bUseImages )
+ {
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+ if( pEntry && pEntry->mbHasImage )
+ {
+ Size aImgSz( pEntry->maImage.GetSizePixel() );
+ nMinMenuItemHeight = std::max( nMinMenuItemHeight, aImgSz.Height() + 6 );
+ aMaxImgSz.Width() = std::max( aMaxImgSz.Width(), aImgSz.Width() );
+ }
+ }
+ }
+
+ mpImpl->mnCheckPos = nExtra;
+ mpImpl->mnImagePos = nExtra;
+ mpImpl->mnTextPos = mpImpl->mnImagePos + aMaxImgSz.Width();
+
+ if ( aMaxImgSz.Width() )
+ mpImpl->mnTextPos += std::max( nExtra, 7L );
+ if ( bCheckable )
+ mpImpl->mnTextPos += 16;
+
+ // set heights, calc maximum width
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+
+ if( pEntry )
+ {
+ if ( ( pEntry->mnBits ) & ( MIB_RADIOCHECK | MIB_CHECKABLE ) )
+ bCheckable = sal_True;
+
+ // Text:
+ if( pEntry->mbHasText || pEntry->mbHasImage )
+ {
+ pEntry->maSize.Height() = nMinMenuItemHeight;
+
+ if( pEntry->mbHasText )
+ {
+ long nTextWidth = GetCtrlTextWidth( pEntry->maText ) + mpImpl->mnTextPos + nExtra;
+ nMaxTextWidth = std::max( nTextWidth, nMaxTextWidth );
+ }
+ }
+ // Control:
+ else if( pEntry->mpControl )
+ {
+ Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
+
+ nMaxTextWidth = std::max( aControlSize.Width(), nMaxTextWidth );
+ pEntry->maSize.Height() = aControlSize.Height() + 1;
+ }
+
+ }
+ }
+
+ aSz.Width() = nMaxTextWidth + (BORDER_X<<1);
+
+ // positionate controls
+ int nY = BORDER_Y;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+
+ if( pEntry )
+ {
+ pEntry->maSize.Width() = nMaxTextWidth;
+
+ if( pEntry->mpControl )
+ {
+ Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
+ Point aControlPos( (aSz.Width() - aControlSize.Width())>>1, nY);
+
+ pEntry->mpControl->SetPosPixel( aControlPos );
+
+ pEntry->maRect = Rectangle( aControlPos, aControlSize );
+ }
+ else
+ {
+ pEntry->maRect = Rectangle( Point( 0, nY ), pEntry->maSize );
+ }
+
+ nY += pEntry->maSize.Height();
+ }
+ else
+ {
+ nY += SEPARATOR_HEIGHT;
+ }
+ }
+
+ aSz.Height() += nY + BORDER_Y;
+
+ return aSz;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::highlightFirstEntry()
+{
+ implChangeHighlightEntry( 0 );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::GetFocus()
+{
+ if( mpImpl->mnHighlightedEntry == -1 )
+ implChangeHighlightEntry( 0 );
+
+ DockingWindow::GetFocus();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::LoseFocus()
+{
+ if( mpImpl->mnHighlightedEntry != -1 )
+ implChangeHighlightEntry( -1 );
+
+ DockingWindow::LoseFocus();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rStr, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const Image& rImage, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, rStr, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, pControl, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( ToolbarMenuEntry* pEntry )
+{
+ mpImpl->maEntryVector.push_back( pEntry );
+ mpImpl->maSize = implCalcSize();
+ if( IsVisible() )
+ Invalidate();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendSeparator()
+{
+ appendEntry( 0 );
+}
+
+// --------------------------------------------------------------------
+
+/** creates an empty ValueSet that is initialized and can be inserted with appendEntry. */
+ValueSet* ToolbarMenu::createEmptyValueSetControl()
+{
+ ValueSet* pSet = new ValueSet( this, WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT );
+ pSet->EnableFullItemMode( FALSE );
+ pSet->SetColor( GetControlBackground() );
+ pSet->SetHighlightHdl( LINK( this, ToolbarMenu, HighlightHdl ) );
+ return pSet;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu::implGetEntry( int nEntry ) const
+{
+ return mpImpl->implGetEntry( nEntry );
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu::implSearchEntry( int nEntryId ) const
+{
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* p = mpImpl->maEntryVector[nEntry];
+ if( p && p->mnEntryId == nEntryId )
+ {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implHighlightEntry( int nHighlightEntry, bool bHighlight )
+{
+ Size aSz( GetOutputSizePixel() );
+ long nX = 0, nY = 0;
+
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+ if( pEntry && (nEntry == nHighlightEntry) )
+ {
+ // no highlights for controls only items
+ if( pEntry->mpControl )
+ {
+ if( !bHighlight )
+ {
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl );
+ if( pValueSet )
+ {
+ pValueSet->SetNoSelection();
+ }
+ }
+ break;
+ }
+
+ bool bRestoreLineColor = false;
+ Color oldLineColor;
+ bool bDrawItemRect = true;
+
+ Rectangle aItemRect( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) );
+ if ( pEntry->mnBits & MIB_POPUPSELECT )
+ {
+ long nFontHeight = GetTextHeight();
+ aItemRect.Right() -= nFontHeight + nFontHeight/4;
+ }
+
+ if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
+ {
+ Size aPxSize( GetOutputSizePixel() );
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) ) );
+ Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) );
+ DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
+ aCtrlRect,
+ CTRL_STATE_ENABLED,
+ ImplControlValue(),
+ OUString() );
+ if( bHighlight && IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
+ {
+ bDrawItemRect = false;
+ if( FALSE == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
+ aItemRect,
+ CTRL_STATE_SELECTED | ( pEntry->mbEnabled? CTRL_STATE_ENABLED: 0 ),
+ ImplControlValue(),
+ OUString() ) )
+ {
+ bDrawItemRect = bHighlight;
+ }
+ }
+ else
+ bDrawItemRect = bHighlight;
+ Pop();
+ }
+ if( bDrawItemRect )
+ {
+ if ( bHighlight )
+ {
+ if( pEntry->mbEnabled )
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
+ else
+ {
+ SetFillColor();
+ oldLineColor = GetLineColor();
+ SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
+ bRestoreLineColor = true;
+ }
+ }
+ else
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
+
+ DrawRect( aItemRect );
+ }
+ implPaint( pEntry, bHighlight );
+ if( bRestoreLineColor )
+ SetLineColor( oldLineColor );
+ break;
+ }
+
+ nY += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implSelectEntry( int nSelectedEntry )
+{
+ mpImpl->mnSelectedEntry = nSelectedEntry;
+
+ ToolbarMenuEntry* pEntry = NULL;
+ if( nSelectedEntry != -1 )
+ pEntry = mpImpl->maEntryVector[ nSelectedEntry ];
+
+ if( pEntry )
+ mpImpl->maSelectHdl.Call( this );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ implHighlightEntry( rMEvt, true );
+
+ implSelectEntry( mpImpl->mnHighlightedEntry );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::MouseButtonUp( const MouseEvent& )
+{
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !IsVisible() )
+ return;
+
+ implHighlightEntry( rMEvt, false );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implHighlightEntry( const MouseEvent& rMEvt, bool bMBDown )
+{
+ long nY = 0;
+ long nMouseY = rMEvt.GetPosPixel().Y();
+ Size aOutSz = GetOutputSizePixel();
+ if ( ( nMouseY >= 0 ) && ( nMouseY < aOutSz.Height() ) )
+ {
+ bool bHighlighted = FALSE;
+
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+ if( pEntry )
+ {
+ long nOldY = nY;
+ nY += pEntry->maSize.Height();
+
+ if( pEntry->mnEntryId != TITLE_ID )
+ {
+ if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) )
+ {
+ if( bMBDown )
+ {
+ if( nEntry != mpImpl->mnHighlightedEntry )
+ {
+ implChangeHighlightEntry( nEntry );
+ }
+ }
+ else
+ {
+ if ( nEntry != mpImpl->mnHighlightedEntry )
+ {
+ implChangeHighlightEntry( nEntry );
+ }
+ }
+ bHighlighted = true;
+ }
+ }
+ }
+ else
+ {
+ nY += SEPARATOR_HEIGHT;
+ }
+ }
+ if ( !bHighlighted )
+ implChangeHighlightEntry( -1 );
+ }
+ else
+ {
+ implChangeHighlightEntry( -1 );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implChangeHighlightEntry( int nEntry )
+{
+ if( mpImpl->mnHighlightedEntry != -1 )
+ {
+ implHighlightEntry( mpImpl->mnHighlightedEntry, false );
+ }
+
+ mpImpl->mnHighlightedEntry = nEntry;
+ Invalidate();
+
+ if( mpImpl->mnHighlightedEntry != -1 )
+ {
+ implHighlightEntry( mpImpl->mnHighlightedEntry, true );
+ }
+
+ mpImpl->notifyHighlightedEntry();
+}
+
+// --------------------------------------------------------------------
+
+static bool implCheckSubControlCursorMove( Control* pControl, bool bUp, int& nLastColumn )
+{
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
+ if( pValueSet )
+ {
+ USHORT nItemPos = pValueSet->GetItemPos( pValueSet->GetSelectItemId() );
+ if( nItemPos != VALUESET_ITEM_NOTFOUND )
+ {
+ const USHORT nColCount = pValueSet->GetColCount();
+ const USHORT nLine = nItemPos / nColCount;
+
+ nLastColumn = nItemPos - (nLine * nColCount);
+
+ if( bUp )
+ {
+ return nLine > 0;
+ }
+ else
+ {
+ const USHORT nLineCount = (pValueSet->GetItemCount() + nColCount - 1) / nColCount;
+ return (nLine+1) < nLineCount;
+ }
+ }
+ }
+
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu::implCursorUpDown( bool bUp, bool bHomeEnd )
+{
+ int n = 0, nLoop = 0;
+ if( !bHomeEnd )
+ {
+ n = mpImpl->mnHighlightedEntry;
+ if( n == -1 )
+ {
+ if( bUp )
+ n = 0;
+ else
+ n = mpImpl->maEntryVector.size()-1;
+ }
+ else
+ {
+ // if we have a currently selected entry and
+ // cursor keys are used than check if this entry
+ // has a control that can use those cursor keys
+ ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
+ if( pData && pData->mpControl && !pData->mbHasText )
+ {
+ if( implCheckSubControlCursorMove( pData->mpControl, bUp, mpImpl->mnLastColumn ) )
+ return pData;
+ }
+ }
+ nLoop = n;
+ }
+ else
+ {
+ // absolute positioning
+ if( bUp )
+ {
+ n = mpImpl->maEntryVector.size();
+ nLoop = n-1;
+ }
+ else
+ {
+ n = -1;
+ nLoop = mpImpl->maEntryVector.size()-1;
+ }
+ }
+
+ do
+ {
+ if( bUp )
+ {
+ if ( n )
+ n--;
+ else
+ if( mpImpl->mnHighlightedEntry == -1 )
+ n = mpImpl->maEntryVector.size()-1;
+ else
+ break;
+ }
+ else
+ {
+ if( n < ((int)mpImpl->maEntryVector.size()-1) )
+ n++;
+ else
+ if( mpImpl->mnHighlightedEntry == -1 )
+ n = 0;
+ else
+ break;
+ }
+
+ ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
+ if( pData && (pData->mnEntryId != TITLE_ID) )
+ {
+ implChangeHighlightEntry( n );
+ return pData;
+ }
+ } while ( n != nLoop );
+
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::implHighlightControl( USHORT nCode, Control* pControl )
+{
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
+ if( pValueSet )
+ {
+ const USHORT nItemCount = pValueSet->GetItemCount();
+ USHORT nItemPos = VALUESET_ITEM_NOTFOUND;
+ switch( nCode )
+ {
+ case KEY_UP:
+ {
+ const USHORT nColCount = pValueSet->GetColCount();
+ const USHORT nLastLine = nItemCount / nColCount;
+ nItemPos = std::min( ((nLastLine-1) * nColCount) + mnLastColumn, nItemCount-1 );
+ break;
+ }
+ case KEY_DOWN:
+ nItemPos = std::min( mnLastColumn, nItemCount-1 );
+ break;
+ case KEY_END:
+ nItemPos = nItemCount -1;
+ break;
+ case KEY_HOME:
+ nItemPos = 0;
+ break;
+ }
+ pValueSet->SelectItem( pValueSet->GetItemId( nItemPos ) );
+ notifyHighlightedEntry();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::KeyInput( const KeyEvent& rKEvent )
+{
+ Control* pForwardControl = 0;
+ USHORT nCode = rKEvent.GetKeyCode().GetCode();
+ switch ( nCode )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ {
+ int nOldEntry = mpImpl->mnHighlightedEntry;
+ ToolbarMenuEntry*p = implCursorUpDown( nCode == KEY_UP, false );
+ if( p && p->mpControl )
+ {
+ if( nOldEntry != mpImpl->mnHighlightedEntry )
+ {
+ mpImpl->implHighlightControl( nCode, p->mpControl );
+ }
+ else
+ {
+ // in case we are in a system floating window, GrabFocus does not work :-/
+ pForwardControl = p->mpControl;
+ }
+ }
+ }
+ break;
+ case KEY_END:
+ case KEY_HOME:
+ {
+ ToolbarMenuEntry* p = implCursorUpDown( nCode == KEY_END, true );
+ if( p && p->mpControl )
+ {
+ mpImpl->implHighlightControl( nCode, p->mpControl );
+ }
+ }
+ break;
+ case KEY_F6:
+ case KEY_ESCAPE:
+ {
+ // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
+ if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
+ break;
+
+ implSelectEntry( -1 );
+ }
+ break;
+
+ case KEY_RETURN:
+ {
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
+ if ( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
+ {
+ if( pEntry->mpControl )
+ {
+ pForwardControl = pEntry->mpControl;
+ }
+ else
+ {
+ implSelectEntry( mpImpl->mnHighlightedEntry );
+ }
+ }
+ }
+ break;
+ default:
+ {
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
+ if ( pEntry && pEntry->mbEnabled && pEntry->mpControl && !pEntry->mbHasText )
+ {
+ pForwardControl = pEntry->mpControl;
+ }
+ }
+
+ }
+ if( pForwardControl )
+ pForwardControl->KeyInput( rKEvent );
+
+}
+
+// --------------------------------------------------------------------
+static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRect, bool i_bHighlight )
+{
+ BOOL bNativeOk = FALSE;
+ if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
+ {
+ ImplControlValue aControlValue;
+ ControlState nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED;
+
+ aControlValue.setTristateVal( BUTTONVALUE_ON );
+
+ bNativeOk = i_pWindow->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
+ i_rRect, nState, aControlValue,
+ rtl::OUString() );
+ }
+
+ if( ! bNativeOk )
+ {
+ const StyleSettings& rSettings = i_pWindow->GetSettings().GetStyleSettings();
+ Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() );
+ i_pWindow->DrawSelectionBackground( i_rRect, 0, i_bHighlight, TRUE, FALSE, 2, NULL, &aColor );
+ }
+}
+
+static long ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth )
+{
+ rMaxWidth = rCheckHeight = rRadioHeight = 0;
+
+ ImplControlValue aVal;
+ Rectangle aNativeBounds;
+ Rectangle aNativeContent;
+ Point tmp( 0, 0 );
+ Rectangle aCtrlRegion( tmp, Size( 100, 15 ) );
+ if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK ) )
+ {
+ if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
+ ControlPart(PART_MENU_ITEM_CHECK_MARK),
+ aCtrlRegion,
+ ControlState(CTRL_STATE_ENABLED),
+ aVal,
+ OUString(),
+ aNativeBounds,
+ aNativeContent )
+ )
+ {
+ rCheckHeight = aNativeBounds.GetHeight();
+ rMaxWidth = aNativeContent.GetWidth();
+ }
+ }
+ if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK ) )
+ {
+ if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
+ ControlPart(PART_MENU_ITEM_RADIO_MARK),
+ aCtrlRegion,
+ ControlState(CTRL_STATE_ENABLED),
+ aVal,
+ OUString(),
+ aNativeBounds,
+ aNativeContent )
+ )
+ {
+ rRadioHeight = aNativeBounds.GetHeight();
+ rMaxWidth = Max (rMaxWidth, aNativeContent.GetWidth());
+ }
+ }
+ return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight;
+}
+
+void ToolbarMenu::implPaint( ToolbarMenuEntry* pThisOnly, bool bHighlighted )
+{
+ USHORT nBorder = 0; long nStartY = 0; // from Menu implementations, needed when we support native menu background & scrollable menu
+
+ long nFontHeight = GetTextHeight();
+// long nExtra = nFontHeight/4;
+
+ long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0;
+ ImplGetNativeCheckAndRadioSize( this, nCheckHeight, nRadioHeight, nMaxCheckWidth );
+
+ DecorationView aDecoView( this );
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+ const bool bUseImages = rSettings.GetUseImagesInMenus();
+
+ int nOuterSpace = 0; // ImplGetSVData()->maNWFData.mnMenuFormatExtraBorder;
+ Point aTopLeft( nOuterSpace, nOuterSpace ), aTmpPos;
+
+ Size aOutSz( GetOutputSizePixel() );
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+
+ Point aPos( aTopLeft );
+ aPos.Y() += nBorder;
+ aPos.Y() += nStartY;
+
+
+ if( (pEntry == 0) && !pThisOnly )
+ {
+ // Separator
+ aTmpPos.Y() = aPos.Y() + ((SEPARATOR_HEIGHT-2)/2);
+ aTmpPos.X() = aPos.X() + 2 + nOuterSpace;
+ SetLineColor( rSettings.GetShadowColor() );
+ DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) );
+ aTmpPos.Y()++;
+ SetLineColor( rSettings.GetLightColor() );
+ DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) );
+ SetLineColor();
+ }
+ else if( !pThisOnly || ( pEntry == pThisOnly ) )
+ {
+ const bool bTitle = pEntry->mnEntryId == TITLE_ID;
+
+ if ( pThisOnly && bHighlighted )
+ SetTextColor( rSettings.GetMenuHighlightTextColor() );
+
+ if( aPos.Y() >= 0 )
+ {
+ long nTextOffsetY = ((pEntry->maSize.Height()-nFontHeight)/2);
+
+ USHORT nTextStyle = 0;
+ USHORT nSymbolStyle = 0;
+ USHORT nImageStyle = 0;
+
+ if( !pEntry->mbEnabled )
+ {
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ nSymbolStyle |= SYMBOL_DRAW_DISABLE;
+ nImageStyle |= IMAGE_DRAW_DISABLE;
+ }
+
+ Rectangle aOuterCheckRect( Point( aPos.X()+mpImpl->mnCheckPos, aPos.Y() ), Size( pEntry->maSize.Height(), pEntry->maSize.Height() ) );
+ aOuterCheckRect.Left() += 1;
+ aOuterCheckRect.Right() -= 1;
+ aOuterCheckRect.Top() += 1;
+ aOuterCheckRect.Bottom() -= 1;
+
+ if( bTitle )
+ {
+ // fill the background
+ Rectangle aRect( aTopLeft, Size( aOutSz.Width(), pEntry->maSize.Height() ) );
+ SetFillColor(rSettings.GetDialogColor());
+ SetLineColor();
+ DrawRect(aRect);
+ SetLineColor( rSettings.GetLightColor() );
+ DrawLine( aRect.TopLeft(), aRect.TopRight() );
+ SetLineColor( rSettings.GetShadowColor() );
+ DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
+ }
+
+ // CheckMark
+ if ( pEntry->HasCheck() )
+ {
+ // draw selection transparent marker if checked
+ // onto that either a checkmark or the item image
+ // will be painted
+ // however do not do this if native checks will be painted since
+ // the selection color too often does not fit the theme's check and/or radio
+
+ if( !pEntry->mbHasImage )
+ {
+ if( this->IsNativeControlSupported( CTRL_MENU_POPUP,
+ (pEntry->mnBits & MIB_RADIOCHECK)
+ ? PART_MENU_ITEM_CHECK_MARK
+ : PART_MENU_ITEM_RADIO_MARK ) )
+ {
+ ControlPart nPart = ((pEntry->mnBits & MIB_RADIOCHECK)
+ ? PART_MENU_ITEM_RADIO_MARK
+ : PART_MENU_ITEM_CHECK_MARK);
+
+ ControlState nState = 0;
+
+ if ( pEntry->mbChecked )
+ nState |= CTRL_STATE_PRESSED;
+
+ if ( pEntry->mbEnabled )
+ nState |= CTRL_STATE_ENABLED;
+
+ if ( bHighlighted )
+ nState |= CTRL_STATE_SELECTED;
+
+ long nCtrlHeight = (pEntry->mnBits & MIB_RADIOCHECK) ? nCheckHeight : nRadioHeight;
+ aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight)/2;
+ aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight)/2;
+
+ Rectangle aCheckRect( aTmpPos, Size( nCtrlHeight, nCtrlHeight ) );
+ DrawNativeControl( CTRL_MENU_POPUP, nPart, aCheckRect, nState, ImplControlValue(), OUString() );
+ }
+ else if ( pEntry->mbChecked ) // by default do nothing for unchecked items
+ {
+ ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted );
+
+ SymbolType eSymbol;
+ Size aSymbolSize;
+ if ( pEntry->mnBits & MIB_RADIOCHECK )
+ {
+ eSymbol = SYMBOL_RADIOCHECKMARK;
+ aSymbolSize = Size( nFontHeight/2, nFontHeight/2 );
+ }
+ else
+ {
+ eSymbol = SYMBOL_CHECKMARK;
+ aSymbolSize = Size( (nFontHeight*25)/40, nFontHeight/2 );
+ }
+ aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width())/2;
+ aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height())/2;
+ Rectangle aRect( aTmpPos, aSymbolSize );
+ aDecoView.DrawSymbol( aRect, eSymbol, GetTextColor(), nSymbolStyle );
+ }
+ }
+ }
+
+ // Image:
+ if( pEntry->mbHasImage && bUseImages )
+ {
+ // Don't render an image for a check thing
+ /* if((nMenuFlags & MENU_FLAG_SHOWCHECKIMAGES) || !pEntry->HasCheck() )*/
+ {
+ if( pEntry->mbChecked )
+ ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted );
+ aTmpPos = aOuterCheckRect.TopLeft();
+ aTmpPos.X() += (aOuterCheckRect.GetWidth()-pEntry->maImage.GetSizePixel().Width())/2;
+ aTmpPos.Y() += (aOuterCheckRect.GetHeight()-pEntry->maImage.GetSizePixel().Height())/2;
+ DrawImage( aTmpPos, pEntry->maImage, nImageStyle );
+ }
+ }
+
+ // Text:
+ if( pEntry->mbHasText )
+ {
+ aTmpPos.X() = aPos.X() + (bTitle ? 4 : mpImpl->mnTextPos);
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nTextOffsetY;
+ USHORT nStyle = nTextStyle|TEXT_DRAW_MNEMONIC;
+
+ DrawCtrlText( aTmpPos, pEntry->maText, 0, pEntry->maText.Len(), nStyle, NULL, NULL ); // pVector, pDisplayText );
+ }
+
+/*
+ // Accel
+ if ( !bLayout && !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() )
+ {
+ XubString aAccText = pData->aAccelKey.GetName();
+ aTmpPos.X() = aOutSz.Width() - this->GetTextWidth( aAccText );
+ aTmpPos.X() -= 4*nExtra;
+
+ aTmpPos.X() -= nOuterSpace;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nTextOffsetY;
+ this->DrawCtrlText( aTmpPos, aAccText, 0, aAccText.Len(), nTextStyle );
+ }
+*/
+
+/*
+ // SubMenu?
+ if ( !bLayout && !bIsMenuBar && pData->pSubMenu )
+ {
+ aTmpPos.X() = aOutSz.Width() - nFontHeight + nExtra - nOuterSpace;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nExtra/2;
+ aTmpPos.Y() += ( pEntry->maSize.Height() / 2 ) - ( nFontHeight/4 );
+ if ( pEntry->mnBits & MIB_POPUPSELECT )
+ {
+ this->SetTextColor( rSettings.GetMenuTextColor() );
+ Point aTmpPos2( aPos );
+ aTmpPos2.X() = aOutSz.Width() - nFontHeight - nFontHeight/4;
+ aDecoView.DrawFrame(
+ Rectangle( aTmpPos2, Size( nFontHeight+nFontHeight/4, pEntry->maSize.Height() ) ), FRAME_DRAW_GROUP );
+ }
+ aDecoView.DrawSymbol(
+ Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) ),
+ SYMBOL_SPIN_RIGHT, this->GetTextColor(), nSymbolStyle );
+// if ( pEntry->mnBits & MIB_POPUPSELECT )
+// {
+// aTmpPos.Y() += nFontHeight/2 ;
+// this->SetLineColor( rSettings.GetShadowColor() );
+// this->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) );
+// this->SetLineColor( rSettings.GetLightColor() );
+// aTmpPos.Y()++;
+// this->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) );
+// this->SetLineColor();
+// }
+ }
+*/
+
+ if ( pThisOnly && bHighlighted )
+ {
+ // This restores the normal menu or menu bar text
+ // color for when it is no longer highlighted.
+ SetTextColor( rSettings.GetMenuTextColor() );
+ }
+ }
+ }
+
+ aTopLeft.Y() += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::Paint( const Rectangle& )
+{
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
+
+ implPaint();
+
+ if( mpImpl->mnHighlightedEntry != -1 )
+ implHighlightEntry( mpImpl->mnHighlightedEntry, true );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::RequestHelp( const HelpEvent& rHEvt )
+{
+ DockingWindow::RequestHelp( rHEvt );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::StateChanged( StateChangedType nType )
+{
+ DockingWindow::StateChanged( nType );
+
+ if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
+ {
+ initWindow();
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ DockingWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ initWindow();
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
+ {
+ implCursorUpDown( pData->GetDelta() > 0L, false );
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+Reference< ::com::sun::star::accessibility::XAccessible > ToolbarMenu::CreateAccessible()
+{
+ mpImpl->setAccessible( new ToolbarMenuAcc( *mpImpl ) );
+ return Reference< XAccessible >( mpImpl->mxAccessible.get() );
+}
+
+// --------------------------------------------------------------------
+
+// todo: move to new base class that will replace SfxPopupWindo
+void ToolbarMenu::AddStatusListener( const rtl::OUString& rCommandURL )
+{
+ initStatusListener();
+ mpImpl->mxStatusListener->addStatusListener( rCommandURL );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::RemoveStatusListener( const rtl::OUString& rCommandURL )
+{
+ mpImpl->mxStatusListener->removeStatusListener( rCommandURL );
+}
+// --------------------------------------------------------------------
+
+
+void ToolbarMenu::UpdateStatus( const rtl::OUString& rCommandURL )
+{
+ mpImpl->mxStatusListener->updateStatus( rCommandURL );
+}
+
+// --------------------------------------------------------------------
+
+// XStatusListener (subclasses must override this one to get the status updates
+void SAL_CALL ToolbarMenu::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& /*Event*/ ) throw ( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+// --------------------------------------------------------------------
+
+class ToolbarMenuStatusListener : public svt::FrameStatusListener
+{
+public:
+ ToolbarMenuStatusListener( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
+ ToolbarMenu& rToolbarMenu );
+
+ virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
+
+ ToolbarMenu* mpMenu;
+};
+
+// --------------------------------------------------------------------
+
+ToolbarMenuStatusListener::ToolbarMenuStatusListener(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
+ ToolbarMenu& rToolbarMenu )
+: svt::FrameStatusListener( xServiceManager, xFrame )
+, mpMenu( &rToolbarMenu )
+{
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuStatusListener::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ mpMenu = 0;
+ svt::FrameStatusListener::dispose();
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuStatusListener::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException )
+{
+ if( mpMenu )
+ mpMenu->statusChanged( Event );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::initStatusListener()
+{
+ if( !mpImpl->mxStatusListener.is() )
+ mpImpl->mxStatusListener.set( new ToolbarMenuStatusListener( mpImpl->mxServiceManager, mpImpl->mxFrame, *this ) );
+}
+
+// --------------------------------------------------------------------
+
+bool ToolbarMenu::IsInPopupMode()
+{
+ return GetDockingManager()->IsInPopupMode(this);
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::EndPopupMode()
+{
+ GetDockingManager()->EndPopupMode(this);
+}
+
+// --------------------------------------------------------------------
+
+const Size& ToolbarMenu::getMenuSize() const
+{
+ return mpImpl->maSize;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::SetSelectHdl( const Link& rLink )
+{
+ mpImpl->maSelectHdl = rLink;
+}
+
+// --------------------------------------------------------------------
+
+const Link& ToolbarMenu::GetSelectHdl() const
+{
+ return mpImpl->maSelectHdl;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFrame > ToolbarMenu::GetFrame() const
+{
+ return mpImpl->mxFrame;
+}
+
+// --------------------------------------------------------------------
+
+
+// --------------------------------------------------------------------
+
+}
+
+
diff --git a/svtools/source/control/toolbarmenuacc.cxx b/svtools/source/control/toolbarmenuacc.cxx
new file mode 100644
index 000000000000..020467084748
--- /dev/null
+++ b/svtools/source/control/toolbarmenuacc.cxx
@@ -0,0 +1,1003 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <unotools/accessiblestatesethelper.hxx>
+
+#include <vcl/svapp.hxx>
+
+#include "svtools/toolbarmenu.hxx"
+
+#include "toolbarmenuimp.hxx"
+
+using ::rtl::OUString;
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::accessibility;
+
+namespace svtools {
+
+// ------------------
+// - ToolbarMenuAcc -
+// ------------------
+
+ToolbarMenuAcc::ToolbarMenuAcc( ToolbarMenu_Impl& rParent )
+: ToolbarMenuAccComponentBase(m_aMutex)
+, mpParent( &rParent )
+, mbIsFocused(false)
+{
+ mpParent->mrMenu.AddEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
+}
+
+// -----------------------------------------------------------------------------
+
+ToolbarMenuAcc::~ToolbarMenuAcc()
+{
+ if( mpParent )
+ mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ToolbarMenuAcc, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
+
+ /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
+ * might have been destroyed by the previous VCLEventListener (if no AT tool
+ * is running), e.g. sub-toolbars in impress.
+ */
+ if ( mpParent && pEvent && pEvent->ISA( VclWindowEvent ) && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
+ {
+ DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
+ if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
+ {
+ ProcessWindowEvent( *(VclWindowEvent*)pEvent );
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenuAcc::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+{
+ Any aOldValue, aNewValue;
+
+ switch ( rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_OBJECT_DYING:
+ {
+ mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
+ mpParent = 0;
+ }
+ break;
+
+ case VCLEVENT_WINDOW_GETFOCUS:
+ {
+ if( !mbIsFocused )
+ {
+ mpParent->notifyHighlightedEntry();
+ mbIsFocused = true;
+ }
+ }
+ break;
+ case VCLEVENT_WINDOW_LOSEFOCUS:
+ {
+ if( mbIsFocused )
+ {
+ mbIsFocused = false;
+ }
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenuAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
+{
+ if( nEventId )
+ {
+ EventListenerVector aTmpListeners( mxEventListeners );
+ EventListenerVector::const_iterator aIter( aTmpListeners.begin() );
+ AccessibleEventObject aEvtObject;
+
+ aEvtObject.EventId = nEventId;
+ aEvtObject.Source = static_cast<XWeak*>(this);
+ aEvtObject.NewValue = rNewValue;
+ aEvtObject.OldValue = rOldValue;
+
+ while( aIter != aTmpListeners.end() )
+ {
+ try
+ {
+ (*aIter)->notifyEvent( aEvtObject );
+ }
+ catch( Exception& )
+ {
+ }
+
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleContext > SAL_CALL ToolbarMenuAcc::getAccessibleContext() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleChildCount() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ return mpParent->getAccessibleChildCount();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ return mpParent->getAccessibleChild(i);
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleParent() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ Reference< XAccessible > xRet;
+
+ Window* pParent = mpParent->mrMenu.GetParent();
+ if( pParent )
+ xRet = pParent->GetAccessible();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleIndexInParent() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ Window* pParent = mpParent->mrMenu.GetParent();
+ if( pParent )
+ {
+ for( USHORT i = 0, nCount = pParent->GetChildCount(); i < nCount ; i++ )
+ {
+ if( pParent->GetChild( i ) == &mpParent->mrMenu )
+ return i;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ToolbarMenuAcc::getAccessibleRole() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return AccessibleRole::LIST;
+}
+
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL ToolbarMenuAcc::getAccessibleDescription() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "ToolbarMenu" ) );
+}
+
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL ToolbarMenuAcc::getAccessibleName() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ OUString aRet;
+
+ if( mpParent )
+ aRet = mpParent->mrMenu.GetAccessibleName();
+
+ if( !aRet.getLength() )
+ {
+ Window* pLabel = mpParent->mrMenu.GetLabeledBy();
+ if( pLabel && pLabel != &mpParent->mrMenu )
+ aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() );
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuAcc::getAccessibleRelationSet() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return Reference< XAccessibleRelationSet >();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuAcc::getAccessibleStateSet() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
+
+ // Set some states.
+ pStateSet->AddState (AccessibleStateType::ENABLED);
+ pStateSet->AddState (AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (AccessibleStateType::SHOWING);
+ pStateSet->AddState (AccessibleStateType::VISIBLE);
+ pStateSet->AddState (AccessibleStateType::MANAGES_DESCENDANTS);
+ pStateSet->AddState (AccessibleStateType::FOCUSABLE);
+ if (mbIsFocused)
+ pStateSet->AddState (AccessibleStateType::FOCUSED);
+
+ return pStateSet;
+}
+
+// -----------------------------------------------------------------------------
+
+Locale SAL_CALL ToolbarMenuAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const ::rtl::OUString aEmptyStr;
+ Reference< XAccessible > xParent( getAccessibleParent() );
+ Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
+
+ if( xParent.is() )
+ {
+ Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+
+ if( xParentContext.is() )
+ aRet = xParentContext->getLocale ();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::const_iterator aIter = mxEventListeners.begin();
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ bFound = true;
+ else
+ aIter++;
+ }
+
+ if (!bFound)
+ mxEventListeners.push_back( rxListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::iterator aIter = mxEventListeners.begin();
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ {
+ mxEventListeners.erase( aIter );
+ bFound = true;
+ }
+ else
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ToolbarMenuAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const awt::Rectangle aRect( getBounds() );
+ const Point aSize( aRect.Width, aRect.Height );
+ const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
+
+ return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ Reference< XAccessible > xRet;
+
+ const Point aVclPoint( aPoint.X, aPoint.Y );
+
+ const int nEntryCount = mpParent->maEntryVector.size();
+ for( int nEntry = 0; (nEntry < nEntryCount) && !xRet.is(); nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpParent->maEntryVector[nEntry];
+ if( pEntry && pEntry->maRect.IsInside( aVclPoint ) )
+ {
+ if( pEntry->mpControl )
+ {
+ awt::Point aChildPoint( aPoint.X - pEntry->maRect.Left(), aPoint.Y - pEntry->maRect.Top() );
+ Reference< XAccessibleComponent > xComp( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ xRet = xComp->getAccessibleAtPoint(aChildPoint);
+ }
+ else
+ {
+ xRet = Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY );
+ }
+ }
+ }
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL ToolbarMenuAcc::getBounds() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aOutPos( mpParent->mrMenu.GetPosPixel() );
+ const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() );
+ awt::Rectangle aRet;
+
+ aRet.X = aOutPos.X();
+ aRet.Y = aOutPos.Y();
+ aRet.Width = aOutSize.Width();
+ aRet.Height = aOutSize.Height();
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuAcc::getLocation() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aOutPos( mpParent->mrMenu.GetPosPixel() );
+ return awt::Point( aOutPos.X(), aOutPos.Y() );
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuAcc::getLocationOnScreen() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( Point() ) );
+ return awt::Point( aScreenPos.X(), aScreenPos.Y() );
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Size SAL_CALL ToolbarMenuAcc::getSize() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() );
+ return awt::Size( aOutSize.Width(), aOutSize.Height() );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::grabFocus() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ mpParent->mrMenu.GrabFocus();
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL ToolbarMenuAcc::getAccessibleKeyBinding() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getForeground() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getBackground() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ mpParent->selectAccessibleChild( nChildIndex );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ToolbarMenuAcc::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+ return mpParent->isAccessibleChildSelected( nChildIndex );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::clearAccessibleSelection() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+ mpParent->clearAccessibleSelection();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::selectAllAccessibleChildren() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ // unsupported due to single selection only
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChildCount() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ return mpParent->mnHighlightedEntry != -1 ? 1 : 0;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ if( (mpParent->mnHighlightedEntry != -1) && (nSelectedChildIndex == 0) )
+ {
+ ToolbarMenuEntry* pEntry = mpParent->maEntryVector[ mpParent->mnHighlightedEntry ];
+ if( pEntry )
+ {
+ if( pEntry->mpControl )
+ {
+ Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ return xSel->getSelectedAccessibleChild(0);
+ }
+ else
+ return Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY );
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // Because of the single selection we can reset the whole selection when
+ // the specified child is currently selected.
+ if (isAccessibleChildSelected(nChildIndex))
+ mpParent->clearAccessibleSelection();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::disposing (void)
+{
+ EventListenerVector aListenerListCopy;
+
+ {
+ // Make a copy of the list and clear the original.
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard (m_aMutex);
+ aListenerListCopy = mxEventListeners;
+ mxEventListeners.clear();
+
+ // Reset the pointer to the parent. It has to be the one who has
+ // disposed us because he is dying.
+ mpParent = NULL;
+ }
+
+ // Inform all listeners that this objects is disposing.
+ EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin());
+ EventObject aEvent (static_cast<XAccessible*>(this));
+ while(aListenerIterator != aListenerListCopy.end())
+ {
+ try
+ {
+ (*aListenerIterator)->disposing (aEvent);
+ }
+ catch( Exception& )
+ {
+ // Ignore exceptions.
+ }
+
+ ++aListenerIterator;
+ }
+}
+
+void ToolbarMenuAcc::ThrowIfDisposed (void) throw (DisposedException)
+{
+ if(rBHelper.bDisposed || rBHelper.bInDispose || !mpParent)
+ {
+ throw DisposedException ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), static_cast<XWeak*>(this));
+ }
+}
+
+// -----------------------
+// - ToolbarMenuEntryAcc -
+// -----------------------
+
+ToolbarMenuEntryAcc::ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent )
+: ToolbarMenuEntryAccBase( m_aMutex )
+, mpParent( pParent )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ToolbarMenuEntryAcc::~ToolbarMenuEntryAcc()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenuEntryAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
+{
+ if( nEventId )
+ {
+ EventListenerVector aTmpListeners( mxEventListeners );
+ ::std::vector< Reference< XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() );
+ AccessibleEventObject aEvtObject;
+
+ aEvtObject.EventId = nEventId;
+ aEvtObject.Source = static_cast<XWeak*>(this);
+ aEvtObject.NewValue = rNewValue;
+ aEvtObject.OldValue = rOldValue;
+
+ while( aIter != aTmpListeners.end() )
+ {
+ (*aIter)->notifyEvent( aEvtObject );
+ aIter++;
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::disposing (void)
+{
+ EventListenerVector aListenerListCopy;
+
+ {
+ // Make a copy of the list and clear the original.
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard (m_aMutex);
+ aListenerListCopy = mxEventListeners;
+ mxEventListeners.clear();
+
+ // Reset the pointer to the parent. It has to be the one who has
+ // disposed us because he is dying.
+ mpParent = NULL;
+ }
+
+ // Inform all listeners that this objects is disposing.
+ EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin());
+ EventObject aEvent (static_cast<XAccessible*>(this));
+ while(aListenerIterator != aListenerListCopy.end())
+ {
+ try
+ {
+ (*aListenerIterator)->disposing (aEvent);
+ }
+ catch( Exception& )
+ {
+ // Ignore exceptions.
+ }
+
+ ++aListenerIterator;
+ }
+}
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleContext > SAL_CALL ToolbarMenuEntryAcc::getAccessibleContext() throw (RuntimeException)
+{
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleChildCount() throw (RuntimeException)
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleParent() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ Reference< XAccessible > xRet;
+
+ if( mpParent )
+ xRet = mpParent->mrMenu.GetAccessible();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleIndexInParent() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // The index defaults to -1 to indicate the child does not belong to its
+ // parent.
+ sal_Int32 nIndexInParent = -1;
+
+ if( mpParent )
+ {
+ Reference< XAccessibleContext > xParent( mpParent->mrMenu.GetAccessible(), UNO_QUERY );
+
+ if( xParent.is() )
+ {
+ Reference< XAccessible > xThis( this );
+
+ const sal_Int32 nCount = xParent->getAccessibleChildCount();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ if( xParent->getAccessibleChild(nIndex) == xThis )
+ {
+ nIndexInParent = nIndex;
+ break;
+ }
+ }
+ }
+ }
+
+ return nIndexInParent;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ToolbarMenuEntryAcc::getAccessibleRole() throw (RuntimeException)
+{
+ return AccessibleRole::LIST_ITEM;
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleDescription() throw (RuntimeException)
+{
+ return ::rtl::OUString();
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleName() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ String aRet;
+
+ if( mpParent )
+ {
+ aRet = mpParent->maText;
+
+ if( !aRet.Len() )
+ {
+ aRet = String( RTL_CONSTASCII_USTRINGPARAM( "Item " ) );
+ aRet += String::CreateFromInt32( mpParent->mnEntryId );
+ }
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleRelationSet() throw (RuntimeException)
+{
+ return Reference< XAccessibleRelationSet >();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleStateSet() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper;
+
+ if( mpParent )
+ {
+ pStateSet->AddState (AccessibleStateType::ENABLED);
+ pStateSet->AddState (AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (AccessibleStateType::SHOWING);
+ pStateSet->AddState (AccessibleStateType::VISIBLE);
+ pStateSet->AddState (AccessibleStateType::TRANSIENT);
+ if( mpParent->mnEntryId != TITLE_ID )
+ {
+ pStateSet->AddState( AccessibleStateType::SELECTABLE );
+
+ // SELECTED
+ if( mpParent->mrMenu.getHighlightedEntryId() == mpParent->mnEntryId )
+ pStateSet->AddState( AccessibleStateType::SELECTED );
+ }
+ }
+
+ return pStateSet;
+}
+
+// -----------------------------------------------------------------------------
+
+Locale SAL_CALL ToolbarMenuEntryAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException)
+{
+ const ::rtl::OUString aEmptyStr;
+ Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
+
+ Reference< XAccessible > xParent( getAccessibleParent() );
+ if( xParent.is() )
+ {
+ Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+
+ if( xParentContext.is() )
+ aRet = xParentContext->getLocale();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ const ::vos::OGuard aGuard( maMutex );
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::const_iterator aIter( mxEventListeners.begin() );
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ bFound = true;
+ else
+ aIter++;
+ }
+
+ if (!bFound)
+ mxEventListeners.push_back( rxListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ const ::vos::OGuard aGuard( maMutex );
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::iterator aIter = mxEventListeners.begin();
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ {
+ mxEventListeners.erase( aIter );
+ bFound = true;
+ }
+ else
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ToolbarMenuEntryAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ const Point aSize( aRect.Width, aRect.Height );
+ const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
+
+ return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
+{
+ Reference< XAccessible > xRet;
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL ToolbarMenuEntryAcc::getBounds() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ awt::Rectangle aRet;
+
+ if( mpParent )
+ {
+ Rectangle aRect( mpParent->maRect );
+ Point aOrigin;
+ Rectangle aParentRect( aOrigin, mpParent->mrMenu.GetOutputSizePixel() );
+
+ aRect.Intersection( aParentRect );
+
+ aRet.X = aRect.Left();
+ aRet.Y = aRect.Top();
+ aRet.Width = aRect.GetWidth();
+ aRet.Height = aRect.GetHeight();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocation() throw (RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ return awt::Point( aRect.X, aRect.Y );
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocationOnScreen() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ awt::Point aRet;
+
+ if( mpParent )
+ {
+ const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) );
+
+ aRet.X = aScreenPos.X();
+ aRet.Y = aScreenPos.Y();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Size SAL_CALL ToolbarMenuEntryAcc::getSize() throw (RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ awt::Size aRet;
+
+ aRet.Width = aRect.Width;
+ aRet.Height = aRect.Height;
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::grabFocus() throw (RuntimeException)
+{
+ // nothing to do
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL ToolbarMenuEntryAcc::getAccessibleKeyBinding() throw (RuntimeException)
+{
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getForeground( ) throw (RuntimeException)
+{
+ return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor());
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getBackground( ) throw (RuntimeException)
+{
+ return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor());
+}
+
+}
diff --git a/svtools/source/control/toolbarmenuimp.hxx b/svtools/source/control/toolbarmenuimp.hxx
new file mode 100644
index 000000000000..d1de4f704b76
--- /dev/null
+++ b/svtools/source/control/toolbarmenuimp.hxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <vos/mutex.hxx>
+#include <vcl/image.hxx>
+#include <vcl/menu.hxx>
+
+#include <cppuhelper/compbase4.hxx>
+#include <cppuhelper/compbase5.hxx>
+#include <comphelper/broadcasthelper.hxx>
+
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include <rtl/ref.hxx>
+
+#include <vector>
+
+#include "framestatuslistener.hxx"
+
+#include "svtools/valueset.hxx"
+
+namespace svtools {
+
+struct ToolbarMenu_Impl;
+class ToolbarMenu;
+class ToolbarMenuEntry;
+
+typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener > > EventListenerVector;
+typedef std::vector< ToolbarMenuEntry * > ToolbarMenuEntryVector;
+
+const int EXTRAITEMHEIGHT = 0; // 4;
+const int SEPARATOR_HEIGHT = 4;
+const int TITLE_ID = -1;
+const int BORDER_X = 0;
+const int BORDER_Y = 0;
+
+// --------------------
+// - ToolbarMenuEntry -
+// --------------------
+
+class ToolbarMenuEntry
+{
+public:
+ ToolbarMenu& mrMenu;
+
+ int mnEntryId;
+ MenuItemBits mnBits;
+ Size maSize;
+
+ bool mbHasText;
+ bool mbHasImage;
+ bool mbChecked;
+ bool mbEnabled;
+
+ String maText;
+ Image maImage;
+ Control* mpControl;
+ Rectangle maRect;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > mxAccContext;
+
+public:
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits );
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits );
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits );
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits );
+ ~ToolbarMenuEntry();
+
+ void init( int nEntryId, MenuItemBits nBits );
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& GetAccessible( bool bCreate = false );
+
+ sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ bool HasCheck() const
+ {
+ return mbChecked || ( mnBits & ( MIB_RADIOCHECK | MIB_CHECKABLE | MIB_AUTOCHECK ) );
+ }
+};
+
+// ---------------
+// - ToolbarMenuAcc -
+// ---------------
+
+typedef ::cppu::WeakComponentImplHelper5<
+ ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::accessibility::XAccessibleSelection >
+ ToolbarMenuAccComponentBase;
+
+class ToolbarMenuAcc :
+ public ::comphelper::OBaseMutex,
+ public ToolbarMenuAccComponentBase
+{
+public:
+
+ ToolbarMenuAcc( ToolbarMenu_Impl& rParent );
+ ~ToolbarMenuAcc();
+
+ void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
+
+public:
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::addEventListener;
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::removeEventListener;
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) 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 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) 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);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) 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& aPoint ) 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 void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) 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);
+
+ // 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);
+
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+
+private:
+ EventListenerVector mxEventListeners;
+ ToolbarMenu_Impl* mpParent;
+ /// The current FOCUSED state.
+ bool mbIsFocused;
+
+ void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
+
+ /** Tell all listeners that the object is dying. This callback is
+ usually called from the WeakComponentImplHelper class.
+ */
+ virtual void SAL_CALL disposing (void);
+
+ /** Check whether or not the object has been disposed (or is in the
+ state of beeing disposed). If that is the case then
+ DisposedException is thrown to inform the (indirect) caller of the
+ foul deed.
+ */
+ void ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException);
+};
+
+// -----------------------
+// - ToolbarMenuEntryAcc -
+// -----------------------
+
+typedef ::cppu::WeakComponentImplHelper4< ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent > ToolbarMenuEntryAccBase;
+
+class ToolbarMenuEntryAcc : public ::comphelper::OBaseMutex,
+ public ToolbarMenuEntryAccBase
+{
+public:
+ ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent );
+ ~ToolbarMenuEntryAcc();
+
+ void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ using ToolbarMenuEntryAccBase::addEventListener;
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ using ToolbarMenuEntryAccBase::removeEventListener;
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) 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 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) 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);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) 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& aPoint ) 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 void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) 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);
+
+private:
+ EventListenerVector mxEventListeners;
+ ::vos::OMutex maMutex;
+ ToolbarMenuEntry* mpParent;
+
+ /** Tell all listeners that the object is dying. This callback is
+ usually called from the WeakComponentImplHelper class.
+ */
+ virtual void SAL_CALL disposing (void);
+};
+
+// -----------------------------------------------------------------------------
+
+struct ToolbarMenu_Impl
+{
+ ToolbarMenu& mrMenu;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame;
+ rtl::Reference< svt::FrameStatusListener > mxStatusListener;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxServiceManager;
+ rtl::Reference< ToolbarMenuAcc > mxAccessible;
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxOldSelection;
+
+ ToolbarMenuEntryVector maEntryVector;
+
+ int mnCheckPos;
+ int mnImagePos;
+ int mnTextPos;
+
+ int mnHighlightedEntry;
+ int mnSelectedEntry;
+ int mnLastColumn;
+
+ Size maSize;
+
+ Link maSelectHdl;
+
+ ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame );
+ ~ToolbarMenu_Impl();
+
+ void setAccessible( ToolbarMenuAcc* pAccessible );
+
+ void fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ bool hasAccessibleListeners();
+
+ sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ sal_Bool isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ void clearAccessibleSelection();
+
+ ToolbarMenuEntry* implGetEntry( int nEntry ) const;
+ void notifyHighlightedEntry();
+
+ void implHighlightControl( USHORT nCode, Control* pControl );
+};
+
+}
diff --git a/svtools/source/control/urlcontrol.cxx b/svtools/source/control/urlcontrol.cxx
new file mode 100644
index 000000000000..788948355965
--- /dev/null
+++ b/svtools/source/control/urlcontrol.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_svtools.hxx"
+
+#include <svtools/urlcontrol.hxx>
+#include "svl/filenotation.hxx"
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ //=====================================================================
+ //= OFileURLControl
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OFileURLControl::OFileURLControl(Window* _pParent)
+ :SvtURLBox(_pParent, INET_PROT_FILE)
+ {
+ DisableHistory();
+ }
+
+ //---------------------------------------------------------------------
+ OFileURLControl::OFileURLControl(Window* _pParent, const ResId& _rId)
+ :SvtURLBox(_pParent, _rId, INET_PROT_FILE)
+ {
+ DisableHistory();
+ }
+
+ //---------------------------------------------------------------------
+ long OFileURLControl::PreNotify( NotifyEvent& _rNEvt )
+ {
+ if (GetSubEdit() == _rNEvt.GetWindow())
+ if (EVENT_KEYINPUT == _rNEvt.GetType())
+ if (KEY_RETURN == _rNEvt.GetKeyEvent()->GetKeyCode().GetCode())
+ if (IsInDropDown())
+ m_sPreservedText = GetURL();
+
+ return SvtURLBox::PreNotify(_rNEvt);
+ }
+
+ //---------------------------------------------------------------------
+ long OFileURLControl::Notify( NotifyEvent& _rNEvt )
+ {
+ if (GetSubEdit() == _rNEvt.GetWindow())
+ if (EVENT_KEYINPUT == _rNEvt.GetType())
+ if (KEY_RETURN == _rNEvt.GetKeyEvent()->GetKeyCode().GetCode())
+ if (IsInDropDown())
+ {
+ long nReturn = SvtURLBox::Notify(_rNEvt);
+
+ // build a system dependent (thus more user readable) file name
+ OFileNotation aTransformer(m_sPreservedText, OFileNotation::N_URL);
+ SetText(aTransformer.get(OFileNotation::N_SYSTEM));
+ Modify();
+
+ // Update the pick list
+ UpdatePickList();
+
+ return nReturn;
+ }
+
+ return SvtURLBox::Notify(_rNEvt);
+ }
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
+
diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx
new file mode 100644
index 000000000000..66da5636d89c
--- /dev/null
+++ b/svtools/source/control/valueacc.cxx
@@ -0,0 +1,1258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SV_VALUESET_CXX
+
+#include <unotools/accessiblestatesethelper.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/valueset.hxx>
+#include "valueimp.hxx"
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+using namespace ::com::sun::star;
+
+// ----------------
+// - ValueSetItem -
+// ----------------
+
+ValueSetItem::ValueSetItem( ValueSet& rParent ) :
+ mrParent( rParent ),
+ mnId( 0 ),
+ mnBits( 0 ),
+ mpData( NULL ),
+ mpxAcc( NULL )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem::~ValueSetItem()
+{
+ if( mpxAcc )
+ {
+ static_cast< ValueItemAcc* >( mpxAcc->get() )->ParentDestroyed();
+ delete mpxAcc;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > ValueSetItem::GetAccessible( bool bIsTransientChildrenDisabled )
+{
+ if( !mpxAcc )
+ mpxAcc = new uno::Reference< accessibility::XAccessible >( new ValueItemAcc( this, bIsTransientChildrenDisabled ) );
+
+ return *mpxAcc;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSetItem::ClearAccessible()
+{
+ if( mpxAcc )
+ delete mpxAcc, mpxAcc = NULL;
+}
+
+
+// ---------------
+// - ValueSetAcc -
+// ---------------
+
+ValueSetAcc::ValueSetAcc( ValueSet* pParent, bool bIsTransientChildrenDisabled ) :
+ ValueSetAccComponentBase (m_aMutex),
+ mpParent( pParent ),
+ mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled ),
+ mbIsFocused(false)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ValueSetAcc::~ValueSetAcc()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSetAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
+{
+ if( nEventId )
+ {
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners );
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() );
+ accessibility::AccessibleEventObject aEvtObject;
+
+ aEvtObject.EventId = nEventId;
+ aEvtObject.Source = static_cast<uno::XWeak*>(this);
+ aEvtObject.NewValue = rNewValue;
+ aEvtObject.OldValue = rOldValue;
+
+ while( aIter != aTmpListeners.end() )
+ {
+ try
+ {
+ (*aIter)->notifyEvent( aEvtObject );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+const uno::Sequence< sal_Int8 >& ValueSetAcc::getUnoTunnelId()
+{
+ static 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;
+}
+
+// -----------------------------------------------------------------------------
+
+ValueSetAcc* ValueSetAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
+ throw()
+{
+ try
+ {
+ uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY );
+ return( xUnoTunnel.is() ? reinterpret_cast<ValueSetAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( ValueSetAcc::getUnoTunnelId() ))) : NULL );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ return NULL;
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+void ValueSetAcc::GetFocus (void)
+{
+ mbIsFocused = true;
+
+ // Boradcast the state change.
+ ::com::sun::star::uno::Any aOldState, aNewState;
+ aNewState <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
+ FireAccessibleEvent(
+ ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED,
+ aOldState, aNewState);
+}
+
+// -----------------------------------------------------------------------------
+
+void ValueSetAcc::LoseFocus (void)
+{
+ mbIsFocused = false;
+
+ // Boradcast the state change.
+ ::com::sun::star::uno::Any aOldState, aNewState;
+ aOldState <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
+ FireAccessibleEvent(
+ ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED,
+ aOldState, aNewState);
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueSetAcc::getAccessibleContext()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueSetAcc::getAccessibleChildCount()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ sal_Int32 nCount = mpParent->ImplGetVisibleItemCount();
+ if (HasNoneField())
+ nCount += 1;
+ return nCount;
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleChild( sal_Int32 i )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ uno::Reference< accessibility::XAccessible > xRet;
+ ValueSetItem* pItem = getItem (sal::static_int_cast< USHORT >(i));
+
+ if( pItem )
+ xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleParent()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ Window* pParent = mpParent->GetParent();
+ uno::Reference< accessibility::XAccessible > xRet;
+
+ if( pParent )
+ xRet = pParent->GetAccessible();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueSetAcc::getAccessibleIndexInParent()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ Window* pParent = mpParent->GetParent();
+ sal_Int32 nRet = 0;
+
+ if( pParent )
+ {
+ sal_Bool bFound = sal_False;
+
+ for( USHORT i = 0, nCount = pParent->GetChildCount(); ( i < nCount ) && !bFound; i++ )
+ {
+ if( pParent->GetChild( i ) == mpParent )
+ {
+ nRet = i;
+ bFound = sal_True;
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ValueSetAcc::getAccessibleRole()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ // #i73746# As the Java Access Bridge (v 2.0.1) uses "managesDescendants"
+ // always if the role is LIST, we need a different role in this case
+ return (mbIsTransientChildrenDisabled
+ ? accessibility::AccessibleRole::PANEL
+ : accessibility::AccessibleRole::LIST );
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ValueSetAcc::getAccessibleDescription()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ String aRet( RTL_CONSTASCII_USTRINGPARAM( "ValueSet" ) );
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ValueSetAcc::getAccessibleName()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ String aRet;
+
+ if ( mpParent )
+ aRet = mpParent->GetAccessibleName();
+
+ if ( !aRet.Len() )
+ {
+ Window* pLabel = mpParent->GetLabeledBy();
+ if ( pLabel && pLabel != mpParent )
+ aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() );
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueSetAcc::getAccessibleRelationSet()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ return uno::Reference< accessibility::XAccessibleRelationSet >();
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL ValueSetAcc::getAccessibleStateSet()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
+
+ // Set some states.
+ pStateSet->AddState (accessibility::AccessibleStateType::ENABLED);
+ pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (accessibility::AccessibleStateType::SHOWING);
+ pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE);
+ if ( !mbIsTransientChildrenDisabled )
+ pStateSet->AddState (accessibility::AccessibleStateType::MANAGES_DESCENDANTS);
+ pStateSet->AddState (accessibility::AccessibleStateType::FOCUSABLE);
+ if (mbIsFocused)
+ pStateSet->AddState (accessibility::AccessibleStateType::FOCUSED);
+
+ return pStateSet;
+}
+
+// -----------------------------------------------------------------------------
+
+lang::Locale SAL_CALL ValueSetAcc::getLocale()
+ throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const ::rtl::OUString aEmptyStr;
+ uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() );
+ lang::Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
+
+ if( xParent.is() )
+ {
+ uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+
+ if( xParentContext.is() )
+ aRet = xParentContext->getLocale ();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::addEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (m_aMutex);
+
+ if( rxListener.is() )
+ {
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter = mxEventListeners.begin();
+ sal_Bool bFound = sal_False;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ bFound = sal_True;
+ else
+ aIter++;
+ }
+
+ if (!bFound)
+ mxEventListeners.push_back( rxListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::removeEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (m_aMutex);
+
+ if( rxListener.is() )
+ {
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter = mxEventListeners.begin();
+ sal_Bool bFound = sal_False;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ {
+ mxEventListeners.erase( aIter );
+ bFound = sal_True;
+ }
+ else
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ValueSetAcc::containsPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const awt::Rectangle aRect( getBounds() );
+ const Point aSize( aRect.Width, aRect.Height );
+ const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
+
+ return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleAtPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const USHORT nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) );
+ uno::Reference< accessibility::XAccessible > xRet;
+
+ if( VALUESET_ITEM_NOTFOUND != nItemId )
+ {
+ const USHORT nItemPos = mpParent->GetItemPos( nItemId );
+
+ if( VALUESET_ITEM_NONEITEM != nItemPos )
+ {
+ ValueSetItem* pItem = mpParent->mpImpl->mpItemList->GetObject( nItemPos );
+
+ if( ( pItem->meType != VALUESETITEM_SPACE ) && !pItem->maRect.IsEmpty() )
+ xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
+ }
+ }
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL ValueSetAcc::getBounds()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aOutPos( mpParent->GetPosPixel() );
+ const Size aOutSize( mpParent->GetOutputSizePixel() );
+ awt::Rectangle aRet;
+
+ aRet.X = aOutPos.X();
+ aRet.Y = aOutPos.Y();
+ aRet.Width = aOutSize.Width();
+ aRet.Height = aOutSize.Height();
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ValueSetAcc::getLocation()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const awt::Rectangle aRect( getBounds() );
+ awt::Point aRet;
+
+ aRet.X = aRect.X;
+ aRet.Y = aRect.Y;
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ValueSetAcc::getLocationOnScreen()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aScreenPos( mpParent->OutputToAbsoluteScreenPixel( Point() ) );
+ awt::Point aRet;
+
+ aRet.X = aScreenPos.X();
+ aRet.Y = aScreenPos.Y();
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Size SAL_CALL ValueSetAcc::getSize()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const awt::Rectangle aRect( getBounds() );
+ awt::Size aRet;
+
+ aRet.Width = aRect.Width;
+ aRet.Height = aRect.Height;
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::grabFocus()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ mpParent->GrabFocus();
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Any SAL_CALL ValueSetAcc::getAccessibleKeyBinding()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ return uno::Any();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueSetAcc::getForeground( )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueSetAcc::getBackground( )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ValueSetItem* pItem = getItem (sal::static_int_cast< USHORT >(nChildIndex));
+
+ if(pItem != NULL)
+ {
+ mpParent->SelectItem( pItem->mnId );
+ mpParent->Select ();
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ValueSetAcc::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ValueSetItem* pItem = getItem (sal::static_int_cast< USHORT >(nChildIndex));
+ sal_Bool bRet = sal_False;
+
+ if (pItem != NULL)
+ bRet = mpParent->IsItemSelected( pItem->mnId );
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::clearAccessibleSelection()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ mpParent->SetNoSelection();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::selectAllAccessibleChildren()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ // unsupported due to single selection only
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueSetAcc::getSelectedAccessibleChildCount()
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ sal_Int32 nRet = 0;
+
+ for( USHORT i = 0, nCount = getItemCount(); i < nCount; i++ )
+ {
+ ValueSetItem* pItem = getItem (i);
+
+ if( pItem && mpParent->IsItemSelected( pItem->mnId ) )
+ ++nRet;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ uno::Reference< accessibility::XAccessible > xRet;
+
+ for( USHORT i = 0, nCount = getItemCount(), nSel = 0; ( i < nCount ) && !xRet.is(); i++ )
+ {
+ ValueSetItem* pItem = getItem(i);
+
+ if( pItem && mpParent->IsItemSelected( pItem->mnId ) && ( nSelectedChildIndex == static_cast< sal_Int32 >( nSel++ ) ) )
+ xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
+ }
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueSetAcc::deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // Because of the single selection we can reset the whole selection when
+ // the specified child is currently selected.
+ if (isAccessibleChildSelected(nChildIndex))
+ mpParent->SetNoSelection();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int64 SAL_CALL ValueSetAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException )
+{
+ sal_Int64 nRet;
+
+ if( ( rId.getLength() == 16 ) && ( 0 == rtl_compareMemory( ValueSetAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
+ nRet = reinterpret_cast< sal_Int64 >( this );
+ else
+ nRet = 0;
+
+ return nRet;
+}
+
+
+
+
+void SAL_CALL ValueSetAcc::disposing (void)
+{
+ ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> > aListenerListCopy;
+
+ {
+ // Make a copy of the list and clear the original.
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard (m_aMutex);
+ aListenerListCopy = mxEventListeners;
+ mxEventListeners.clear();
+
+ // Reset the pointer to the parent. It has to be the one who has
+ // disposed us because he is dying.
+ mpParent = NULL;
+ }
+
+ // Inform all listeners that this objects is disposing.
+ ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> >::const_iterator
+ aListenerIterator (aListenerListCopy.begin());
+ lang::EventObject aEvent (static_cast<accessibility::XAccessible*>(this));
+ while (aListenerIterator != aListenerListCopy.end())
+ {
+ try
+ {
+ (*aListenerIterator)->disposing (aEvent);
+ }
+ catch( uno::Exception& )
+ {
+ // Ignore exceptions.
+ }
+
+ ++aListenerIterator;
+ }
+}
+
+
+USHORT ValueSetAcc::getItemCount (void) const
+{
+ USHORT nCount = mpParent->ImplGetVisibleItemCount();
+ // When the None-Item is visible then increase the number of items by
+ // one.
+ if (HasNoneField())
+ nCount += 1;
+ return nCount;
+}
+
+
+ValueSetItem* ValueSetAcc::getItem (USHORT nIndex) const
+{
+ ValueSetItem* pItem = NULL;
+
+ if (HasNoneField())
+ {
+ if (nIndex == 0)
+ // When present the first item is the then allways visible none field.
+ pItem = mpParent->ImplGetItem (VALUESET_ITEM_NONEITEM);
+ else
+ // Shift down the index to compensate for the none field.
+ nIndex -= 1;
+ }
+ if (pItem == NULL)
+ pItem = mpParent->ImplGetVisibleItem (static_cast<USHORT>(nIndex));
+
+ return pItem;
+}
+
+
+
+
+void ValueSetAcc::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ OSL_TRACE ("Calling disposed object. Throwing exception:");
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+ else
+ {
+ DBG_ASSERT (mpParent!=NULL, "ValueSetAcc not disposed but mpParent == NULL");
+ }
+}
+
+
+
+sal_Bool ValueSetAcc::IsDisposed (void)
+{
+ return (rBHelper.bDisposed || rBHelper.bInDispose);
+}
+
+
+
+
+bool ValueSetAcc::HasNoneField (void) const
+{
+ DBG_ASSERT (mpParent!=NULL, "ValueSetAcc::HasNoneField called with mpParent==NULL");
+ return ((mpParent->GetStyle() & WB_NONEFIELD) != 0);
+}
+
+
+
+
+// ----------------
+// - ValueItemAcc -
+// ----------------
+
+ValueItemAcc::ValueItemAcc( ValueSetItem* pParent, bool bIsTransientChildrenDisabled ) :
+ mpParent( pParent ),
+ mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ValueItemAcc::~ValueItemAcc()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ValueItemAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
+{
+ if( nEventId )
+ {
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners );
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() );
+ accessibility::AccessibleEventObject aEvtObject;
+
+ aEvtObject.EventId = nEventId;
+ aEvtObject.Source = static_cast<uno::XWeak*>(this);
+ aEvtObject.NewValue = rNewValue;
+ aEvtObject.OldValue = rOldValue;
+
+ while( aIter != aTmpListeners.end() )
+ {
+ (*aIter)->notifyEvent( aEvtObject );
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void ValueItemAcc::ParentDestroyed()
+{
+ const ::vos::OGuard aGuard( maMutex );
+ mpParent = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+const uno::Sequence< sal_Int8 >& ValueItemAcc::getUnoTunnelId()
+{
+ static 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;
+}
+
+// -----------------------------------------------------------------------------
+
+ValueItemAcc* ValueItemAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
+ throw()
+{
+ try
+ {
+ uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY );
+ return( xUnoTunnel.is() ? reinterpret_cast<ValueItemAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( ValueItemAcc::getUnoTunnelId() ))) : NULL );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ return NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueItemAcc::getAccessibleContext()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueItemAcc::getAccessibleChildCount()
+ throw (uno::RuntimeException)
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleChild( sal_Int32 )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ throw lang::IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleParent()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ uno::Reference< accessibility::XAccessible > xRet;
+
+ if( mpParent )
+ xRet = mpParent->mrParent.GetAccessible();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueItemAcc::getAccessibleIndexInParent()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // The index defaults to -1 to indicate the child does not belong to its
+ // parent.
+ sal_Int32 nIndexInParent = -1;
+
+ if( mpParent )
+ {
+ bool bDone = false;
+
+ USHORT nCount = mpParent->mrParent.ImplGetVisibleItemCount();
+ ValueSetItem* pItem;
+ for (USHORT i=0; i<nCount && !bDone; i++)
+ {
+ // Guard the retrieval of the i-th child with a try/catch block
+ // just in case the number of children changes in the mean time.
+ try
+ {
+ pItem = mpParent->mrParent.ImplGetVisibleItem (i);
+ }
+ catch (lang::IndexOutOfBoundsException aException)
+ {
+ pItem = NULL;
+ }
+
+ // Do not create an accessible object for the test.
+ if (pItem != NULL && pItem->mpxAcc != NULL)
+ if (pItem->GetAccessible( mbIsTransientChildrenDisabled ).get() == this )
+ {
+ nIndexInParent = i;
+ bDone = true;
+ }
+ }
+ }
+
+ return nIndexInParent;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole()
+ throw (uno::RuntimeException)
+{
+ return accessibility::AccessibleRole::LIST_ITEM;
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ValueItemAcc::getAccessibleDescription()
+ throw (uno::RuntimeException)
+{
+ return ::rtl::OUString();
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ValueItemAcc::getAccessibleName()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ String aRet;
+
+ if( mpParent )
+ {
+ aRet = mpParent->maText;
+
+ if( !aRet.Len() )
+ {
+ aRet = String( RTL_CONSTASCII_USTRINGPARAM( "Item " ) );
+ aRet += String::CreateFromInt32( mpParent->mnId );
+ }
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueItemAcc::getAccessibleRelationSet()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< accessibility::XAccessibleRelationSet >();
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL ValueItemAcc::getAccessibleStateSet()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper;
+
+ if( mpParent )
+ {
+ pStateSet->AddState (accessibility::AccessibleStateType::ENABLED);
+ pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (accessibility::AccessibleStateType::SHOWING);
+ pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE);
+ if ( !mbIsTransientChildrenDisabled )
+ pStateSet->AddState (accessibility::AccessibleStateType::TRANSIENT);
+
+ // SELECTABLE
+ pStateSet->AddState( accessibility::AccessibleStateType::SELECTABLE );
+ // pStateSet->AddState( accessibility::AccessibleStateType::FOCUSABLE );
+
+ // SELECTED
+ if( mpParent->mrParent.GetSelectItemId() == mpParent->mnId )
+ {
+ pStateSet->AddState( accessibility::AccessibleStateType::SELECTED );
+ // pStateSet->AddState( accessibility::AccessibleStateType::FOCUSED );
+ }
+ }
+
+ return pStateSet;
+}
+
+// -----------------------------------------------------------------------------
+
+lang::Locale SAL_CALL ValueItemAcc::getLocale()
+ throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const ::rtl::OUString aEmptyStr;
+ uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() );
+ lang::Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
+
+ if( xParent.is() )
+ {
+ uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+
+ if( xParentContext.is() )
+ aRet = xParentContext->getLocale();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueItemAcc::addEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
+ throw (uno::RuntimeException)
+{
+ const ::vos::OGuard aGuard( maMutex );
+
+ if( rxListener.is() )
+ {
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter = mxEventListeners.begin();
+ sal_Bool bFound = sal_False;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ bFound = sal_True;
+ else
+ aIter++;
+ }
+
+ if (!bFound)
+ mxEventListeners.push_back( rxListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueItemAcc::removeEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
+ throw (uno::RuntimeException)
+{
+ const ::vos::OGuard aGuard( maMutex );
+
+ if( rxListener.is() )
+ {
+ ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter = mxEventListeners.begin();
+ sal_Bool bFound = sal_False;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ {
+ mxEventListeners.erase( aIter );
+ bFound = sal_True;
+ }
+ else
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ValueItemAcc::containsPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ const Point aSize( aRect.Width, aRect.Height );
+ const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
+
+ return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleAtPoint( const awt::Point& )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessible > xRet;
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL ValueItemAcc::getBounds()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ awt::Rectangle aRet;
+
+ if( mpParent )
+ {
+ Rectangle aRect( mpParent->maRect );
+ Point aOrigin;
+ Rectangle aParentRect( aOrigin, mpParent->mrParent.GetOutputSizePixel() );
+
+ aRect.Intersection( aParentRect );
+
+ aRet.X = aRect.Left();
+ aRet.Y = aRect.Top();
+ aRet.Width = aRect.GetWidth();
+ aRet.Height = aRect.GetHeight();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ValueItemAcc::getLocation()
+ throw (uno::RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ awt::Point aRet;
+
+ aRet.X = aRect.X;
+ aRet.Y = aRect.Y;
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ValueItemAcc::getLocationOnScreen()
+ throw (uno::RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ awt::Point aRet;
+
+ if( mpParent )
+ {
+ const Point aScreenPos( mpParent->mrParent.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) );
+
+ aRet.X = aScreenPos.X();
+ aRet.Y = aScreenPos.Y();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Size SAL_CALL ValueItemAcc::getSize()
+ throw (uno::RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ awt::Size aRet;
+
+ aRet.Width = aRect.Width;
+ aRet.Height = aRect.Height;
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ValueItemAcc::grabFocus()
+ throw (uno::RuntimeException)
+{
+ // nothing to do
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Any SAL_CALL ValueItemAcc::getAccessibleKeyBinding()
+ throw (uno::RuntimeException)
+{
+ return uno::Any();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueItemAcc::getForeground( )
+ throw (uno::RuntimeException)
+{
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ValueItemAcc::getBackground( )
+ throw (uno::RuntimeException)
+{
+ UINT32 nColor;
+ if (mpParent && mpParent->meType == VALUESETITEM_COLOR)
+ nColor = mpParent->maColor.GetColor();
+ else
+ nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int64 SAL_CALL ValueItemAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException )
+{
+ sal_Int64 nRet;
+
+ if( ( rId.getLength() == 16 ) && ( 0 == rtl_compareMemory( ValueItemAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
+ nRet = reinterpret_cast< sal_Int64 >( this );
+ else
+ nRet = 0;
+
+ return nRet;
+}
diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx
new file mode 100755
index 000000000000..abde4a015ab8
--- /dev/null
+++ b/svtools/source/control/valueimp.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#include <vos/mutex.hxx>
+#include <tools/list.hxx>
+#include <tools/color.hxx>
+#include <tools/string.hxx>
+#ifndef _IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+#include <rtl/uuid.h>
+#include <cppuhelper/implbase5.hxx>
+#include <cppuhelper/compbase6.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include <memory>
+#include <vector>
+
+// -----------
+// - Defines -
+// -----------
+
+#define ITEM_OFFSET 4
+#define ITEM_OFFSET_DOUBLE 6
+#define NAME_LINE_OFF_X 2
+#define NAME_LINE_OFF_Y 2
+#define NAME_LINE_HEIGHT 2
+#define NAME_OFFSET 2
+#define SCRBAR_OFFSET 1
+#define VALUESET_ITEM_NONEITEM 0xFFFE
+#define VALUESET_SCROLL_OFFSET 4
+
+// --------------------
+// - ValueSetItemType -
+// --------------------
+
+enum ValueSetItemType
+{
+ VALUESETITEM_NONE,
+ VALUESETITEM_IMAGE,
+ VALUESETITEM_COLOR,
+ VALUESETITEM_USERDRAW,
+ VALUESETITEM_SPACE
+};
+
+// ----------------
+// - ValueSetItem -
+// ----------------
+
+class ValueSet;
+
+struct ValueSetItem
+{
+ ValueSet& mrParent;
+ USHORT mnId;
+ USHORT mnBits;
+ ValueSetItemType meType;
+ Image maImage;
+ Color maColor;
+ XubString maText;
+ void* mpData;
+ Rectangle maRect;
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >* mpxAcc;
+
+ ValueSetItem( ValueSet& rParent );
+ ~ValueSetItem();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ GetAccessible( bool bIsTransientChildrenDisabled );
+ void ClearAccessible();
+};
+
+// -----------------------------------------------------------------------------
+
+DECLARE_LIST( ValueItemList, ValueSetItem* )
+
+// -----------------------------------------------------------------------------
+
+struct ValueSet_Impl
+{
+ ::std::auto_ptr< ValueItemList > mpItemList;
+ bool mbIsTransientChildrenDisabled;
+ Link maHighlightHdl;
+
+ ValueSet_Impl() : mpItemList( ::std::auto_ptr< ValueItemList >( new ValueItemList() ) ),
+ mbIsTransientChildrenDisabled( false )
+ {
+ }
+};
+
+// ---------------
+// - ValueSetAcc -
+// ---------------
+
+typedef ::cppu::WeakComponentImplHelper6<
+ ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::accessibility::XAccessibleSelection,
+ ::com::sun::star::lang::XUnoTunnel >
+ ValueSetAccComponentBase;
+
+class ValueSetAcc :
+ public ::comphelper::OBaseMutex,
+ public ValueSetAccComponentBase
+{
+public:
+
+ ValueSetAcc( ValueSet* pParent, bool bIsTransientChildrenDisabled );
+ ~ValueSetAcc();
+
+ void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ BOOL HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
+
+ static ValueSetAcc* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxData ) throw();
+
+public:
+
+ /** Called by the corresponding ValueSet when it gets the focus.
+ Stores the new focus state and broadcasts a state change event.
+ */
+ void GetFocus (void);
+
+ /** Called by the corresponding ValueSet when it loses the focus.
+ Stores the new focus state and broadcasts a state change event.
+ */
+ void LoseFocus (void);
+
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ using cppu::WeakComponentImplHelper6<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection, com::sun::star::lang::XUnoTunnel>::addEventListener;
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ using cppu::WeakComponentImplHelper6<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection, com::sun::star::lang::XUnoTunnel>::removeEventListener;
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) 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 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) 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);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) 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& aPoint ) 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 void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) 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);
+
+ // 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);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ // ::vos::OMutex maMutex;
+ ::std::vector< ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener > > mxEventListeners;
+ ValueSet* mpParent;
+ bool mbIsTransientChildrenDisabled;
+ /// The current FOCUSED state.
+ bool mbIsFocused;
+
+ static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
+
+ /** Tell all listeners that the object is dying. This callback is
+ usually called from the WeakComponentImplHelper class.
+ */
+ virtual void SAL_CALL disposing (void);
+
+ /** Return the number of items. This takes the None-Item into account.
+ */
+ USHORT getItemCount (void) const;
+
+ /** Return the item associated with the given index. The None-Item is
+ taken into account which, when present, is taken to be the first
+ (with index 0) item.
+ @param nIndex
+ Index of the item to return. The index 0 denotes the None-Item
+ when present.
+ @return
+ Returns NULL when the given index is out of range.
+ */
+ ValueSetItem* getItem (USHORT nIndex) const;
+
+ /** Check whether or not the object has been disposed (or is in the
+ state of beeing disposed). If that is the case then
+ DisposedException is thrown to inform the (indirect) caller of the
+ foul deed.
+ */
+ void ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException);
+
+ /** Check whether or not the object has been disposed (or is in the
+ state of beeing disposed).
+
+ @return sal_True, if the object is disposed or in the course
+ of being disposed. Otherwise, sal_False is returned.
+ */
+ sal_Bool IsDisposed (void);
+
+ /** Check whether the value set has a 'none' field, i.e. a field (button)
+ that deselects any items (selects none of them).
+ @return
+ Returns <true/> if there is a 'none' field and <false/> it it is
+ missing.
+ */
+ bool HasNoneField (void) const;
+};
+
+// ----------------
+// - ValueItemAcc -
+// ----------------
+
+class ValueItemAcc : public ::cppu::WeakImplHelper5< ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::lang::XUnoTunnel >
+{
+private:
+
+ ::std::vector< ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener > > mxEventListeners;
+ ::vos::OMutex maMutex;
+ ValueSetItem* mpParent;
+ bool mbIsTransientChildrenDisabled;
+
+ static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
+
+public:
+
+ ValueItemAcc( ValueSetItem* pParent, bool bIsTransientChildrenDisabled );
+ ~ValueItemAcc();
+
+ void ParentDestroyed();
+
+ void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ BOOL HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
+
+ static ValueItemAcc* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxData ) throw();
+
+public:
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) 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 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) 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);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) 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& aPoint ) 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 void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) 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);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException );
+};
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
new file mode 100644
index 000000000000..62193eadf735
--- /dev/null
+++ b/svtools/source/control/valueset.cxx
@@ -0,0 +1,2758 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <tools/list.hxx>
+#include <tools/debug.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/svapp.hxx>
+#ifndef _SCRBAR_HXX
+#include <vcl/scrbar.hxx>
+#endif
+#ifndef _HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <rtl/ustring.hxx>
+
+#include "valueimp.hxx"
+
+#define _SV_VALUESET_CXX
+#include <svtools/valueset.hxx>
+
+// ------------
+// - ValueSet -
+// ------------
+
+void ValueSet::ImplInit()
+{
+ // Size aWinSize = GetSizePixel();
+ mpImpl = new ValueSet_Impl;
+ mpNoneItem = NULL;
+ mpScrBar = NULL;
+ mnTextOffset = 0;
+ mnVisLines = 0;
+ mnLines = 0;
+ mnUserItemWidth = 0;
+ mnUserItemHeight = 0;
+ mnFirstLine = 0;
+ mnOldItemId = 0;
+ mnSelItemId = 0;
+ mnHighItemId = 0;
+ mnDropPos = VALUESET_ITEM_NOTFOUND;
+ mnCols = 0;
+ mnCurCol = 0;
+ mnUserCols = 0;
+ mnUserVisLines = 0;
+ mnSpacing = 0;
+ mnFrameStyle = 0;
+ mbFormat = TRUE;
+ mbHighlight = FALSE ;
+ mbSelection = FALSE;
+ mbNoSelection = TRUE;
+ mbDrawSelection = TRUE;
+ mbBlackSel = FALSE;
+ mbDoubleSel = FALSE;
+ mbScroll = FALSE;
+ mbDropPos = FALSE;
+ mbFullMode = TRUE;
+
+ // #106446#, #106601# force mirroring of virtual device
+ maVirDev.EnableRTL( GetParent()->IsRTLEnabled() );
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+ValueSet::ValueSet( Window* pParent, WinBits nWinStyle, bool bDisableTransientChildren ) :
+ Control( pParent, nWinStyle ),
+ maVirDev( *this ),
+ maColor( COL_TRANSPARENT )
+{
+ ImplInit();
+ if( mpImpl )
+ mpImpl->mbIsTransientChildrenDisabled = bDisableTransientChildren;
+}
+
+// -----------------------------------------------------------------------
+
+ValueSet::ValueSet( Window* pParent, const ResId& rResId, bool bDisableTransientChildren ) :
+ Control( pParent, rResId ),
+ maVirDev( *this ),
+ maColor( COL_TRANSPARENT )
+{
+ ImplInit();
+ if( mpImpl )
+ mpImpl->mbIsTransientChildrenDisabled = bDisableTransientChildren;
+}
+
+// -----------------------------------------------------------------------
+
+ValueSet::~ValueSet()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
+ xComponent (GetAccessible(FALSE), ::com::sun::star::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose ();
+
+ if ( mpScrBar )
+ delete mpScrBar;
+
+ if ( mpNoneItem )
+ delete mpNoneItem;
+
+ ImplDeleteItems();
+ delete mpImpl;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDeleteItems()
+{
+ for( ValueSetItem* pItem = mpImpl->mpItemList->First(); pItem; pItem = mpImpl->mpItemList->Next() )
+ {
+ if( !pItem->maRect.IsEmpty() && ImplHasAccessibleListeners() )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+
+ aOldAny <<= pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled );
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
+ }
+
+ delete pItem;
+ }
+
+ mpImpl->mpItemList->Clear();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( GetStyle() & WB_MENUSTYLEVALUESET )
+ aColor = rStyleSettings.GetMenuColor();
+ else if ( IsEnabled() && (GetStyle() & WB_FLATVALUESET) )
+ aColor = rStyleSettings.GetWindowColor();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplInitScrollBar()
+{
+ if ( GetStyle() & WB_VSCROLL )
+ {
+ if ( !mpScrBar )
+ {
+ mpScrBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
+ mpScrBar->SetScrollHdl( LINK( this, ValueSet, ImplScrollHdl ) );
+ }
+ else
+ {
+ // Wegen Einstellungsaenderungen passen wir hier die Breite an
+ long nScrBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
+ mpScrBar->SetPosSizePixel( 0, 0, nScrBarWidth, 0, WINDOW_POSSIZE_WIDTH );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplFormatItem( ValueSetItem* pItem )
+{
+ if ( pItem->meType == VALUESETITEM_SPACE )
+ return;
+
+ Rectangle aRect = pItem->maRect;
+ WinBits nStyle = GetStyle();
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( nStyle & WB_FLATVALUESET )
+ {
+ if ( nStyle & WB_DOUBLEBORDER )
+ {
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+ }
+ else
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ }
+ }
+ else
+ {
+ DecorationView aView( &maVirDev );
+ aRect = aView.DrawFrame( aRect, mnFrameStyle );
+ }
+ }
+
+ if ( pItem == mpNoneItem )
+ pItem->maText = GetText();
+
+ if ( (aRect.GetHeight() > 0) && (aRect.GetWidth() > 0) )
+ {
+ if ( pItem == mpNoneItem )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ maVirDev.SetFont( GetFont() );
+ maVirDev.SetTextColor( ( nStyle & WB_MENUSTYLEVALUESET ) ? rStyleSettings.GetMenuTextColor() : rStyleSettings.GetWindowTextColor() );
+ maVirDev.SetTextFillColor();
+ maVirDev.SetFillColor( ( nStyle & WB_MENUSTYLEVALUESET ) ? rStyleSettings.GetMenuColor() : rStyleSettings.GetWindowColor() );
+ maVirDev.DrawRect( aRect );
+ Point aTxtPos( aRect.Left()+2, aRect.Top() );
+ long nTxtWidth = GetTextWidth( pItem->maText );
+ if ( nStyle & WB_RADIOSEL )
+ {
+ aTxtPos.X() += 4;
+ aTxtPos.Y() += 4;
+ }
+ if ( (aTxtPos.X()+nTxtWidth) > aRect.Right() )
+ {
+ maVirDev.SetClipRegion( Region( aRect ) );
+ maVirDev.DrawText( aTxtPos, pItem->maText );
+ maVirDev.SetClipRegion();
+ }
+ else
+ maVirDev.DrawText( aTxtPos, pItem->maText );
+ }
+ else if ( pItem->meType == VALUESETITEM_COLOR )
+ {
+ maVirDev.SetFillColor( pItem->maColor );
+ maVirDev.DrawRect( aRect );
+ }
+ else
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( IsColor() )
+ maVirDev.SetFillColor( maColor );
+ else if ( nStyle & WB_MENUSTYLEVALUESET )
+ maVirDev.SetFillColor( rStyleSettings.GetMenuColor() );
+ else if ( IsEnabled() )
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ else
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ maVirDev.DrawRect( aRect );
+
+ if ( pItem->meType == VALUESETITEM_USERDRAW )
+ {
+ UserDrawEvent aUDEvt( &maVirDev, aRect, pItem->mnId );
+ UserDraw( aUDEvt );
+ }
+ else
+ {
+ Size aImageSize = pItem->maImage.GetSizePixel();
+ Size aRectSize = aRect.GetSize();
+ Point aPos( aRect.Left(), aRect.Top() );
+ aPos.X() += (aRectSize.Width()-aImageSize.Width())/2;
+ aPos.Y() += (aRectSize.Height()-aImageSize.Height())/2;
+
+ USHORT nImageStyle = 0;
+ if( !IsEnabled() )
+ nImageStyle |= IMAGE_DRAW_DISABLE;
+
+ if ( (aImageSize.Width() > aRectSize.Width()) ||
+ (aImageSize.Height() > aRectSize.Height()) )
+ {
+ maVirDev.SetClipRegion( Region( aRect ) );
+ maVirDev.DrawImage( aPos, pItem->maImage, nImageStyle);
+ maVirDev.SetClipRegion();
+ }
+ else
+ maVirDev.DrawImage( aPos, pItem->maImage, nImageStyle );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ValueSet::CreateAccessible()
+{
+ return new ValueSetAcc( this, mpImpl->mbIsTransientChildrenDisabled );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Format()
+{
+ Size aWinSize = GetOutputSizePixel();
+ ULONG nItemCount = mpImpl->mpItemList->Count();
+ WinBits nStyle = GetStyle();
+ long nTxtHeight = GetTextHeight();
+ long nOff;
+ long nSpace;
+ long nNoneHeight;
+ long nNoneSpace;
+ ScrollBar* pDelScrBar = NULL;
+
+ // Scrolling beruecksichtigen
+ if ( nStyle & WB_VSCROLL )
+ ImplInitScrollBar();
+ else
+ {
+ if ( mpScrBar )
+ {
+ // ScrollBar erst spaeter zerstoeren, damit keine rekursiven
+ // Aufrufe entstehen koennen
+ pDelScrBar = mpScrBar;
+ mpScrBar = NULL;
+ }
+ }
+
+ // Item-Offset berechnen
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ if ( nStyle & WB_DOUBLEBORDER )
+ nOff = ITEM_OFFSET_DOUBLE;
+ else
+ nOff = ITEM_OFFSET;
+ }
+ else
+ nOff = 0;
+ nSpace = mnSpacing;
+
+ // Groesse beruecksichtigen, wenn NameField vorhanden
+ if ( nStyle & WB_NAMEFIELD )
+ {
+ mnTextOffset = aWinSize.Height()-nTxtHeight-NAME_OFFSET;
+ aWinSize.Height() -= nTxtHeight+NAME_OFFSET;
+
+ if ( !(nStyle & WB_FLATVALUESET) )
+ {
+ mnTextOffset -= NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
+ aWinSize.Height() -= NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
+ }
+ }
+ else
+ mnTextOffset = 0;
+
+ // Offset und Groesse beruecksichtigen, wenn NoneField vorhanden
+ if ( nStyle & WB_NONEFIELD )
+ {
+ nNoneHeight = nTxtHeight+nOff;
+ nNoneSpace = nSpace;
+ if ( nStyle & WB_RADIOSEL )
+ nNoneHeight += 8;
+ }
+ else
+ {
+ nNoneHeight = 0;
+ nNoneSpace = 0;
+
+ if ( mpNoneItem )
+ {
+ delete mpNoneItem;
+ mpNoneItem = NULL;
+ }
+ }
+
+ // Breite vom ScrollBar berechnen
+ long nScrBarWidth = 0;
+ if ( mpScrBar )
+ nScrBarWidth = mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
+
+ // Spaltenanzahl berechnen
+ if ( !mnUserCols )
+ {
+ if ( mnUserItemWidth )
+ {
+ mnCols = (USHORT)((aWinSize.Width()-nScrBarWidth+nSpace) / (mnUserItemWidth+nSpace));
+ if ( !mnCols )
+ mnCols = 1;
+ }
+ else
+ mnCols = 1;
+ }
+ else
+ mnCols = mnUserCols;
+
+ // Zeilenanzahl berechnen
+ mbScroll = FALSE;
+ mnLines = (long)mpImpl->mpItemList->Count() / mnCols;
+ if ( mpImpl->mpItemList->Count() % mnCols )
+ mnLines++;
+ else if ( !mnLines )
+ mnLines = 1;
+
+ long nCalcHeight = aWinSize.Height()-nNoneHeight;
+ if ( mnUserVisLines )
+ mnVisLines = mnUserVisLines;
+ else if ( mnUserItemHeight )
+ {
+ mnVisLines = (nCalcHeight-nNoneSpace+nSpace) / (mnUserItemHeight+nSpace);
+ if ( !mnVisLines )
+ mnVisLines = 1;
+ }
+ else
+ mnVisLines = mnLines;
+ if ( mnLines > mnVisLines )
+ mbScroll = TRUE;
+ if ( mnLines <= mnVisLines )
+ mnFirstLine = 0;
+ else
+ {
+ if ( mnFirstLine > (USHORT)(mnLines-mnVisLines) )
+ mnFirstLine = (USHORT)(mnLines-mnVisLines);
+ }
+
+ // Itemgroessen berechnen
+ long nColSpace = (mnCols-1)*nSpace;
+ long nLineSpace = ((mnVisLines-1)*nSpace)+nNoneSpace;
+ long nItemWidth;
+ long nItemHeight;
+ if ( mnUserItemWidth && !mnUserCols )
+ {
+ nItemWidth = mnUserItemWidth;
+ if ( nItemWidth > aWinSize.Width()-nScrBarWidth-nColSpace )
+ nItemWidth = aWinSize.Width()-nScrBarWidth-nColSpace;
+ }
+ else
+ nItemWidth = (aWinSize.Width()-nScrBarWidth-nColSpace) / mnCols;
+ if ( mnUserItemHeight && !mnUserVisLines )
+ {
+ nItemHeight = mnUserItemHeight;
+ if ( nItemHeight > nCalcHeight-nNoneSpace )
+ nItemHeight = nCalcHeight-nNoneSpace;
+ }
+ else
+ {
+ nCalcHeight -= nLineSpace;
+ nItemHeight = nCalcHeight / mnVisLines;
+ }
+
+ // Init VirDev
+ maVirDev.SetSettings( GetSettings() );
+ maVirDev.SetBackground( GetBackground() );
+ maVirDev.SetOutputSizePixel( aWinSize, TRUE );
+
+ // Bei zu kleinen Items machen wir nichts
+ long nMinHeight = 2;
+ if ( nStyle & WB_ITEMBORDER )
+ nMinHeight = 4;
+ if ( (nItemWidth <= 0) || (nItemHeight <= nMinHeight) || !nItemCount )
+ {
+ if ( nStyle & WB_NONEFIELD )
+ {
+ if ( mpNoneItem )
+ {
+ mpNoneItem->maRect.SetEmpty();
+ mpNoneItem->maText = GetText();
+ }
+ }
+
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
+ pItem->maRect.SetEmpty();
+ }
+
+ if ( mpScrBar )
+ mpScrBar->Hide();
+ }
+ else
+ {
+ // Frame-Style ermitteln
+ if ( nStyle & WB_DOUBLEBORDER )
+ mnFrameStyle = FRAME_DRAW_DOUBLEIN;
+ else
+ mnFrameStyle = FRAME_DRAW_IN;
+
+ // Selektionsfarben und -breiten ermitteln
+ // Gegebenenfalls die Farben anpassen, damit man die Selektion besser
+ // erkennen kann
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aHighColor( rStyleSettings.GetHighlightColor() );
+ if ( ((aHighColor.GetRed() > 0x80) || (aHighColor.GetGreen() > 0x80) ||
+ (aHighColor.GetBlue() > 0x80)) ||
+ ((aHighColor.GetRed() == 0x80) && (aHighColor.GetGreen() == 0x80) &&
+ (aHighColor.GetBlue() == 0x80)) )
+ mbBlackSel = TRUE;
+ else
+ mbBlackSel = FALSE;
+
+ // Wenn die Items groesser sind, dann die Selektion doppelt so breit
+ // zeichnen
+ if ( (nStyle & WB_DOUBLEBORDER) &&
+ ((nItemWidth >= 25) && (nItemHeight >= 20)) )
+ mbDoubleSel = TRUE;
+ else
+ mbDoubleSel = FALSE;
+
+ // Calculate offsets
+ long nStartX;
+ long nStartY;
+ if ( mbFullMode )
+ {
+ long nAllItemWidth = (nItemWidth*mnCols)+nColSpace;
+ long nAllItemHeight = (nItemHeight*mnVisLines)+nNoneHeight+nLineSpace;
+ nStartX = (aWinSize.Width()-nScrBarWidth-nAllItemWidth)/2;
+ nStartY = (aWinSize.Height()-nAllItemHeight)/2;
+ }
+ else
+ {
+ nStartX = 0;
+ nStartY = 0;
+ }
+
+ // Items berechnen und zeichnen
+ maVirDev.SetLineColor();
+ long x = nStartX;
+ long y = nStartY;
+
+ // NoSelection-Field erzeugen und anzeigen
+ if ( nStyle & WB_NONEFIELD )
+ {
+ if ( !mpNoneItem )
+ mpNoneItem = new ValueSetItem( *this );
+
+ mpNoneItem->mnId = 0;
+ mpNoneItem->meType = VALUESETITEM_NONE;
+ mpNoneItem->maRect.Left() = x;
+ mpNoneItem->maRect.Top() = y;
+ mpNoneItem->maRect.Right() = mpNoneItem->maRect.Left()+aWinSize.Width()-x-1;
+ mpNoneItem->maRect.Bottom() = y+nNoneHeight-1;
+
+ ImplFormatItem( mpNoneItem );
+
+ y += nNoneHeight+nNoneSpace;
+ }
+
+ // draw items
+ ULONG nFirstItem = mnFirstLine * mnCols;
+ ULONG nLastItem = nFirstItem + (mnVisLines * mnCols);
+
+ if ( !mbFullMode )
+ {
+ // If want also draw parts of items in the last line,
+ // then we add one more line if parts of these line are
+ // visible
+ if ( y+(mnVisLines*(nItemHeight+nSpace)) < aWinSize.Height() )
+ nLastItem += mnCols;
+ }
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
+
+ if ( (i >= nFirstItem) && (i < nLastItem) )
+ {
+ const BOOL bWasEmpty = pItem->maRect.IsEmpty();
+
+ pItem->maRect.Left() = x;
+ pItem->maRect.Top() = y;
+ pItem->maRect.Right() = pItem->maRect.Left()+nItemWidth-1;
+ pItem->maRect.Bottom() = pItem->maRect.Top()+nItemHeight-1;
+
+ if( bWasEmpty && ImplHasAccessibleListeners() )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+
+ aNewAny <<= pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled );
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
+ }
+
+ ImplFormatItem( pItem );
+
+ if ( !((i+1) % mnCols) )
+ {
+ x = nStartX;
+ y += nItemHeight+nSpace;
+ }
+ else
+ x += nItemWidth+nSpace;
+ }
+ else
+ {
+ if( !pItem->maRect.IsEmpty() && ImplHasAccessibleListeners() )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+
+ aOldAny <<= pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled );
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
+ }
+
+ pItem->maRect.SetEmpty();
+ }
+ }
+
+ // ScrollBar anordnen, Werte setzen und anzeigen
+ if ( mpScrBar )
+ {
+ Point aPos( aWinSize.Width()-nScrBarWidth+SCRBAR_OFFSET, 0 );
+ Size aSize( nScrBarWidth-SCRBAR_OFFSET, aWinSize.Height() );
+ // If a none field is visible, then we center the scrollbar
+ if ( nStyle & WB_NONEFIELD )
+ {
+ aPos.Y() = nStartY+nNoneHeight+1;
+ aSize.Height() = ((nItemHeight+nSpace)*mnVisLines)-2-nSpace;
+ }
+ mpScrBar->SetPosSizePixel( aPos, aSize );
+ mpScrBar->SetRangeMax( mnLines );
+ mpScrBar->SetVisibleSize( mnVisLines );
+ mpScrBar->SetThumbPos( (long)mnFirstLine );
+ long nPageSize = mnVisLines;
+ if ( nPageSize < 1 )
+ nPageSize = 1;
+ mpScrBar->SetPageSize( nPageSize );
+ mpScrBar->Show();
+ }
+ }
+
+ // Jetzt haben wir formatiert und warten auf das naechste
+ mbFormat = FALSE;
+
+ // ScrollBar loeschen
+ if ( pDelScrBar )
+ delete pDelScrBar;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDrawItemText( const XubString& rText )
+{
+ if ( !(GetStyle() & WB_NAMEFIELD) )
+ return;
+
+ Size aWinSize = GetOutputSizePixel();
+ long nTxtWidth = GetTextWidth( rText );
+ long nTxtOffset = mnTextOffset;
+
+ // Rechteck loeschen und Text ausgeben
+ if ( GetStyle() & WB_FLATVALUESET )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ DrawRect( Rectangle( Point( 0, nTxtOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
+ SetTextColor( rStyleSettings.GetButtonTextColor() );
+ }
+ else
+ {
+ nTxtOffset += NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
+ Erase( Rectangle( Point( 0, nTxtOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
+ }
+ DrawText( Point( (aWinSize.Width()-nTxtWidth) / 2, nTxtOffset+(NAME_OFFSET/2) ), rText );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDrawSelect()
+{
+ if ( !IsReallyVisible() )
+ return;
+
+ BOOL bFocus = HasFocus();
+ BOOL bDrawSel;
+
+ if ( (mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight) )
+ bDrawSel = FALSE;
+ else
+ bDrawSel = TRUE;
+
+ if ( !bFocus &&
+ ((mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight)) )
+ {
+ XubString aEmptyStr;
+ ImplDrawItemText( aEmptyStr );
+ return;
+ }
+
+ USHORT nItemId = mnSelItemId;
+
+ for( int stage = 0; stage < 2; stage++ )
+ {
+ if( stage == 1 )
+ {
+ if ( mbHighlight )
+ nItemId = mnHighItemId;
+ else
+ break;
+ }
+
+ ValueSetItem* pItem;
+ if ( nItemId )
+ pItem = mpImpl->mpItemList->GetObject( GetItemPos( nItemId ) );
+ else
+ {
+ if ( mpNoneItem )
+ pItem = mpNoneItem;
+ else
+ {
+ pItem = ImplGetFirstItem();
+ if ( !bFocus || !pItem )
+ continue;
+ }
+ }
+
+ if ( pItem->maRect.IsEmpty() )
+ continue;
+
+ // Selection malen
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aRect = pItem->maRect;
+ Control::SetFillColor();
+
+ Color aDoubleColor( rStyleSettings.GetHighlightColor() );
+ Color aSingleColor( rStyleSettings.GetHighlightTextColor() );
+ if( ! mbDoubleSel )
+ {
+ /*
+ * #99777# contrast enhancement for thin mode
+ */
+ const Wallpaper& rWall = GetDisplayBackground();
+ if( ! rWall.IsBitmap() && ! rWall.IsGradient() )
+ {
+ const Color& rBack = rWall.GetColor();
+ if( rBack.IsDark() && ! aDoubleColor.IsBright() )
+ {
+ aDoubleColor = Color( COL_WHITE );
+ aSingleColor = Color( COL_BLACK );
+ }
+ else if( rBack.IsBright() && ! aDoubleColor.IsDark() )
+ {
+ aDoubleColor = Color( COL_BLACK );
+ aSingleColor = Color( COL_WHITE );
+ }
+ }
+ }
+
+ // Selectionsausgabe festlegen
+ WinBits nStyle = GetStyle();
+ if ( nStyle & WB_MENUSTYLEVALUESET )
+ {
+ if ( bFocus )
+ ShowFocus( aRect );
+
+ if ( bDrawSel )
+ {
+ if ( mbBlackSel )
+ SetLineColor( Color( COL_BLACK ) );
+ else
+ SetLineColor( aDoubleColor );
+ DrawRect( aRect );
+ }
+ }
+ else if ( nStyle & WB_RADIOSEL )
+ {
+ aRect.Left() += 3;
+ aRect.Top() += 3;
+ aRect.Right() -= 3;
+ aRect.Bottom() -= 3;
+ if ( nStyle & WB_DOUBLEBORDER )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ }
+
+ if ( bFocus )
+ ShowFocus( aRect );
+
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+
+ if ( bDrawSel )
+ {
+ SetLineColor( aDoubleColor );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ DrawRect( aRect );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ DrawRect( aRect );
+ }
+ }
+ else
+ {
+ if ( bDrawSel )
+ {
+ if ( mbBlackSel )
+ SetLineColor( Color( COL_BLACK ) );
+ else
+ SetLineColor( aDoubleColor );
+ DrawRect( aRect );
+ }
+ if ( mbDoubleSel )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( bDrawSel )
+ DrawRect( aRect );
+ }
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ Rectangle aRect2 = aRect;
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( bDrawSel )
+ DrawRect( aRect );
+ if ( mbDoubleSel )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( bDrawSel )
+ DrawRect( aRect );
+ }
+
+ if ( bDrawSel )
+ {
+ if ( mbBlackSel )
+ SetLineColor( Color( COL_WHITE ) );
+ else
+ SetLineColor( aSingleColor );
+ }
+ else
+ SetLineColor( Color( COL_LIGHTGRAY ) );
+ DrawRect( aRect2 );
+
+ if ( bFocus )
+ ShowFocus( aRect2 );
+ }
+
+ ImplDrawItemText( pItem->maText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplHideSelect( USHORT nItemId )
+{
+ Rectangle aRect;
+
+ USHORT nItemPos = GetItemPos( nItemId );
+ if ( nItemPos != sal::static_int_cast<USHORT>(LIST_ENTRY_NOTFOUND) )
+ aRect = mpImpl->mpItemList->GetObject( nItemPos )->maRect;
+ else
+ {
+ if ( mpNoneItem )
+ aRect = mpNoneItem->maRect;
+ }
+
+ if ( !aRect.IsEmpty() )
+ {
+ HideFocus();
+ Point aPos = aRect.TopLeft();
+ Size aSize = aRect.GetSize();
+ DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplHighlightItem( USHORT nItemId, BOOL bIsSelection )
+{
+ if ( mnHighItemId != nItemId )
+ {
+ // Alten merken, um vorherige Selektion zu entfernen
+ USHORT nOldItem = mnHighItemId;
+ mnHighItemId = nItemId;
+
+ // Wenn keiner selektiert ist, dann Selektion nicht malen
+ if ( !bIsSelection && mbNoSelection )
+ mbDrawSelection = FALSE;
+
+ // Neu ausgeben und alte Selection wegnehmen
+ ImplHideSelect( nOldItem );
+ ImplDrawSelect();
+ mbDrawSelection = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDrawDropPos( BOOL bShow )
+{
+ if ( (mnDropPos != VALUESET_ITEM_NOTFOUND) && mpImpl->mpItemList->Count() )
+ {
+ USHORT nItemPos = mnDropPos;
+ USHORT nItemId1;
+ USHORT nItemId2 = 0;
+ BOOL bRight;
+ if ( nItemPos >= mpImpl->mpItemList->Count() )
+ {
+ nItemPos = (USHORT)(mpImpl->mpItemList->Count()-1);
+ bRight = TRUE;
+ }
+ else
+ bRight = FALSE;
+
+ nItemId1 = GetItemId( nItemPos );
+ if ( (nItemId1 != mnSelItemId) && (nItemId1 != mnHighItemId) )
+ nItemId1 = 0;
+ Rectangle aRect2 = mpImpl->mpItemList->GetObject( nItemPos )->maRect;
+ Rectangle aRect1;
+ if ( bRight )
+ {
+ aRect1 = aRect2;
+ aRect2.SetEmpty();
+ }
+ else if ( nItemPos > 0 )
+ {
+ aRect1 = mpImpl->mpItemList->GetObject( nItemPos-1 )->maRect;
+ nItemId2 = GetItemId( nItemPos-1 );
+ if ( (nItemId2 != mnSelItemId) && (nItemId2 != mnHighItemId) )
+ nItemId2 = 0;
+ }
+
+ // Items ueberhaupt sichtbar (nur Erstes/Letztes)
+ if ( !aRect1.IsEmpty() || !aRect2.IsEmpty() )
+ {
+ if ( nItemId1 )
+ ImplHideSelect( nItemId1 );
+ if ( nItemId2 )
+ ImplHideSelect( nItemId2 );
+
+ if ( bShow )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long nX;
+ long nY;
+ SetLineColor( rStyleSettings.GetButtonTextColor() );
+ if ( !aRect1.IsEmpty() )
+ {
+ Point aPos = aRect1.RightCenter();
+ nX = aPos.X()-2;
+ nY = aPos.Y();
+ for ( USHORT i = 0; i < 4; i++ )
+ DrawLine( Point( nX-i, nY-i ), Point( nX-i, nY+i ) );
+ }
+ if ( !aRect2.IsEmpty() )
+ {
+ Point aPos = aRect2.LeftCenter();
+ nX = aPos.X()+2;
+ nY = aPos.Y();
+ for ( USHORT i = 0; i < 4; i++ )
+ DrawLine( Point( nX+i, nY-i ), Point( nX+i, nY+i ) );
+ }
+ }
+ else
+ {
+ if ( !aRect1.IsEmpty() )
+ {
+ Point aPos = aRect1.TopLeft();
+ Size aSize = aRect1.GetSize();
+ DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+ }
+ if ( !aRect2.IsEmpty() )
+ {
+ Point aPos = aRect2.TopLeft();
+ Size aSize = aRect2.GetSize();
+ DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+ }
+ }
+
+ if ( nItemId1 || nItemId2 )
+ ImplDrawSelect();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDraw()
+{
+ if ( mbFormat )
+ Format();
+
+ HideFocus();
+
+ Point aDefPos;
+ Size aSize = maVirDev.GetOutputSizePixel();
+
+ if ( mpScrBar && mpScrBar->IsVisible() )
+ {
+ Point aScrPos = mpScrBar->GetPosPixel();
+ Size aScrSize = mpScrBar->GetSizePixel();
+ Point aTempPos( 0, aScrPos.Y() );
+ Size aTempSize( aSize.Width(), aScrPos.Y() );
+
+ DrawOutDev( aDefPos, aTempSize, aDefPos, aTempSize, maVirDev );
+ aTempSize.Width() = aScrPos.X()-1;
+ aTempSize.Height() = aScrSize.Height();
+ DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
+ aTempPos.Y() = aScrPos.Y()+aScrSize.Height();
+ aTempSize.Width() = aSize.Width();
+ aTempSize.Height() = aSize.Height()-aTempPos.Y();
+ DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
+ }
+ else
+ DrawOutDev( aDefPos, aSize, aDefPos, aSize, maVirDev );
+
+ // Trennlinie zum Namefield zeichnen
+ if ( GetStyle() & WB_NAMEFIELD )
+ {
+ if ( !(GetStyle() & WB_FLATVALUESET) )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Size aWinSize = GetOutputSizePixel();
+ Point aPos1( NAME_LINE_OFF_X, mnTextOffset+NAME_LINE_OFF_Y );
+ Point aPos2( aWinSize.Width()-(NAME_LINE_OFF_X*2), mnTextOffset+NAME_LINE_OFF_Y );
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( aPos1, aPos2 );
+ aPos1.Y()++;
+ aPos2.Y()++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ }
+ else
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( aPos1, aPos2 );
+ }
+ }
+
+ ImplDrawSelect();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ValueSet::ImplScroll( const Point& rPos )
+{
+ Size aOutSize = GetOutputSizePixel();
+ long nScrBarWidth;
+
+ if ( mpScrBar )
+ nScrBarWidth = mpScrBar->GetSizePixel().Width();
+ else
+ nScrBarWidth = 0;
+
+ if ( !mbScroll || (rPos.X() < 0) || (rPos.X() > aOutSize.Width()-nScrBarWidth) )
+ return FALSE;
+
+ long nScrollOffset;
+ USHORT nOldLine = mnFirstLine;
+ const Rectangle& rTopRect = mpImpl->mpItemList->GetObject( mnFirstLine*mnCols )->maRect;
+ if ( rTopRect.GetHeight() <= 16 )
+ nScrollOffset = VALUESET_SCROLL_OFFSET/2;
+ else
+ nScrollOffset = VALUESET_SCROLL_OFFSET;
+ if ( (mnFirstLine > 0) && (rPos.Y() >= 0) )
+ {
+ long nTopPos = rTopRect.Top();
+ if ( (rPos.Y() >= nTopPos) && (rPos.Y() <= nTopPos+nScrollOffset) )
+ mnFirstLine--;
+ }
+ if ( (mnFirstLine == nOldLine) &&
+ (mnFirstLine < (USHORT)(mnLines-mnVisLines)) && (rPos.Y() < aOutSize.Height()) )
+ {
+ long nBottomPos = mpImpl->mpItemList->GetObject( (mnFirstLine+mnVisLines-1)*mnCols )->maRect.Bottom();
+ if ( (rPos.Y() >= nBottomPos-nScrollOffset) && (rPos.Y() <= nBottomPos) )
+ mnFirstLine++;
+ }
+
+ if ( mnFirstLine != nOldLine )
+ {
+ mbFormat = TRUE;
+ ImplDraw();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::ImplGetItem( const Point& rPos, BOOL bMove ) const
+{
+ if ( mpNoneItem )
+ {
+ if ( mpNoneItem->maRect.IsInside( rPos ) )
+ return VALUESET_ITEM_NONEITEM;
+ }
+
+ Point aDefPos;
+ Rectangle aWinRect( aDefPos, maVirDev.GetOutputSizePixel() );
+
+ ULONG nItemCount = mpImpl->mpItemList->Count();
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
+ if ( pItem->maRect.IsInside( rPos ) )
+ {
+ if ( aWinRect.IsInside( rPos ) )
+ return (USHORT)i;
+ else
+ return VALUESET_ITEM_NOTFOUND;
+ }
+ }
+
+ // Wenn Spacing gesetzt ist, wird der vorher selektierte
+ // Eintrag zurueckgegeben, wenn die Maus noch nicht das Fenster
+ // verlassen hat
+ if ( bMove && mnSpacing && mnHighItemId )
+ {
+ if ( aWinRect.IsInside( rPos ) )
+ return GetItemPos( mnHighItemId );
+ }
+
+ return VALUESET_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem* ValueSet::ImplGetItem( USHORT nPos )
+{
+ if ( nPos == VALUESET_ITEM_NONEITEM )
+ return mpNoneItem;
+ else
+ return mpImpl->mpItemList->GetObject( nPos );
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem* ValueSet::ImplGetFirstItem()
+{
+ USHORT nItemCount = (USHORT)mpImpl->mpItemList->Count();
+ USHORT i = 0;
+
+ while ( i < nItemCount )
+ {
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
+ if ( pItem->meType != VALUESETITEM_SPACE )
+ return pItem;
+ i++;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::ImplGetVisibleItemCount() const
+{
+ USHORT nRet = 0;
+
+ for( sal_Int32 n = 0, nItemCount = mpImpl->mpItemList->Count(); n < nItemCount; n++ )
+ {
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( n );
+
+ if( pItem->meType != VALUESETITEM_SPACE && !pItem->maRect.IsEmpty() )
+ nRet++;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem* ValueSet::ImplGetVisibleItem( USHORT nVisiblePos )
+{
+ ValueSetItem* pRet = NULL;
+ USHORT nFoundPos = 0;
+
+ for( sal_Int32 n = 0, nItemCount = mpImpl->mpItemList->Count(); ( n < nItemCount ) && !pRet; n++ )
+ {
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( n );
+
+ if( ( pItem->meType != VALUESETITEM_SPACE ) && !pItem->maRect.IsEmpty() && ( nVisiblePos == nFoundPos++ ) )
+ pRet = pItem;
+ }
+
+ return pRet;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
+{
+ ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( FALSE ) );
+
+ if( pAcc )
+ pAcc->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ValueSet::ImplHasAccessibleListeners()
+{
+ ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( FALSE ) );
+ return( pAcc && pAcc->HasAccessibleListeners() );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ValueSet,ImplScrollHdl, ScrollBar*, pScrollBar )
+{
+ USHORT nNewFirstLine = (USHORT)pScrollBar->GetThumbPos();
+ if ( nNewFirstLine != mnFirstLine )
+ {
+ mnFirstLine = nNewFirstLine;
+ mbFormat = TRUE;
+ ImplDraw();
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ValueSet,ImplTimerHdl, Timer*, EMPTYARG )
+{
+ ImplTracking( GetPointerPosPixel(), TRUE );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplTracking( const Point& rPos, BOOL bRepeat )
+{
+ if ( bRepeat || mbSelection )
+ {
+ if ( ImplScroll( rPos ) )
+ {
+ if ( mbSelection )
+ {
+ maTimer.SetTimeoutHdl( LINK( this, ValueSet, ImplTimerHdl ) );
+ maTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
+ maTimer.Start();
+ }
+ }
+ }
+
+ ValueSetItem* pItem = ImplGetItem( ImplGetItem( rPos ) );
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
+ {
+ if( GetStyle() & WB_MENUSTYLEVALUESET )
+ mbHighlight = TRUE;
+
+ ImplHighlightItem( pItem->mnId );
+ }
+ else
+ {
+ if( GetStyle() & WB_MENUSTYLEVALUESET )
+ mbHighlight = TRUE;
+
+ ImplHighlightItem( mnSelItemId, FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplEndTracking( const Point& rPos, BOOL bCancel )
+{
+ ValueSetItem* pItem;
+
+ // Bei Abbruch, den alten Status wieder herstellen
+ if ( bCancel )
+ pItem = NULL;
+ else
+ pItem = ImplGetItem( ImplGetItem( rPos ) );
+
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
+ {
+ SelectItem( pItem->mnId );
+ if ( !mbSelection && !(GetStyle() & WB_NOPOINTERFOCUS) )
+ GrabFocus();
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+ Select();
+ }
+ else
+ {
+ ImplHighlightItem( mnSelItemId, FALSE );
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ ValueSetItem* pItem = ImplGetItem( ImplGetItem( rMEvt.GetPosPixel() ) );
+ if ( mbSelection )
+ {
+ mbHighlight = TRUE;
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
+ {
+ mnOldItemId = mnSelItemId;
+ mnHighItemId = mnSelItemId;
+ ImplHighlightItem( pItem->mnId );
+ }
+
+ return;
+ }
+ else
+ {
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) && !rMEvt.IsMod2() )
+ {
+ if ( (pItem->mnBits & VIB_NODOUBLECLICK) || (rMEvt.GetClicks() == 1) )
+ {
+ mnOldItemId = mnSelItemId;
+ mbHighlight = TRUE;
+ mnHighItemId = mnSelItemId;
+ ImplHighlightItem( pItem->mnId );
+ StartTracking( STARTTRACK_SCROLLREPEAT );
+ }
+ else if ( rMEvt.GetClicks() == 2 )
+ DoubleClick();
+
+ return;
+ }
+ }
+ }
+
+ Control::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ // Wegen SelectionMode
+ if ( rMEvt.IsLeft() && mbSelection )
+ ImplEndTracking( rMEvt.GetPosPixel(), FALSE );
+ else
+ Control::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::MouseMove( const MouseEvent& rMEvt )
+{
+ // Wegen SelectionMode
+ if ( mbSelection || (GetStyle() & WB_MENUSTYLEVALUESET) )
+ ImplTracking( rMEvt.GetPosPixel(), FALSE );
+ Control::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( rTEvt.IsTrackingEnded() )
+ ImplEndTracking( aMousePos, rTEvt.IsTrackingCanceled() );
+ else
+ ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::KeyInput( const KeyEvent& rKEvt )
+{
+ USHORT nLastItem = (USHORT)mpImpl->mpItemList->Count();
+ USHORT nItemPos = VALUESET_ITEM_NOTFOUND;
+ USHORT nCurPos = VALUESET_ITEM_NONEITEM;
+ USHORT nCalcPos;
+
+ if ( !nLastItem || !ImplGetFirstItem() )
+ {
+ Control::KeyInput( rKEvt );
+ return;
+ }
+ else
+ nLastItem--;
+
+ if ( mnSelItemId )
+ nCurPos = GetItemPos( mnSelItemId );
+ nCalcPos = nCurPos;
+
+ //switch off selection mode if key travelling is used
+ BOOL bDefault = FALSE;
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_HOME:
+ if ( mpNoneItem )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ {
+ nItemPos = 0;
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE )
+ nItemPos++;
+ }
+ break;
+
+ case KEY_END:
+ nItemPos = nLastItem;
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE )
+ {
+ if ( nItemPos == 0 )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ nItemPos--;
+ }
+ break;
+
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if ( rKEvt.GetKeyCode().GetCode()==KEY_LEFT )
+ {
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ nItemPos = nLastItem;
+ else if ( !nCalcPos )
+ {
+ if ( mpNoneItem )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ nItemPos = nLastItem;
+ }
+ else
+ nItemPos = nCalcPos-1;
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ }
+ else
+ {
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ nItemPos = 0;
+ else if ( nCalcPos == nLastItem )
+ {
+ if ( mpNoneItem )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ nItemPos = 0;
+ }
+ else
+ nItemPos = nCalcPos+1;
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ }
+ break;
+
+ case KEY_UP:
+ case KEY_PAGEUP:
+ {
+ if( rKEvt.GetKeyCode().GetCode() != KEY_PAGEUP ||
+ ( !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2() ) )
+ {
+ const long nLineCount = ( ( KEY_UP == rKEvt.GetKeyCode().GetCode() ) ? 1 : mnVisLines );
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ {
+ if ( nLastItem+1 <= mnCols )
+ nItemPos = mnCurCol;
+ else
+ {
+ nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(mnCurCol%mnCols);
+ if ( nItemPos+mnCols <= nLastItem )
+ nItemPos = nItemPos + mnCols;
+ }
+ }
+ else if ( nCalcPos >= ( nLineCount * mnCols ) )
+ nItemPos = sal::static_int_cast< USHORT >(
+ nCalcPos - ( nLineCount * mnCols ));
+ else
+ {
+ if ( mpNoneItem )
+ {
+ mnCurCol = nCalcPos%mnCols;
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ }
+ else
+ {
+ if ( nLastItem+1 <= mnCols )
+ nItemPos = nCalcPos;
+ else
+ {
+ nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(nCalcPos%mnCols);
+ if ( nItemPos+mnCols <= nLastItem )
+ nItemPos = nItemPos + mnCols;
+ }
+ }
+ }
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ }
+ else
+ Control::KeyInput( rKEvt );
+ }
+ break;
+
+ case KEY_DOWN:
+ case KEY_PAGEDOWN:
+ {
+ if( rKEvt.GetKeyCode().GetCode() != KEY_PAGEDOWN ||
+ ( !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2() ) )
+ {
+ const long nLineCount = ( ( KEY_DOWN == rKEvt.GetKeyCode().GetCode() ) ? 1 : mnVisLines );
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ nItemPos = mnCurCol;
+ else if ( nCalcPos + ( nLineCount * mnCols ) <= nLastItem )
+ nItemPos = sal::static_int_cast< USHORT >(
+ nCalcPos + ( nLineCount * mnCols ));
+ else
+ {
+#if 0
+ if( (KEY_DOWN == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) )
+ {
+ Window* pParent = GetParent();
+ pParent->GrabFocus();
+ pParent->KeyInput( rKEvt );
+ break;
+ }
+ else
+#endif
+ {
+ if ( mpNoneItem )
+ {
+ mnCurCol = nCalcPos%mnCols;
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ }
+ else
+ nItemPos = nCalcPos%mnCols;
+ }
+ }
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ }
+ else
+ Control::KeyInput( rKEvt );
+
+ }
+ break;
+ case KEY_RETURN:
+ //enable default handling of KEY_RETURN in dialogs
+ if(0 != (GetStyle()&WB_NO_DIRECTSELECT))
+ {
+ Select();
+ break;
+ }
+ //no break;
+ default:
+ Control::KeyInput( rKEvt );
+ bDefault = TRUE;
+ break;
+ }
+ if(!bDefault)
+ EndSelection();
+ if ( nItemPos != VALUESET_ITEM_NOTFOUND )
+ {
+ USHORT nItemId;
+ if ( nItemPos != VALUESET_ITEM_NONEITEM )
+ nItemId = GetItemId( nItemPos );
+ else
+ nItemId = 0;
+
+ if ( nItemId != mnSelItemId )
+ {
+ SelectItem( nItemId );
+ //select only if WB_NO_DIRECTSELECT is not set
+ if(0 == (GetStyle()&WB_NO_DIRECTSELECT))
+ Select();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
+ {
+ if ( HandleScrollCommand( rCEvt, NULL, mpScrBar ) )
+ return;
+ }
+
+ Control::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Paint( const Rectangle& )
+{
+ if ( GetStyle() & WB_FLATVALUESET )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ long nOffY = maVirDev.GetOutputSizePixel().Height();
+ Size aWinSize = GetOutputSizePixel();
+ DrawRect( Rectangle( Point( 0, nOffY ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
+ }
+
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::GetFocus()
+{
+ OSL_TRACE ("value set getting focus");
+ ImplDrawSelect();
+ Control::GetFocus();
+
+ // Tell the accessible object that we got the focus.
+ ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( FALSE ) );
+ if( pAcc )
+ pAcc->GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::LoseFocus()
+{
+ OSL_TRACE ("value set losing focus");
+ if ( mbNoSelection && mnSelItemId )
+ ImplHideSelect( mnSelItemId );
+ else
+ HideFocus();
+ Control::LoseFocus();
+
+ // Tell the accessible object that we lost the focus.
+ ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( FALSE ) );
+ if( pAcc )
+ pAcc->LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Resize()
+{
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ Control::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( (rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON)) == HELPMODE_QUICK )
+ {
+ Point aPos = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+ USHORT nItemPos = ImplGetItem( aPos );
+ if ( nItemPos != VALUESET_ITEM_NOTFOUND )
+ {
+ ValueSetItem* pItem = ImplGetItem( nItemPos );
+ Rectangle aItemRect = pItem->maRect;
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ Help::ShowQuickHelp( this, aItemRect, GetItemText( pItem->mnId ) );
+ return;
+ }
+ }
+
+ Control::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( mbFormat )
+ Format();
+ }
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_TEXT )
+ {
+ if ( mpNoneItem && !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( mpNoneItem );
+ Invalidate( mpNoneItem->maRect );
+ }
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+ else if ( (nType == STATE_CHANGE_STYLE) || (nType == STATE_CHANGE_ENABLE) )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Image& rImage, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem( *this );
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_IMAGE;
+ pItem->maImage = rImage;
+ mpImpl->mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Color& rColor, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem( *this );
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_COLOR;
+ pItem->maColor = rColor;
+ mpImpl->mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Image& rImage,
+ const XubString& rText, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem( *this );
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_IMAGE;
+ pItem->maImage = rImage;
+ pItem->maText = rText;
+ mpImpl->mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Color& rColor,
+ const XubString& rText, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem( *this );
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_COLOR;
+ pItem->maColor = rColor;
+ pItem->maText = rText;
+ mpImpl->mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem( *this );
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_USERDRAW;
+ mpImpl->mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertSpace( USHORT nItemId, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertSpace(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertSpace(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem( *this );
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_SPACE;
+ mpImpl->mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::RemoveItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ delete mpImpl->mpItemList->Remove( nPos );
+
+ // Variablen zuruecksetzen
+ if ( (mnHighItemId == nItemId) || (mnSelItemId == nItemId) )
+ {
+ mnCurCol = 0;
+ mnOldItemId = 0;
+ mnHighItemId = 0;
+ mnSelItemId = 0;
+ mbNoSelection = TRUE;
+ }
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::CopyItems( const ValueSet& rValueSet )
+{
+ ImplDeleteItems();
+
+ ValueSetItem* pItem = rValueSet.mpImpl->mpItemList->First();
+ while ( pItem )
+ {
+ ValueSetItem* pNewItem = new ValueSetItem( *this );
+
+ pNewItem->mnId = pItem->mnId;
+ pNewItem->mnBits = pItem->mnBits;
+ pNewItem->meType = pItem->meType;
+ pNewItem->maImage = pItem->maImage;
+ pNewItem->maColor = pItem->maColor;
+ pNewItem->maText = pItem->maText;
+ pNewItem->mpData = pItem->mpData;
+ pNewItem->maRect = pItem->maRect;
+ pNewItem->mpxAcc = NULL;
+
+ mpImpl->mpItemList->Insert( pNewItem );
+ pItem = rValueSet.mpImpl->mpItemList->Next();
+ }
+
+ // Variablen zuruecksetzen
+ mnFirstLine = 0;
+ mnCurCol = 0;
+ mnOldItemId = 0;
+ mnHighItemId = 0;
+ mnSelItemId = 0;
+ mbNoSelection = TRUE;
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Clear()
+{
+ ImplDeleteItems();
+
+ // Variablen zuruecksetzen
+ mnFirstLine = 0;
+ mnCurCol = 0;
+ mnOldItemId = 0;
+ mnHighItemId = 0;
+ mnSelItemId = 0;
+ mbNoSelection = TRUE;
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemCount() const
+{
+ return (USHORT)mpImpl->mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemPos( USHORT nItemId ) const
+{
+ ValueSetItem* pItem = mpImpl->mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return (USHORT)mpImpl->mpItemList->GetCurPos();
+ pItem = mpImpl->mpItemList->Next();
+ }
+
+ return VALUESET_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemId( USHORT nPos ) const
+{
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
+
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemId( const Point& rPos ) const
+{
+ USHORT nItemPos = ImplGetItem( rPos );
+ if ( nItemPos != VALUESET_ITEM_NOTFOUND )
+ return GetItemId( nItemPos );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle ValueSet::GetItemRect( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpImpl->mpItemList->GetObject( nPos )->maRect;
+ else
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::EnableFullItemMode( BOOL bFullMode )
+{
+ mbFullMode = bFullMode;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetColCount( USHORT nNewCols )
+{
+ if ( mnUserCols != nNewCols )
+ {
+ mnUserCols = nNewCols;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetLineCount( USHORT nNewLines )
+{
+ if ( mnUserVisLines != nNewLines )
+ {
+ mnUserVisLines = nNewLines;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemWidth( long nNewItemWidth )
+{
+ if ( mnUserItemWidth != nNewItemWidth )
+ {
+ mnUserItemWidth = nNewItemWidth;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemHeight( long nNewItemHeight )
+{
+ if ( mnUserItemHeight != nNewItemHeight )
+ {
+ mnUserItemHeight = nNewItemHeight;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetFirstLine( USHORT nNewLine )
+{
+ if ( mnFirstLine != nNewLine )
+ {
+ mnFirstLine = nNewLine;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SelectItem( USHORT nItemId )
+{
+ USHORT nItemPos = 0;
+
+ if ( nItemId )
+ {
+ nItemPos = GetItemPos( nItemId );
+ if ( nItemPos == VALUESET_ITEM_NOTFOUND )
+ return;
+ if ( mpImpl->mpItemList->GetObject( nItemPos )->meType == VALUESETITEM_SPACE )
+ return;
+ }
+
+ if ( (mnSelItemId != nItemId) || mbNoSelection )
+ {
+ USHORT nOldItem = mnSelItemId ? mnSelItemId : 1;
+ mnSelItemId = nItemId;
+ mbNoSelection = FALSE;
+
+ BOOL bNewOut;
+ BOOL bNewLine;
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ bNewOut = TRUE;
+ else
+ bNewOut = FALSE;
+ bNewLine = FALSE;
+
+ // Gegebenenfalls in den sichtbaren Bereich scrollen
+ if ( mbScroll && nItemId )
+ {
+ USHORT nNewLine = (USHORT)(nItemPos / mnCols);
+ if ( nNewLine < mnFirstLine )
+ {
+ mnFirstLine = nNewLine;
+ bNewLine = TRUE;
+ }
+ else if ( nNewLine > (USHORT)(mnFirstLine+mnVisLines-1) )
+ {
+ mnFirstLine = (USHORT)(nNewLine-mnVisLines+1);
+ bNewLine = TRUE;
+ }
+ }
+
+ if ( bNewOut )
+ {
+ if ( bNewLine )
+ {
+ // Falls sich der sichtbare Bereich geaendert hat,
+ // alles neu ausgeben
+ mbFormat = TRUE;
+ ImplDraw();
+ }
+ else
+ {
+ // alte Selection wegnehmen und neue ausgeben
+ ImplHideSelect( nOldItem );
+ ImplDrawSelect();
+ }
+ }
+
+ if( ImplHasAccessibleListeners() )
+ {
+ // focus event (deselect)
+ if( nOldItem )
+ {
+ const USHORT nPos = GetItemPos( nItemId );
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ ValueItemAcc* pItemAcc = ValueItemAcc::getImplementation(
+ mpImpl->mpItemList->GetObject( nPos )->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
+
+ if( pItemAcc )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+ if( !mpImpl->mbIsTransientChildrenDisabled)
+ {
+ aOldAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
+ static_cast< ::cppu::OWeakObject* >( pItemAcc ));
+ ImplFireAccessibleEvent (::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
+ }
+ else
+ {
+ aOldAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
+ pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
+ }
+ }
+ }
+ }
+
+ // focus event (select)
+ const USHORT nPos = GetItemPos( mnSelItemId );
+
+ ValueSetItem* pItem;
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pItem = mpImpl->mpItemList->GetObject(nPos);
+ else
+ pItem = mpNoneItem;
+
+ ValueItemAcc* pItemAcc = NULL;
+ if (pItem != NULL)
+ pItemAcc = ValueItemAcc::getImplementation(pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
+
+ if( pItemAcc )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+ if( !mpImpl->mbIsTransientChildrenDisabled)
+ {
+ aNewAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
+ static_cast< ::cppu::OWeakObject* >( pItemAcc ));
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
+ }
+ else
+ {
+ aNewAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
+ pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
+ }
+ }
+
+ // selection event
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
+ }
+ mpImpl->maHighlightHdl.Call(this);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetNoSelection()
+{
+ mbNoSelection = TRUE;
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemBits( USHORT nItemId, USHORT nItemBits )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ mpImpl->mpItemList->GetObject( nPos )->mnBits = nItemBits;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemBits( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpImpl->mpItemList->GetObject( nPos )->mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemImage( USHORT nItemId, const Image& rImage )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
+ pItem->meType = VALUESETITEM_IMAGE;
+ pItem->maImage = rImage;
+
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( pItem );
+ Invalidate( pItem->maRect );
+ }
+ else
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Image ValueSet::GetItemImage( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpImpl->mpItemList->GetObject( nPos )->maImage;
+ else
+ return Image();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemColor( USHORT nItemId, const Color& rColor )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
+ pItem->meType = VALUESETITEM_COLOR;
+ pItem->maColor = rColor;
+
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( pItem );
+ Invalidate( pItem->maRect );
+ }
+ else
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Color ValueSet::GetItemColor( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpImpl->mpItemList->GetObject( nPos )->maColor;
+ else
+ return Color();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemData( USHORT nItemId, void* pData )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
+ pItem->mpData = pData;
+
+ if ( pItem->meType == VALUESETITEM_USERDRAW )
+ {
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( pItem );
+ Invalidate( pItem->maRect );
+ }
+ else
+ mbFormat = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* ValueSet::GetItemData( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpImpl->mpItemList->GetObject( nPos )->mpData;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+
+ ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
+
+ // Remember old and new name for accessibility event.
+ ::com::sun::star::uno::Any aOldName, aNewName;
+ ::rtl::OUString sString (pItem->maText);
+ aOldName <<= sString;
+ sString = rText;
+ aNewName <<= sString;
+
+ pItem->maText = rText;
+
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ USHORT nTempId = mnSelItemId;
+
+ if ( mbHighlight )
+ nTempId = mnHighItemId;
+
+ if ( nTempId == nItemId )
+ ImplDrawItemText( pItem->maText );
+ }
+
+ if (ImplHasAccessibleListeners())
+ {
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> xAccessible (
+ pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
+ static_cast<ValueItemAcc*>(xAccessible.get())->FireAccessibleEvent (
+ ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED,
+ aOldName, aNewName);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString ValueSet::GetItemText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpImpl->mpItemList->GetObject( nPos )->maText;
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetColor( const Color& rColor )
+{
+ maColor = rColor;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetExtraSpacing( USHORT nNewSpacing )
+{
+ if ( GetStyle() & WB_ITEMBORDER )
+ {
+ mnSpacing = nNewSpacing;
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::StartSelection()
+{
+ mnOldItemId = mnSelItemId;
+ mbHighlight = TRUE;
+ mbSelection = TRUE;
+ mnHighItemId = mnSelItemId;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::EndSelection()
+{
+ if ( mbHighlight )
+ {
+ if ( IsTracking() )
+ EndTracking( ENDTRACK_CANCEL );
+
+ ImplHighlightItem( mnSelItemId );
+ mbHighlight = FALSE;
+ }
+ mbSelection = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ValueSet::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
+{
+ if ( rCEvt.GetCommand() != COMMAND_STARTDRAG )
+ return FALSE;
+
+ // Gegebenenfalls eine vorhandene Aktion abbrechen
+ EndSelection();
+
+ // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
+ // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
+ // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
+ // dies nur bei einer Mausaktion.
+ USHORT nSelId;
+ if ( rCEvt.IsMouseEvent() )
+ nSelId = GetItemId( rCEvt.GetMousePosPixel() );
+ else
+ nSelId = mnSelItemId;
+
+ // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
+ if ( !nSelId )
+ return FALSE;
+
+ // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
+ // Seite setzen und Select rufen.
+ if ( nSelId != mnSelItemId )
+ {
+ SelectItem( nSelId );
+ Update();
+ Select();
+ }
+
+ Region aRegion;
+
+ // Region zuweisen
+ rRegion = aRegion;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Size ValueSet::CalcWindowSizePixel( const Size& rItemSize, USHORT nDesireCols,
+ USHORT nDesireLines )
+{
+ long nCalcCols = (long)nDesireCols;
+ long nCalcLines = (long)nDesireLines;
+
+ if ( !nCalcCols )
+ {
+ if ( mnUserCols )
+ nCalcCols = (long)mnUserCols;
+ else
+ nCalcCols = 1;
+ }
+
+ if ( !nCalcLines )
+ {
+ nCalcLines = mnVisLines;
+
+ if ( mbFormat )
+ {
+ if ( mnUserVisLines )
+ nCalcLines = mnUserVisLines;
+ else
+ {
+ nCalcLines = (long)mpImpl->mpItemList->Count() / nCalcCols;
+ if ( mpImpl->mpItemList->Count() % nCalcCols )
+ nCalcLines++;
+ else if ( !nCalcLines )
+ nCalcLines = 1;
+ }
+ }
+ }
+
+ Size aSize( rItemSize.Width()*nCalcCols, rItemSize.Height()*nCalcLines );
+ WinBits nStyle = GetStyle();
+ long nTxtHeight = GetTextHeight();
+ long nSpace;
+ long n;
+
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ if ( nStyle & WB_DOUBLEBORDER )
+ n = ITEM_OFFSET_DOUBLE;
+ else
+ n = ITEM_OFFSET;
+
+ aSize.Width() += n*nCalcCols;
+ aSize.Height() += n*nCalcLines;
+ }
+ else
+ n = 0;
+
+ if ( mnSpacing )
+ {
+ nSpace = mnSpacing;
+ aSize.Width() += mnSpacing*(nCalcCols-1);
+ aSize.Height() += mnSpacing*(nCalcLines-1);
+ }
+ else
+ nSpace = 0;
+
+ if ( nStyle & WB_NAMEFIELD )
+ {
+ aSize.Height() += nTxtHeight + NAME_OFFSET;
+ if ( !(nStyle & WB_FLATVALUESET) )
+ aSize.Height() += NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
+ }
+
+ if ( nStyle & WB_NONEFIELD )
+ {
+ aSize.Height() += nTxtHeight + n + nSpace;
+ if ( nStyle & WB_RADIOSEL )
+ aSize.Height() += 8;
+ }
+
+ // Evt. ScrollBar-Breite aufaddieren
+ aSize.Width() += GetScrollWidth();
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+Size ValueSet::CalcItemSizePixel( const Size& rItemSize, BOOL bOut ) const
+{
+ Size aSize = rItemSize;
+
+ WinBits nStyle = GetStyle();
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ long n;
+
+ if ( nStyle & WB_DOUBLEBORDER )
+ n = ITEM_OFFSET_DOUBLE;
+ else
+ n = ITEM_OFFSET;
+
+ if ( bOut )
+ {
+ aSize.Width() += n;
+ aSize.Height() += n;
+ }
+ else
+ {
+ aSize.Width() -= n;
+ aSize.Height() -= n;
+ }
+ }
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+long ValueSet::GetScrollWidth() const
+{
+ if ( GetStyle() & WB_VSCROLL )
+ {
+ ((ValueSet*)this)->ImplInitScrollBar();
+ return mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
+ }
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::ShowDropPos( const Point& rPos )
+{
+ mbDropPos = TRUE;
+
+ // Gegebenenfalls scrollen
+ ImplScroll( rPos );
+
+ // DropPosition ermitteln
+ USHORT nPos = ImplGetItem( rPos, TRUE );
+ if ( nPos == VALUESET_ITEM_NONEITEM )
+ nPos = 0;
+ else if ( nPos == VALUESET_ITEM_NOTFOUND )
+ {
+ Size aOutSize = GetOutputSizePixel();
+ if ( GetStyle() & WB_NAMEFIELD )
+ aOutSize.Height() = mnTextOffset;
+ if ( (rPos.X() >= 0) && (rPos.X() < aOutSize.Width()) &&
+ (rPos.Y() >= 0) && (rPos.Y() < aOutSize.Height()) )
+ nPos = (USHORT)mpImpl->mpItemList->Count();
+ }
+ else
+ {
+ // Im letzten viertel, dann wird ein Item spaeter eingefuegt
+ Rectangle aRect = mpImpl->mpItemList->GetObject( nPos )->maRect;
+ if ( rPos.X() > aRect.Left()+aRect.GetWidth()-(aRect.GetWidth()/4) )
+ nPos++;
+ }
+
+ if ( nPos != mnDropPos )
+ {
+ ImplDrawDropPos( FALSE );
+ mnDropPos = nPos;
+ ImplDrawDropPos( TRUE );
+ }
+
+ return mnDropPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::HideDropPos()
+{
+ if ( mbDropPos )
+ {
+ ImplDrawDropPos( FALSE );
+ mbDropPos = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+bool ValueSet::IsRTLActive (void)
+{
+ return Application::GetSettings().GetLayoutRTL() && IsRTLEnabled();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetHighlightHdl( const Link& rLink )
+{
+ mpImpl->maHighlightHdl = rLink;
+}
+
+// -----------------------------------------------------------------------
+
+const Link& ValueSet::GetHighlightHdl() const
+{
+ return mpImpl->maHighlightHdl;
+}
+
+// -----------------------------------------------------------------------
+
diff --git a/svtools/source/dialogs/addresstemplate.cxx b/svtools/source/dialogs/addresstemplate.cxx
new file mode 100644
index 000000000000..9a66230f012c
--- /dev/null
+++ b/svtools/source/dialogs/addresstemplate.cxx
@@ -0,0 +1,1340 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <stdio.h>
+
+
+#include "addresstemplate.hxx"
+#ifndef _SVT_ADDRESSTEMPLATE_HRC_
+#include "addresstemplate.hrc"
+#endif
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#ifndef _SVT_HELPID_HRC
+#include <svtools/helpid.hrc>
+#endif
+#include <svtools/svtdata.hxx>
+#include <tools/debug.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/stl_types.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/msgbox.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#ifndef _CPPUHELPER_EXTRACT_HXX_
+#include <cppuhelper/extract.hxx>
+#endif
+#include <comphelper/interaction.hxx>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include "localresaccess.hxx"
+#ifndef SVTOOLS_FILENOTATION_HXX_
+#include "svl/filenotation.hxx"
+#endif
+#include <tools/urlobj.hxx>
+
+#include <algorithm>
+
+// .......................................................................
+namespace svt
+{
+// .......................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::ui::dialogs;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::task;
+ using namespace ::comphelper;
+ using namespace ::utl;
+
+ DECLARE_STL_VECTOR( String, StringArray );
+ DECLARE_STL_STDKEY_SET( ::rtl::OUString, StringBag );
+ DECLARE_STL_USTRINGACCESS_MAP( ::rtl::OUString, MapString2String );
+
+ namespace
+ {
+ String lcl_getSelectedDataSource( const ComboBox& _dataSourceCombo )
+ {
+ String selectedDataSource = _dataSourceCombo.GetText();
+ if ( _dataSourceCombo.GetEntryPos( selectedDataSource ) == LISTBOX_ENTRY_NOTFOUND )
+ {
+ // none of the pre-selected entries -> assume a path to a database document
+ OFileNotation aFileNotation( selectedDataSource, OFileNotation::N_SYSTEM );
+ selectedDataSource = aFileNotation.get( OFileNotation::N_URL );
+ }
+ return selectedDataSource;
+ }
+ }
+
+ // ===================================================================
+ // = IAssigmentData
+ // ===================================================================
+ class IAssigmentData
+ {
+ public:
+ virtual ~IAssigmentData();
+
+ /// the data source to use for the address book
+ virtual ::rtl::OUString getDatasourceName() const = 0;
+
+ /// the command to use for the address book
+ virtual ::rtl::OUString getCommand() const = 0;
+
+ /** the command type to use for the address book
+ @return
+ a <type scope="com.sun.star.sdb">CommandType</type> value
+ */
+ virtual sal_Int32 getCommandType() const = 0;
+
+ /// checks whether or not there is an assignment for a given logical field
+ virtual sal_Bool hasFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
+ /// retrieves the assignment for a given logical field
+ virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
+
+ /// set the assignment for a given logical field
+ virtual void setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment) = 0;
+ /// clear the assignment for a given logical field
+ virtual void clearFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
+
+ virtual void setDatasourceName(const ::rtl::OUString& _rName) = 0;
+ virtual void setCommand(const ::rtl::OUString& _rCommand) = 0;
+ };
+
+ // -------------------------------------------------------------------
+ IAssigmentData::~IAssigmentData()
+ {
+ }
+
+ // ===================================================================
+ // = AssigmentTransientData
+ // ===================================================================
+ class AssigmentTransientData : public IAssigmentData
+ {
+ protected:
+ Reference< XDataSource > m_xDataSource;
+ ::rtl::OUString m_sDSName;
+ ::rtl::OUString m_sTableName;
+ MapString2String m_aAliases;
+
+public:
+ AssigmentTransientData(
+ const Reference< XDataSource >& _rxDataSource,
+ const ::rtl::OUString& _rDataSourceName,
+ const ::rtl::OUString& _rTableName,
+ const Sequence< AliasProgrammaticPair >& _rFields
+ );
+
+ // IAssigmentData overridables
+ virtual ::rtl::OUString getDatasourceName() const;
+ virtual ::rtl::OUString getCommand() const;
+ virtual sal_Int32 getCommandType() const;
+
+ virtual sal_Bool hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
+ virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
+ virtual void setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
+ virtual void clearFieldAssignment(const ::rtl::OUString& _rLogicalName);
+
+ virtual void setDatasourceName(const ::rtl::OUString& _rName);
+ virtual void setCommand(const ::rtl::OUString& _rCommand);
+ };
+
+ // -------------------------------------------------------------------
+ AssigmentTransientData::AssigmentTransientData( const Reference< XDataSource >& _rxDataSource,
+ const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rTableName,
+ const Sequence< AliasProgrammaticPair >& _rFields )
+ :m_xDataSource( _rxDataSource )
+ ,m_sDSName( _rDataSourceName )
+ ,m_sTableName( _rTableName )
+ {
+ // fill our aliaes structure
+ // first collect all known programmatic names
+ StringBag aKnownNames;
+
+ String sLogicalFieldNames( SvtResId( STR_LOCAGICAL_FIELD_NAMES ) );
+ sal_Int32 nTokenCount = sLogicalFieldNames.GetTokenCount(';');
+ for (sal_Int32 i = 0; i<nTokenCount; ++i)
+ aKnownNames.insert(sLogicalFieldNames.GetToken((sal_uInt16)i, ';'));
+
+ // loop throuzh the given names
+ const AliasProgrammaticPair* pFields = _rFields.getConstArray();
+ for (;pFields != pFields; ++pFields)
+ {
+ StringBagIterator aKnownPos = aKnownNames.find( pFields->ProgrammaticName );
+ if ( aKnownNames.end() != aKnownPos )
+ {
+ m_aAliases[ pFields->ProgrammaticName ] = pFields->Alias;
+ }
+ else
+ {
+ DBG_ERROR ( ( ::rtl::OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
+ += ::rtl::OString(pFields->ProgrammaticName.getStr(), pFields->ProgrammaticName.getLength(), RTL_TEXTENCODING_ASCII_US)
+ += ::rtl::OString(")!")
+ ).getStr()
+ );
+ }
+ }
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssigmentTransientData::getDatasourceName() const
+ {
+ return m_sDSName;
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssigmentTransientData::getCommand() const
+ {
+ return m_sTableName;
+ }
+
+ // -------------------------------------------------------------------
+ sal_Int32 AssigmentTransientData::getCommandType() const
+ {
+ return CommandType::TABLE;
+ }
+
+ // -------------------------------------------------------------------
+ sal_Bool AssigmentTransientData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
+ {
+ ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
+ return ( m_aAliases.end() != aPos )
+ && ( aPos->second.getLength() );
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssigmentTransientData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
+ {
+ ::rtl::OUString sReturn;
+ ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
+ if ( m_aAliases.end() != aPos )
+ sReturn = aPos->second;
+
+ return sReturn;
+ }
+
+ // -------------------------------------------------------------------
+ void AssigmentTransientData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
+ {
+ m_aAliases[ _rLogicalName ] = _rAssignment;
+ }
+
+ // -------------------------------------------------------------------
+ void AssigmentTransientData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
+ {
+ MapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
+ if ( m_aAliases.end() != aPos )
+ m_aAliases.erase( aPos );
+ }
+
+ // -------------------------------------------------------------------
+ void AssigmentTransientData::setDatasourceName(const ::rtl::OUString&)
+ {
+ DBG_ERROR( "AssigmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
+ }
+
+ // -------------------------------------------------------------------
+ void AssigmentTransientData::setCommand(const ::rtl::OUString&)
+ {
+ DBG_ERROR( "AssigmentTransientData::setCommand: cannot be implemented for transient data!" );
+ }
+
+ // ===================================================================
+ // = AssignmentPersistentData
+ // ===================================================================
+ class AssignmentPersistentData
+ :public ::utl::ConfigItem
+ ,public IAssigmentData
+ {
+ protected:
+ StringBag m_aStoredFields;
+
+ protected:
+ ::com::sun::star::uno::Any
+ getProperty(const ::rtl::OUString& _rLocalName) const;
+ ::com::sun::star::uno::Any
+ getProperty(const sal_Char* _pLocalName) const;
+
+ ::rtl::OUString getStringProperty(const sal_Char* _pLocalName) const;
+ sal_Int32 getInt32Property(const sal_Char* _pLocalName) const;
+
+ ::rtl::OUString getStringProperty(const ::rtl::OUString& _rLocalName) const;
+
+ void setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue);
+
+ public:
+ AssignmentPersistentData();
+ ~AssignmentPersistentData();
+
+ // IAssigmentData overridables
+ virtual ::rtl::OUString getDatasourceName() const;
+ virtual ::rtl::OUString getCommand() const;
+ virtual sal_Int32 getCommandType() const;
+
+ virtual sal_Bool hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
+ virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
+ virtual void setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
+ virtual void clearFieldAssignment(const ::rtl::OUString& _rLogicalName);
+
+ virtual void setDatasourceName(const ::rtl::OUString& _rName);
+ virtual void setCommand(const ::rtl::OUString& _rCommand);
+
+ virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames);
+ virtual void Commit();
+ };
+
+
+void AssignmentPersistentData::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& )
+{
+}
+
+void AssignmentPersistentData::Commit()
+{
+}
+
+ // -------------------------------------------------------------------
+ AssignmentPersistentData::AssignmentPersistentData()
+ :ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.DataAccess/AddressBook" )))
+ {
+ Sequence< ::rtl::OUString > aStoredNames = GetNodeNames(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Fields")));
+ const ::rtl::OUString* pStoredNames = aStoredNames.getConstArray();
+ for (sal_Int32 i=0; i<aStoredNames.getLength(); ++i, ++pStoredNames)
+ m_aStoredFields.insert(*pStoredNames);
+ }
+
+ // -------------------------------------------------------------------
+ AssignmentPersistentData::~AssignmentPersistentData()
+ {
+ }
+
+ // -------------------------------------------------------------------
+ sal_Bool AssignmentPersistentData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
+ {
+ return (m_aStoredFields.end() != m_aStoredFields.find(_rLogicalName));
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssignmentPersistentData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
+ {
+ ::rtl::OUString sAssignment;
+ if (hasFieldAssignment(_rLogicalName))
+ {
+ ::rtl::OUString sFieldPath(RTL_CONSTASCII_USTRINGPARAM("Fields/"));
+ sFieldPath += _rLogicalName;
+ sFieldPath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
+ sAssignment = getStringProperty(sFieldPath);
+ }
+ return sAssignment;
+ }
+
+ // -------------------------------------------------------------------
+ Any AssignmentPersistentData::getProperty(const sal_Char* _pLocalName) const
+ {
+ return getProperty(::rtl::OUString::createFromAscii(_pLocalName));
+ }
+
+ // -------------------------------------------------------------------
+ Any AssignmentPersistentData::getProperty(const ::rtl::OUString& _rLocalName) const
+ {
+ Sequence< ::rtl::OUString > aProperties(&_rLocalName, 1);
+ Sequence< Any > aValues = const_cast<AssignmentPersistentData*>(this)->GetProperties(aProperties);
+ DBG_ASSERT(aValues.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
+ return aValues[0];
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssignmentPersistentData::getStringProperty(const ::rtl::OUString& _rLocalName) const
+ {
+ ::rtl::OUString sReturn;
+ getProperty( _rLocalName ) >>= sReturn;
+ return sReturn;
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssignmentPersistentData::getStringProperty(const sal_Char* _pLocalName) const
+ {
+ ::rtl::OUString sReturn;
+ getProperty( _pLocalName ) >>= sReturn;
+ return sReturn;
+ }
+
+ // -------------------------------------------------------------------
+ sal_Int32 AssignmentPersistentData::getInt32Property(const sal_Char* _pLocalName) const
+ {
+ sal_Int32 nReturn = 0;
+ getProperty( _pLocalName ) >>= nReturn;
+ return nReturn;
+ }
+
+ // -------------------------------------------------------------------
+ void AssignmentPersistentData::setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue)
+ {
+ Sequence< ::rtl::OUString > aNames(1);
+ Sequence< Any > aValues(1);
+ aNames[0] = ::rtl::OUString::createFromAscii(_pLocalName);
+ aValues[0] <<= _rValue;
+ PutProperties(aNames, aValues);
+ }
+
+ // -------------------------------------------------------------------
+ void AssignmentPersistentData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
+ {
+ if (!_rAssignment.getLength())
+ {
+ if (hasFieldAssignment(_rLogicalName))
+ // the assignment exists but it should be reset
+ clearFieldAssignment(_rLogicalName);
+ return;
+ }
+
+ // Fields
+ ::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
+
+ // Fields/<field>
+ ::rtl::OUString sFieldElementNodePath(sDescriptionNodePath);
+ sFieldElementNodePath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ sFieldElementNodePath += _rLogicalName;
+
+ Sequence< PropertyValue > aNewFieldDescription(2);
+ // Fields/<field>/ProgrammaticFieldName
+ aNewFieldDescription[0].Name = sFieldElementNodePath;
+ aNewFieldDescription[0].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/ProgrammaticFieldName"));
+ aNewFieldDescription[0].Value <<= _rLogicalName;
+ // Fields/<field>/AssignedFieldName
+ aNewFieldDescription[1].Name = sFieldElementNodePath;
+ aNewFieldDescription[1].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
+ aNewFieldDescription[1].Value <<= _rAssignment;
+
+ // just set the new value
+#ifdef DBG_UTIL
+ sal_Bool bSuccess =
+#endif
+ SetSetProperties(sDescriptionNodePath, aNewFieldDescription);
+ DBG_ASSERT(bSuccess, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
+ }
+
+ // -------------------------------------------------------------------
+ void AssignmentPersistentData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
+ {
+ if (!hasFieldAssignment(_rLogicalName))
+ // nothing to do
+ return;
+
+ ::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
+ Sequence< ::rtl::OUString > aNames(&_rLogicalName, 1);
+ ClearNodeElements(sDescriptionNodePath, aNames);
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssignmentPersistentData::getDatasourceName() const
+ {
+ return getStringProperty( "DataSourceName" );
+ }
+
+ // -------------------------------------------------------------------
+ ::rtl::OUString AssignmentPersistentData::getCommand() const
+ {
+ return getStringProperty( "Command" );
+ }
+
+ // -------------------------------------------------------------------
+ void AssignmentPersistentData::setDatasourceName(const ::rtl::OUString& _rName)
+ {
+ setStringProperty( "DataSourceName", _rName );
+ }
+
+ // -------------------------------------------------------------------
+ void AssignmentPersistentData::setCommand(const ::rtl::OUString& _rCommand)
+ {
+ setStringProperty( "Command", _rCommand );
+ }
+
+ // -------------------------------------------------------------------
+ sal_Int32 AssignmentPersistentData::getCommandType() const
+ {
+ return getInt32Property( "CommandType" );
+ }
+
+ // ===================================================================
+ // = AddressBookSourceDialogData
+ // ===================================================================
+ struct AddressBookSourceDialogData
+ {
+ FixedText* pFieldLabels[FIELD_PAIRS_VISIBLE * 2];
+ ListBox* pFields[FIELD_PAIRS_VISIBLE * 2];
+
+ /// when working transient, we need the data source
+ Reference< XDataSource >
+ m_xTransientDataSource;
+ /// current scroll pos in the field list
+ sal_Int32 nFieldScrollPos;
+ /// the index within m_pFields of the last visible list box. This is redundant, it could be extracted from other members
+ sal_Int32 nLastVisibleListIndex;
+ /// indicates that we've an odd field number. This member is for efficiency only, it's redundant.
+ sal_Bool bOddFieldNumber : 1;
+ /// indicates that we're working with the real persistent configuration
+ sal_Bool bWorkingPersistent : 1;
+
+ /// the strings to use as labels for the field selection listboxes
+ StringArray aFieldLabels;
+ // the current field assignment
+ StringArray aFieldAssignments;
+ /// the logical field names
+ StringArray aLogicalFieldNames;
+
+ IAssigmentData* pConfigData;
+
+ // ................................................................
+ AddressBookSourceDialogData( )
+ :nFieldScrollPos(0)
+ ,nLastVisibleListIndex(0)
+ ,bOddFieldNumber(sal_False)
+ ,bWorkingPersistent( sal_True )
+ ,pConfigData( new AssignmentPersistentData )
+ {
+ }
+
+ // ................................................................
+ AddressBookSourceDialogData( const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
+ const ::rtl::OUString& _rTableName, const Sequence< AliasProgrammaticPair >& _rFields )
+ :m_xTransientDataSource( _rxTransientDS )
+ ,nFieldScrollPos(0)
+ ,nLastVisibleListIndex(0)
+ ,bOddFieldNumber(sal_False)
+ ,bWorkingPersistent( sal_False )
+ ,pConfigData( new AssigmentTransientData( m_xTransientDataSource, _rDataSourceName, _rTableName, _rFields ) )
+ {
+ }
+
+ ~AddressBookSourceDialogData()
+ {
+ delete pConfigData;
+ }
+
+ };
+
+ // ===================================================================
+ // = AddressBookSourceDialog
+ // ===================================================================
+#define INIT_FIELDS() \
+ ModalDialog(_pParent, SvtResId( DLG_ADDRESSBOOKSOURCE ))\
+ ,m_aDatasourceFrame (this, SvtResId(FL_DATASOURCEFRAME))\
+ ,m_aDatasourceLabel (this, SvtResId(FT_DATASOURCE))\
+ ,m_aDatasource (this, SvtResId(CB_DATASOURCE))\
+ ,m_aAdministrateDatasources (this, SvtResId(PB_ADMINISTATE_DATASOURCES))\
+ ,m_aTableLabel (this, SvtResId(FT_TABLE))\
+ ,m_aTable (this, SvtResId(CB_TABLE))\
+ ,m_aFieldsTitle (this, SvtResId(FT_FIELDS))\
+ ,m_aFieldsFrame (this, SvtResId(CT_BORDER))\
+ ,m_aFieldScroller (&m_aFieldsFrame, SvtResId(SB_FIELDSCROLLER))\
+ ,m_aOK (this, SvtResId(PB_OK))\
+ ,m_aCancel (this, SvtResId(PB_CANCEL))\
+ ,m_aHelp (this, SvtResId(PB_HELP))\
+ ,m_sNoFieldSelection(SvtResId(STR_NO_FIELD_SELECTION))\
+ ,m_xORB(_rxORB)
+
+ // -------------------------------------------------------------------
+ AddressBookSourceDialog::AddressBookSourceDialog(Window* _pParent,
+ const Reference< XMultiServiceFactory >& _rxORB )
+ :INIT_FIELDS()
+ ,m_pImpl( new AddressBookSourceDialogData )
+ {
+ implConstruct();
+ }
+
+ // -------------------------------------------------------------------
+ AddressBookSourceDialog::AddressBookSourceDialog( Window* _pParent, const Reference< XMultiServiceFactory >& _rxORB,
+ const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
+ const ::rtl::OUString& _rTable, const Sequence< AliasProgrammaticPair >& _rMapping )
+ :INIT_FIELDS()
+ ,m_pImpl( new AddressBookSourceDialogData( _rxTransientDS, _rDataSourceName, _rTable, _rMapping ) )
+ {
+ implConstruct();
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::implConstruct()
+ {
+ for (sal_Int32 row=0; row<FIELD_PAIRS_VISIBLE; ++row)
+ {
+ for (sal_Int32 column=0; column<2; ++column)
+ {
+ // the label
+ m_pImpl->pFieldLabels[row * 2 + column] = new FixedText(&m_aFieldsFrame, SvtResId((USHORT)(FT_FIELD_BASE + row * 2 + column)));
+ // the listbox
+ m_pImpl->pFields[row * 2 + column] = new ListBox(&m_aFieldsFrame, SvtResId((USHORT)(LB_FIELD_BASE + row * 2 + column)));
+ m_pImpl->pFields[row * 2 + column]->SetDropDownLineCount(15);
+ m_pImpl->pFields[row * 2 + column]->SetSelectHdl(LINK(this, AddressBookSourceDialog, OnFieldSelect));
+
+ m_pImpl->pFields[row * 2 + column]->SetHelpId(HID_ADDRTEMPL_FIELD_ASSIGNMENT);
+ }
+ }
+
+ m_aFieldsFrame.SetStyle((m_aFieldsFrame.GetStyle() | WB_TABSTOP | WB_DIALOGCONTROL) & ~WB_NODIALOGCONTROL);
+
+ // correct the z-order
+ m_aFieldScroller.SetZOrder(m_pImpl->pFields[FIELD_CONTROLS_VISIBLE - 1], WINDOW_ZORDER_BEHIND);
+ m_aOK.SetZOrder(&m_aFieldsFrame, WINDOW_ZORDER_BEHIND);
+ m_aCancel.SetZOrder(&m_aOK, WINDOW_ZORDER_BEHIND);
+
+ initializeDatasources();
+
+ // for the moment, we have a hard coded list of all known fields.
+ // A better solution would be to store all known field translations in the configuration, which could be
+ // extensible by the user in an arbitrary way.
+ // But for the moment we need a quick solution ...
+ // (the main thing would be to store the translations to use here in the user interface, besides that, the code
+ // should be adjustable with a rather small effort.)
+
+ // initialize the strings for the field labels
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_FIRSTNAME )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_LASTNAME )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_COMPANY)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_DEPARTMENT )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_STREET )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ZIPCODE )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_CITY )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_STATE)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_COUNTRY )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_HOMETEL )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_WORKTEL )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_OFFICETEL)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_MOBILE)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_TELOTHER)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_PAGER)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_FAX )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_EMAIL )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_URL )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_TITLE )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_POSITION )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_INITIALS )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ADDRFORM )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_SALUTATION )) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ID)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_CALENDAR)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_INVITE)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_NOTE)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER1)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER2)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER3)) );
+ m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER4)) );
+
+ // force a even number of known fields
+ m_pImpl->bOddFieldNumber = (m_pImpl->aFieldLabels.size() % 2) != 0;
+ if (m_pImpl->bOddFieldNumber)
+ m_pImpl->aFieldLabels.push_back( String() );
+
+ // limit the scrollbar range accordingly
+ sal_Int32 nOverallFieldPairs = m_pImpl->aFieldLabels.size() / 2;
+ m_aFieldScroller.SetRange( Range(0, nOverallFieldPairs - FIELD_PAIRS_VISIBLE) );
+ m_aFieldScroller.SetLineSize(1);
+ m_aFieldScroller.SetPageSize(FIELD_PAIRS_VISIBLE);
+
+ // reset the current field assignments
+ m_pImpl->aFieldAssignments.resize(m_pImpl->aFieldLabels.size());
+ // (empty strings mean "no assignment")
+
+ // some knittings
+ m_aFieldScroller.SetScrollHdl(LINK(this, AddressBookSourceDialog, OnFieldScroll));
+ m_aAdministrateDatasources.SetClickHdl(LINK(this, AddressBookSourceDialog, OnAdministrateDatasources));
+ m_aDatasource.EnableAutocomplete(sal_True);
+ m_aTable.EnableAutocomplete(sal_True);
+ m_aTable.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
+ m_aDatasource.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
+ m_aTable.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
+ m_aDatasource.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
+ m_aTable.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
+ m_aDatasource.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
+ m_aOK.SetClickHdl(LINK(this, AddressBookSourceDialog, OnOkClicked));
+
+ m_aDatasource.SetDropDownLineCount(15);
+
+ // initialize the field controls
+ resetFields();
+ m_aFieldScroller.SetThumbPos(0);
+ m_pImpl->nFieldScrollPos = -1;
+ implScrollFields(0, sal_False, sal_False);
+
+ // the logical names
+ String sLogicalFieldNames(SvtResId(STR_LOCAGICAL_FIELD_NAMES));
+ sal_Int32 nAdjustedTokenCount = sLogicalFieldNames.GetTokenCount(';') + (m_pImpl->bOddFieldNumber ? 1 : 0);
+ DBG_ASSERT(nAdjustedTokenCount == (sal_Int32)m_pImpl->aFieldLabels.size(),
+ "AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
+ m_pImpl->aLogicalFieldNames.reserve(nAdjustedTokenCount);
+ for (sal_Int32 i = 0; i<nAdjustedTokenCount; ++i)
+ m_pImpl->aLogicalFieldNames.push_back(sLogicalFieldNames.GetToken((sal_uInt16)i, ';'));
+
+ PostUserEvent(LINK(this, AddressBookSourceDialog, OnDelayedInitialize));
+ // so the dialog will at least show up before we do the loading of the
+ // configuration data and the (maybe time consuming) analysis of the data source/table to select
+
+ FreeResource();
+
+ if ( !m_pImpl->bWorkingPersistent )
+ {
+ StyleSettings aSystemStyle = GetSettings().GetStyleSettings();
+ const Color& rNewColor = aSystemStyle.GetDialogColor();
+
+ m_aDatasource.SetReadOnly( sal_True );
+ m_aDatasource.SetBackground( Wallpaper( rNewColor ) );
+ m_aDatasource.SetControlBackground( rNewColor );
+
+ m_aTable.SetReadOnly( sal_True );
+ m_aTable.SetBackground( Wallpaper( rNewColor ) );
+ m_aTable.SetControlBackground( rNewColor );
+
+ m_aAdministrateDatasources.Hide( );
+ }
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::getFieldMapping(Sequence< AliasProgrammaticPair >& _rMapping) const
+ {
+ _rMapping.realloc( m_pImpl->aLogicalFieldNames.size() );
+ AliasProgrammaticPair* pPair = _rMapping.getArray();
+
+ ::rtl::OUString sCurrent;
+ for ( ConstStringArrayIterator aProgrammatic = m_pImpl->aLogicalFieldNames.begin();
+ aProgrammatic != m_pImpl->aLogicalFieldNames.end();
+ ++aProgrammatic
+ )
+ {
+ sCurrent = *aProgrammatic;
+ if ( m_pImpl->pConfigData->hasFieldAssignment( sCurrent ) )
+ {
+ // the user gave us an assignment for this field
+ pPair->ProgrammaticName = *aProgrammatic;
+ pPair->Alias = m_pImpl->pConfigData->getFieldAssignment( *aProgrammatic );
+ ++pPair;
+ }
+ }
+
+ _rMapping.realloc( pPair - _rMapping.getArray() );
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::loadConfiguration()
+ {
+ ::rtl::OUString sName = m_pImpl->pConfigData->getDatasourceName();
+ INetURLObject aURL( sName );
+ if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
+ {
+ OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
+ sName = aFileNotation.get(OFileNotation::N_SYSTEM);
+ }
+
+ m_aDatasource.SetText(sName);
+ m_aTable.SetText(m_pImpl->pConfigData->getCommand());
+ // we ignore the CommandType: only tables are supported
+
+ // the logical names for the fields
+ DBG_ASSERT(m_pImpl->aLogicalFieldNames.size() == m_pImpl->aFieldAssignments.size(),
+ "AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!");
+
+ ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
+ StringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
+ for ( ;
+ aLogical < m_pImpl->aLogicalFieldNames.end();
+ ++aLogical, ++aAssignment
+ )
+ *aAssignment = m_pImpl->pConfigData->getFieldAssignment(*aLogical);
+ }
+
+ // -------------------------------------------------------------------
+ AddressBookSourceDialog::~AddressBookSourceDialog()
+ {
+ sal_Int32 i;
+ for (i=0; i<FIELD_CONTROLS_VISIBLE; ++i)
+ {
+ delete m_pImpl->pFieldLabels[i];
+ delete m_pImpl->pFields[i];
+ }
+
+ delete m_pImpl;
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::initializeDatasources()
+ {
+ if (!m_xDatabaseContext.is())
+ {
+ DBG_ASSERT(m_xORB.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
+ if (!m_xORB.is())
+ return;
+
+ const String sContextServiceName = String::CreateFromAscii("com.sun.star.sdb.DatabaseContext");
+ try
+ {
+ m_xDatabaseContext = Reference< XNameAccess >(m_xORB->createInstance(sContextServiceName), UNO_QUERY);
+ }
+ catch(Exception&) { }
+ if (!m_xDatabaseContext.is())
+ {
+ ShowServiceNotAvailableError( this, sContextServiceName, sal_False);
+ return;
+ }
+ }
+ m_aDatasource.Clear();
+
+ // fill the datasources listbox
+ Sequence< ::rtl::OUString > aDatasourceNames;
+ try
+ {
+ aDatasourceNames = m_xDatabaseContext->getElementNames();
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
+ }
+ const ::rtl::OUString* pDatasourceNames = aDatasourceNames.getConstArray();
+ const ::rtl::OUString* pEnd = pDatasourceNames + aDatasourceNames.getLength();
+ for (; pDatasourceNames < pEnd; ++pDatasourceNames)
+ m_aDatasource.InsertEntry(*pDatasourceNames);
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnFieldScroll, ScrollBar*, _pScrollBar)
+ {
+ implScrollFields( _pScrollBar->GetThumbPos(), sal_True, sal_True );
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::resetTables()
+ {
+ if (!m_xDatabaseContext.is())
+ return;
+
+ WaitObject aWaitCursor(this);
+
+ // no matter what we do here, we handled the currently selected data source (no matter if successfull or not)
+ m_aDatasource.SaveValue();
+
+ // create an interaction handler (may be needed for connecting)
+ const String sInteractionHandlerServiceName = String::CreateFromAscii("com.sun.star.task.InteractionHandler");
+ Reference< XInteractionHandler > xHandler;
+ try
+ {
+ xHandler = Reference< XInteractionHandler >(m_xORB->createInstance(sInteractionHandlerServiceName), UNO_QUERY);
+ }
+ catch(Exception&) { }
+ if (!xHandler.is())
+ {
+ ShowServiceNotAvailableError(this, sInteractionHandlerServiceName, sal_True);
+ return;
+ }
+
+ // the currently selected table
+ ::rtl::OUString sOldTable = m_aTable.GetText();
+
+ m_aTable.Clear();
+
+ m_xCurrentDatasourceTables= NULL;
+
+ // get the tables of the connection
+ Sequence< ::rtl::OUString > aTableNames;
+ Any aException;
+ try
+ {
+ Reference< XCompletedConnection > xDS;
+ if ( m_pImpl->bWorkingPersistent )
+ {
+ String sSelectedDS = lcl_getSelectedDataSource( m_aDatasource );
+
+ // get the data source the user has chosen and let it build a connection
+ INetURLObject aURL( sSelectedDS );
+ if ( aURL.GetProtocol() != INET_PROT_NOT_VALID || m_xDatabaseContext->hasByName(sSelectedDS) )
+ m_xDatabaseContext->getByName( sSelectedDS ) >>= xDS;
+ }
+ else
+ {
+ xDS = xDS.query( m_pImpl->m_xTransientDataSource );
+ }
+
+ // build the connection
+ Reference< XConnection > xConn;
+ if (xDS.is())
+ xConn = xDS->connectWithCompletion(xHandler);
+
+ // get the table names
+ Reference< XTablesSupplier > xSupplTables(xConn, UNO_QUERY);
+ if (xSupplTables.is())
+ {
+ m_xCurrentDatasourceTables = Reference< XNameAccess >(xSupplTables->getTables(), UNO_QUERY);
+ if (m_xCurrentDatasourceTables.is())
+ aTableNames = m_xCurrentDatasourceTables->getElementNames();
+ }
+ }
+ catch(SQLContext& e) { aException <<= e; }
+ catch(SQLWarning& e) { aException <<= e; }
+ catch(SQLException& e) { aException <<= e; }
+ catch(Exception&)
+ {
+ DBG_ERROR("AddressBookSourceDialog::resetTables: could not retrieve the table!");
+ }
+
+ if (aException.hasValue())
+ {
+ Reference< XInteractionRequest > xRequest = new OInteractionRequest(aException);
+ try
+ {
+ xHandler->handle(xRequest);
+ }
+ catch(Exception&) { }
+ return;
+ }
+
+ sal_Bool bKnowOldTable = sal_False;
+ // fill the table list
+ const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
+ const ::rtl::OUString* pEnd = pTableNames + aTableNames.getLength();
+ for (;pTableNames != pEnd; ++pTableNames)
+ {
+ m_aTable.InsertEntry(*pTableNames);
+ if (0 == pTableNames->compareTo(sOldTable))
+ bKnowOldTable = sal_True;
+ }
+
+ // set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
+ if (!bKnowOldTable)
+ sOldTable = ::rtl::OUString();
+ m_aTable.SetText(sOldTable);
+
+ resetFields();
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::resetFields()
+ {
+ WaitObject aWaitCursor(this);
+
+ // no matter what we do here, we handled the currently selected table (no matter if successfull or not)
+ m_aDatasource.SaveValue();
+
+ String sSelectedTable = m_aTable.GetText();
+ Sequence< ::rtl::OUString > aColumnNames;
+ try
+ {
+ if (m_xCurrentDatasourceTables.is())
+ {
+ // get the table and the columns
+ Reference< XColumnsSupplier > xSuppTableCols;
+ if (m_xCurrentDatasourceTables->hasByName(sSelectedTable))
+ ::cppu::extractInterface(xSuppTableCols, m_xCurrentDatasourceTables->getByName(sSelectedTable));
+ Reference< XNameAccess > xColumns;
+ if (xSuppTableCols.is())
+ xColumns = xSuppTableCols->getColumns();
+ if (xColumns.is())
+ aColumnNames = xColumns->getElementNames();
+ }
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
+ }
+
+
+ const ::rtl::OUString* pColumnNames = aColumnNames.getConstArray();
+ const ::rtl::OUString* pEnd = pColumnNames + aColumnNames.getLength();
+
+ // for quicker access
+ ::std::set< String > aColumnNameSet;
+ for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
+ aColumnNameSet.insert(*pColumnNames);
+
+ std::vector<String>::iterator aInitialSelection = m_pImpl->aFieldAssignments.begin() + m_pImpl->nFieldScrollPos;
+
+ ListBox** pListbox = m_pImpl->pFields;
+ String sSaveSelection;
+ for (sal_Int32 i=0; i<FIELD_CONTROLS_VISIBLE; ++i, ++pListbox, ++aInitialSelection)
+ {
+ sSaveSelection = (*pListbox)->GetSelectEntry();
+
+ (*pListbox)->Clear();
+
+ // the one entry for "no selection"
+ (*pListbox)->InsertEntry(m_sNoFieldSelection, 0);
+ // as it's entry data, set the index of the list box in our array
+ (*pListbox)->SetEntryData(0, reinterpret_cast<void*>(i));
+
+ // the field names
+ for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
+ (*pListbox)->InsertEntry(*pColumnNames);
+
+ if (aInitialSelection->Len() && (aColumnNameSet.end() != aColumnNameSet.find(*aInitialSelection)))
+ // we can select the entry as specified in our field assignment array
+ (*pListbox)->SelectEntry(*aInitialSelection);
+ else
+ // try to restore the selection
+ if (aColumnNameSet.end() != aColumnNameSet.find(sSaveSelection))
+ // the old selection is a valid column name
+ (*pListbox)->SelectEntry(sSaveSelection);
+ else
+ // select the <none> entry
+ (*pListbox)->SelectEntryPos(0);
+ }
+
+ // adjust m_pImpl->aFieldAssignments
+ for ( StringArrayIterator aAdjust = m_pImpl->aFieldAssignments.begin();
+ aAdjust != m_pImpl->aFieldAssignments.end();
+ ++aAdjust
+ )
+ if (aAdjust->Len())
+ if (aColumnNameSet.end() == aColumnNameSet.find(*aAdjust))
+ aAdjust->Erase();
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnFieldSelect, ListBox*, _pListbox)
+ {
+ // the index of the affected list box in our array
+ sal_IntPtr nListBoxIndex = reinterpret_cast<sal_IntPtr>(_pListbox->GetEntryData(0));
+ DBG_ASSERT(nListBoxIndex >= 0 && nListBoxIndex < FIELD_CONTROLS_VISIBLE,
+ "AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");
+
+ // update the array where we remember the field selections
+ if (0 == _pListbox->GetSelectEntryPos())
+ // it's the "no field selection" entry
+ m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = String();
+ else
+ // it's a regular field entry
+ m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = _pListbox->GetSelectEntry();
+
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos, sal_Bool _bAdjustFocus, sal_Bool _bAdjustScrollbar)
+ {
+ if (_nPos == m_pImpl->nFieldScrollPos)
+ // nothing to do
+ return;
+
+ // loop through our field control rows and do some adjustments
+ // for the new texts
+ FixedText** pLeftLabelControl = m_pImpl->pFieldLabels;
+ FixedText** pRightLabelControl = pLeftLabelControl + 1;
+ ConstStringArrayIterator pLeftColumnLabel = m_pImpl->aFieldLabels.begin() + 2 * _nPos;
+ ConstStringArrayIterator pRightColumnLabel = pLeftColumnLabel + 1;
+
+ // for the focus movement and the selection scroll
+ ListBox** pLeftListControl = m_pImpl->pFields;
+ ListBox** pRightListControl = pLeftListControl + 1;
+
+ // for the focus movement
+ sal_Int32 nOldFocusRow = -1;
+ sal_Int32 nOldFocusColumn = 0;
+
+ // for the selection scroll
+ ConstStringArrayIterator pLeftAssignment = m_pImpl->aFieldAssignments.begin() + 2 * _nPos;
+ ConstStringArrayIterator pRightAssignment = pLeftAssignment + 1;
+
+ m_pImpl->nLastVisibleListIndex = -1;
+ // loop
+ for (sal_Int32 i=0; i<FIELD_PAIRS_VISIBLE; ++i)
+ {
+ if ((*pLeftListControl)->HasChildPathFocus())
+ {
+ nOldFocusRow = i;
+ nOldFocusColumn = 0;
+ }
+ else if ((*pRightListControl)->HasChildPathFocus())
+ {
+ nOldFocusRow = i;
+ nOldFocusColumn = 1;
+ }
+
+ // the new texts of the label controls
+ (*pLeftLabelControl)->SetText(*pLeftColumnLabel);
+ (*pRightLabelControl)->SetText(*pRightColumnLabel);
+
+ // we may have to hide the controls in the right column, if we have no label text for it
+ // (which means we have an odd number of fields, though we forced our internal arrays to
+ // be even-sized for easier handling)
+ // (If sometimes we support an arbitrary number of field assignments, we would have to care for
+ // an invisible left hand side column, too. But right now, the left hand side controls are always
+ // visible)
+ sal_Bool bHideRightColumn = (0 == pRightColumnLabel->Len());
+ (*pRightLabelControl)->Show(!bHideRightColumn);
+ (*pRightListControl)->Show(!bHideRightColumn);
+ // the new selections of the listboxes
+ implSelectField(*pLeftListControl, *pLeftAssignment);
+ implSelectField(*pRightListControl, *pRightAssignment);
+
+ // the index of the last visible list box
+ ++m_pImpl->nLastVisibleListIndex; // the left hand side box is always visible
+ if (!bHideRightColumn)
+ ++m_pImpl->nLastVisibleListIndex;
+
+ // increment ...
+ if ( i < FIELD_PAIRS_VISIBLE - 1 )
+ { // (not in the very last round, here the +=2 could result in an invalid
+ // iterator position, which causes an abort in a non-product version
+ pLeftLabelControl += 2;
+ pRightLabelControl += 2;
+ pLeftColumnLabel += 2;
+ pRightColumnLabel += 2;
+
+ pLeftListControl += 2;
+ pRightListControl += 2;
+ pLeftAssignment += 2;
+ pRightAssignment += 2;
+ }
+ }
+
+ if (_bAdjustFocus && (nOldFocusRow >= 0))
+ { // we have to adjust the focus and one of the list boxes has the focus
+ sal_Int32 nDelta = m_pImpl->nFieldScrollPos - _nPos;
+ // the new row for the focus
+ sal_Int32 nNewFocusRow = nOldFocusRow + nDelta;
+ // normalize
+ nNewFocusRow = std::min(nNewFocusRow, (sal_Int32)(FIELD_PAIRS_VISIBLE - 1), ::std::less< sal_Int32 >());
+ nNewFocusRow = std::max(nNewFocusRow, (sal_Int32)0, ::std::less< sal_Int32 >());
+ // set the new focus (in the same column)
+ m_pImpl->pFields[nNewFocusRow * 2 + nOldFocusColumn]->GrabFocus();
+ }
+
+ m_pImpl->nFieldScrollPos = _nPos;
+
+ if (_bAdjustScrollbar)
+ m_aFieldScroller.SetThumbPos(m_pImpl->nFieldScrollPos);
+ }
+
+ // -------------------------------------------------------------------
+ void AddressBookSourceDialog::implSelectField(ListBox* _pBox, const String& _rText)
+ {
+ if (_rText.Len())
+ // a valid field name
+ _pBox->SelectEntry(_rText);
+ else
+ // no selection for this item
+ _pBox->SelectEntryPos(0);
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnDelayedInitialize, void*, EMPTYARG)
+ {
+ // load the initial data from the configuration
+ loadConfiguration();
+ resetTables();
+ // will reset the tables/fields implicitly
+
+ if ( !m_pImpl->bWorkingPersistent )
+ if ( m_pImpl->pFields[0] )
+ m_pImpl->pFields[0]->GrabFocus();
+
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnComboSelect, ComboBox*, _pBox)
+ {
+ if (_pBox == &m_aDatasource)
+ resetTables();
+ else
+ resetFields();
+ return 0;
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnComboGetFocus, ComboBox*, _pBox)
+ {
+ _pBox->SaveValue();
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnComboLoseFocus, ComboBox*, _pBox)
+ {
+ if (_pBox->GetSavedValue() != _pBox->GetText())
+ {
+ if (_pBox == &m_aDatasource)
+ resetTables();
+ else
+ resetFields();
+ }
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnOkClicked, Button*, EMPTYARG)
+ {
+ String sSelectedDS = lcl_getSelectedDataSource( m_aDatasource );
+ if ( m_pImpl->bWorkingPersistent )
+ {
+ m_pImpl->pConfigData->setDatasourceName(sSelectedDS);
+ m_pImpl->pConfigData->setCommand(m_aTable.GetText());
+ }
+
+ // set the field assignments
+ ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
+ ConstStringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
+ for ( ;
+ aLogical < m_pImpl->aLogicalFieldNames.end();
+ ++aLogical, ++aAssignment
+ )
+ m_pImpl->pConfigData->setFieldAssignment(*aLogical, *aAssignment);
+
+
+ EndDialog(RET_OK);
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ IMPL_LINK(AddressBookSourceDialog, OnAdministrateDatasources, void*, EMPTYARG)
+ {
+ // collect some initial arguments for the dialog
+ Sequence< Any > aArgs(1);
+ aArgs[0] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")), 0, makeAny(VCLUnoHelper::GetInterface(this)), PropertyState_DIRECT_VALUE);
+
+ // create the dialog object
+ const String sDialogServiceName = String::CreateFromAscii("com.sun.star.ui.dialogs.AddressBookSourcePilot");
+ Reference< XExecutableDialog > xAdminDialog;
+ try
+ {
+ xAdminDialog = Reference< XExecutableDialog >(m_xORB->createInstanceWithArguments(sDialogServiceName, aArgs), UNO_QUERY);
+ }
+ catch(Exception&) { }
+ if (!xAdminDialog.is())
+ {
+ ShowServiceNotAvailableError(this, sDialogServiceName, sal_True);
+ return 1L;
+ }
+
+ // excute the dialog
+ try
+ {
+ if ( xAdminDialog->execute() == RET_OK )
+ {
+ Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
+ if ( xProp.is() )
+ {
+ ::rtl::OUString sName;
+ xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSourceName"))) >>= sName;
+
+ INetURLObject aURL( sName );
+ if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
+ {
+ OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
+ sName = aFileNotation.get(OFileNotation::N_SYSTEM);
+ }
+ m_aDatasource.InsertEntry(sName);
+ delete m_pImpl->pConfigData;
+ m_pImpl->pConfigData = new AssignmentPersistentData();
+ loadConfiguration();
+ resetTables();
+ // will reset the fields implicitly
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("AddressBookSourceDialog::OnAdministrateDatasources: an error occured while executing the administration dialog!");
+ }
+
+ // re-fill the data source list
+ // try to preserve the current selection
+
+// initializeDatasources();
+
+ return 0L;
+ }
+
+ // -------------------------------------------------------------------
+ long AddressBookSourceDialog::PreNotify( NotifyEvent& _rNEvt )
+ {
+ switch (_rNEvt.GetType())
+ {
+ case EVENT_KEYINPUT:
+ {
+ const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
+ sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
+ sal_Bool bShift = pKeyEvent->GetKeyCode().IsShift();
+ sal_Bool bCtrl = pKeyEvent->GetKeyCode().IsMod1();
+ sal_Bool bAlt = pKeyEvent->GetKeyCode().IsMod2();
+
+ if (KEY_TAB == nCode)
+ { // somebody pressed the tab key
+ if (!bAlt && !bCtrl && !bShift)
+ { // it's really the only the key (no modifiers)
+ if (m_pImpl->pFields[m_pImpl->nLastVisibleListIndex]->HasChildPathFocus())
+ // the last of our visible list boxes has the focus
+ if (m_pImpl->nFieldScrollPos < m_aFieldScroller.GetRangeMax())
+ { // we can still scroll down
+ sal_Int32 nNextFocusList = m_pImpl->nLastVisibleListIndex + 1 - 2;
+ // -> scroll down
+ implScrollFields(m_pImpl->nFieldScrollPos + 1, sal_False, sal_True);
+ // give the left control in the "next" line the focus
+ m_pImpl->pFields[nNextFocusList]->GrabFocus();
+ // return saying "have handled this"
+ return 1;
+ }
+ }
+ else if (!bAlt && !bCtrl && bShift)
+ { // it's shift-tab
+ if (m_pImpl->pFields[0]->HasChildPathFocus())
+ // our first list box has the focus
+ if (m_pImpl->nFieldScrollPos > 0)
+ { // we can still scroll up
+ // -> scroll up
+ implScrollFields(m_pImpl->nFieldScrollPos - 1, sal_False, sal_True);
+ // give the right control in the "prebious" line the focus
+ m_pImpl->pFields[0 - 1 + 2]->GrabFocus();
+ // return saying "have handled this"
+ return 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+ return ModalDialog::PreNotify(_rNEvt);
+ }
+
+// .......................................................................
+} // namespace svt
+// .......................................................................
+
diff --git a/svtools/source/dialogs/addresstemplate.hrc b/svtools/source/dialogs/addresstemplate.hrc
new file mode 100644
index 000000000000..5fb89cd567fc
--- /dev/null
+++ b/svtools/source/dialogs/addresstemplate.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.
+ *
+ ************************************************************************/
+
+#ifndef _SVT_ADDRESSTEMPLATE_HRC_
+#define _SVT_ADDRESSTEMPLATE_HRC_
+
+
+#define FIELD_PAIRS_VISIBLE 5
+#define FIELD_CONTROLS_VISIBLE 2 * FIELD_PAIRS_VISIBLE
+
+#define FL_DATASOURCEFRAME 1
+#define FT_DATASOURCE 2
+#define CB_DATASOURCE 3
+#define CT_BORDER 1
+#define PB_ADMINISTATE_DATASOURCES 4
+#define FT_TABLE 5
+#define CB_TABLE 6
+#define FT_FIELDS 7
+#define SB_FIELDSCROLLER 8
+#define PB_OK 9
+#define PB_CANCEL 10
+#define PB_HELP 11
+
+#define FT_FIELD_BASE 50
+#define LB_FIELD_BASE 50
+
+#define STR_NO_FIELD_SELECTION 1
+#define STR_FIELD_COMPANY 2
+#define STR_FIELD_DEPARTMENT 3
+#define STR_FIELD_FIRSTNAME 4
+#define STR_FIELD_LASTNAME 5
+#define STR_FIELD_STREET 6
+#define STR_FIELD_COUNTRY 7
+#define STR_FIELD_ZIPCODE 8
+#define STR_FIELD_CITY 9
+#define STR_FIELD_TITLE 10
+#define STR_FIELD_POSITION 11
+#define STR_FIELD_ADDRFORM 12
+#define STR_FIELD_INITIALS 13
+#define STR_FIELD_SALUTATION 14
+#define STR_FIELD_HOMETEL 15
+#define STR_FIELD_WORKTEL 16
+#define STR_FIELD_FAX 17
+#define STR_FIELD_EMAIL 18
+#define STR_FIELD_URL 19
+#define STR_FIELD_NOTE 20
+#define STR_FIELD_USER1 21
+#define STR_FIELD_USER2 22
+#define STR_FIELD_USER3 23
+#define STR_FIELD_USER4 24
+#define STR_FIELD_ID 25
+#define STR_FIELD_STATE 26
+#define STR_FIELD_OFFICETEL 27
+#define STR_FIELD_PAGER 28
+#define STR_FIELD_MOBILE 29
+#define STR_FIELD_TELOTHER 30
+#define STR_FIELD_CALENDAR 31
+#define STR_FIELD_INVITE 32
+
+#define STR_LOCAGICAL_FIELD_NAMES 33
+
+
+#endif // _SVT_ADDRESSTEMPLATE_HRC_
+
diff --git a/svtools/source/dialogs/addresstemplate.src b/svtools/source/dialogs/addresstemplate.src
new file mode 100644
index 000000000000..0652dfb9d0f5
--- /dev/null
+++ b/svtools/source/dialogs/addresstemplate.src
@@ -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 _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#ifndef _SVT_ADDRESSTEMPLATE_HRC_
+#include "addresstemplate.hrc"
+#endif
+#ifndef _SVT_CONTROLDIMS_HRC_
+#include "controldims.hrc"
+#endif
+
+#define FIELD_ROW_HEIGHT 17
+
+ModalDialog DLG_ADDRESSBOOKSOURCE
+{
+ SVLook = TRUE ;
+ OutputSize = TRUE ;
+ Size = MAP_APPFONT ( 300 , 88 + FIELD_ROW_HEIGHT * FIELD_PAIRS_VISIBLE ) ;
+ Hide = TRUE ;
+ Moveable = TRUE ;
+ Text [ en-US ] = "Templates: Address Book Assignment";
+
+ FixedLine FL_DATASOURCEFRAME
+ {
+ Text [ en-US ] = "Address Book Source";
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 2 ) ;
+ Size = MAP_APPFONT ( 288 , RSC_CD_FIXEDLINE_HEIGHT ) ;
+ };
+ FixedText FT_DATASOURCE
+ {
+ Text [ en-US ] = "Data source";
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 15 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+
+ Group = TRUE;
+ };
+ ComboBox CB_DATASOURCE
+ {
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 105, 13 ) ;
+ Size = MAP_APPFONT ( 96, 55 ) ;
+
+ DropDown = TRUE;
+ TabStop = TRUE;
+ };
+ PushButton PB_ADMINISTATE_DATASOURCES
+ {
+ Text [ en-US ] = "~Address Data Source...";
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 204, 13 ) ;
+ Size = MAP_APPFONT ( 90, 14 ) ;
+ TabStop = TRUE;
+ };
+ FixedText FT_TABLE
+ {
+ Text [ en-US ] = "Table";
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 32 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+
+ Group = TRUE;
+ };
+ ComboBox CB_TABLE
+ {
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 105, 30 ) ;
+ Size = MAP_APPFONT ( 96, 55 ) ;
+
+ DropDown = TRUE;
+ TabStop = TRUE;
+ };
+ FixedText FT_FIELDS
+ {
+ Text [ en-US ] = "Field assignment";
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6, 30 + RSC_CD_DROPDOWN_HEIGHT + RSC_SP_CTRL_Y ) ;
+ Size = MAP_APPFONT ( 248 , RSC_CD_FIXEDTEXT_HEIGHT ) ;
+ };
+ Window CT_BORDER
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6, 30 + RSC_CD_DROPDOWN_HEIGHT + RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT + RSC_SP_CTRL_DESC_Y ) ;
+ Size = MAP_APPFONT ( 288 , 5 + FIELD_ROW_HEIGHT * FIELD_PAIRS_VISIBLE ) ;
+ };
+
+#define DECLARE_FIELD( row, column ) \
+ FixedText FT_FIELD_BASE + row * 2 + column \
+ { \
+ SVLook = TRUE ; \
+ Pos = MAP_APPFONT ( 3 + column * 134, RSC_SP_CTRL_GROUP_Y + 2 + row * FIELD_ROW_HEIGHT ) ; \
+ Size = MAP_APPFONT ( 79 , 10 ) ; \
+ Group = TRUE; \
+ }; \
+ ListBox LB_FIELD_BASE + row * 2 + column \
+ { \
+ SVLook = TRUE; \
+ Pos = MAP_APPFONT ( 89 + column * 134, RSC_SP_CTRL_GROUP_Y + row * FIELD_ROW_HEIGHT ) ; \
+ Size = MAP_APPFONT ( 42 , 14 ) ; \
+ Border = TRUE; \
+ DropDown = TRUE; \
+ TabStop = TRUE; \
+ }
+
+#if FIELD_PAIRS_VISIBLE > 0
+ DECLARE_FIELD( 0, 0 );
+ DECLARE_FIELD( 0, 1 );
+#endif
+#if FIELD_PAIRS_VISIBLE > 1
+ DECLARE_FIELD( 1, 0 );
+ DECLARE_FIELD( 1, 1 );
+#endif
+#if FIELD_PAIRS_VISIBLE > 2
+ DECLARE_FIELD( 3, 0 );
+ DECLARE_FIELD( 3, 1 );
+#endif
+#if FIELD_PAIRS_VISIBLE > 3
+ DECLARE_FIELD( 2, 0 );
+ DECLARE_FIELD( 2, 1 );
+#endif
+#if FIELD_PAIRS_VISIBLE > 4
+ DECLARE_FIELD( 4, 0 );
+ DECLARE_FIELD( 4, 1 );
+#endif
+#if FIELD_PAIRS_VISIBLE > 5
+ DECLARE_FIELD( 5, 0 );
+ DECLARE_FIELD( 5, 1 );
+#endif
+
+ ScrollBar SB_FIELDSCROLLER
+ {
+ SVLook = TRUE;
+ Pos = MAP_APPFONT ( 275, RSC_SP_CTRL_GROUP_Y ) ;
+ Size = MAP_APPFONT ( 8 , 16 - RSC_SP_CTRL_GROUP_Y + FIELD_ROW_HEIGHT * (FIELD_PAIRS_VISIBLE - 1) ) ;
+ };
+
+ OKButton PB_OK
+ {
+ SVLook = TRUE;
+ DefButton = TRUE;
+ Pos = MAP_APPFONT ( 137, 70 + FIELD_ROW_HEIGHT * FIELD_PAIRS_VISIBLE ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+
+ CancelButton PB_CANCEL
+ {
+ SVLook = TRUE;
+ Pos = MAP_APPFONT ( 190, 70 + FIELD_ROW_HEIGHT * FIELD_PAIRS_VISIBLE ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+
+ HelpButton PB_HELP
+ {
+ SVLook = TRUE;
+ Pos = MAP_APPFONT ( 244, 70 + FIELD_ROW_HEIGHT * FIELD_PAIRS_VISIBLE ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+
+ String STR_LOCAGICAL_FIELD_NAMES
+ {
+ Text = "FirstName;LastName;Company;Department;Street;Zip;City;State;Country;PhonePriv;PhoneComp;PhoneOffice;PhoneCell;PhoneOther;Pager;Fax;EMail;URL;Title;Position;Code;AddrForm;AddrFormMail;Id;CalendarURL;InviteParticipant;Note;Altfield1;Altfield2;Altfield3;Altfield4";
+ // no need to translate this
+ // the items in this string have to be in the same order as the STR_FIELD_* strings are added to the
+ // field label list of the dialog
+ };
+
+ String STR_NO_FIELD_SELECTION
+ {
+ Text [ en-US ] = "<none>";
+ };
+
+ String STR_FIELD_COMPANY
+ {
+ Text [ en-US ] = "Company";
+ };
+ String STR_FIELD_DEPARTMENT
+ {
+ Text [ en-US ] = "Department";
+ };
+ String STR_FIELD_FIRSTNAME
+ {
+ Text [ en-US ] = "First name";
+ };
+ String STR_FIELD_LASTNAME
+ {
+ Text [ en-US ] = "Last name";
+ };
+ String STR_FIELD_STREET
+ {
+ Text [ en-US ] = "Street";
+ };
+ String STR_FIELD_COUNTRY
+ {
+ Text [ en-US ] = "Country";
+ };
+ String STR_FIELD_ZIPCODE
+ {
+ Text [ en-US ] = "ZIP Code";
+ };
+ String STR_FIELD_CITY
+ {
+ Text [ en-US ] = "City";
+ };
+ String STR_FIELD_TITLE
+ {
+ Text [ en-US ] = "Title";
+ };
+ String STR_FIELD_POSITION
+ {
+ Text [ en-US ] = "Position";
+ };
+ String STR_FIELD_ADDRFORM
+ {
+ Text [ en-US ] = "Addr. Form";
+ };
+ String STR_FIELD_INITIALS
+ {
+ Text [ en-US ] = "Initials";
+ };
+ String STR_FIELD_SALUTATION
+ {
+ Text [ en-US ] = "Complimentary close";
+ };
+ String STR_FIELD_HOMETEL
+ {
+ Text [ en-US ] = "Tel: Home";
+ };
+ String STR_FIELD_WORKTEL
+ {
+ Text [ en-US ] = "Tel: Work";
+ };
+ String STR_FIELD_FAX
+ {
+ Text [ en-US ] = "FAX";
+ };
+ String STR_FIELD_EMAIL
+ {
+ Text [ en-US ] = "E-mail";
+ };
+ String STR_FIELD_URL
+ {
+ Text [ en-US ] = "URL";
+ };
+ String STR_FIELD_NOTE
+ {
+ Text [ en-US ] = "Note";
+ };
+ String STR_FIELD_USER1
+ {
+ Text [ en-US ] = "User 1";
+ };
+ String STR_FIELD_USER2
+ {
+ Text [ en-US ] = "User 2";
+ };
+ String STR_FIELD_USER3
+ {
+ Text [ en-US ] = "User 3";
+ };
+ String STR_FIELD_USER4
+ {
+ Text [ en-US ] = "User 4";
+ };
+
+ String STR_FIELD_ID
+ {
+ Text [ en-US ] = "ID";
+ };
+ String STR_FIELD_STATE
+ {
+ Text [ en-US ] = "State";
+ };
+ String STR_FIELD_OFFICETEL
+ {
+ Text [ en-US ] = "Tel: Office";
+ };
+ String STR_FIELD_PAGER
+ {
+ Text [ en-US ] = "Pager";
+ };
+ String STR_FIELD_MOBILE
+ {
+ Text [ en-US ] = "Mobile";
+ };
+ String STR_FIELD_TELOTHER
+ {
+ Text [ en-US ] = "Tel: Other";
+ };
+ String STR_FIELD_CALENDAR
+ {
+ Text [ en-US ] = "Calendar";
+ };
+ String STR_FIELD_INVITE
+ {
+ Text [ en-US ] = "Invite";
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/dialogs/colctrl.cxx b/svtools/source/dialogs/colctrl.cxx
new file mode 100644
index 000000000000..4456fe2f1268
--- /dev/null
+++ b/svtools/source/dialogs/colctrl.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_svtools.hxx"
+
+
+#include <vcl/salbtype.hxx>
+#include <vcl/bmpacc.hxx>
+
+#include <svtools/colctrl.hxx>
+
+// ----------------
+// - ColorControl -
+// ----------------
+
+SvColorControl::SvColorControl( Window* pParent, WinBits nStyle ) :
+ Control ( pParent, nStyle ),
+ mpBitmap ( NULL ),
+ mpReadAccess ( NULL ),
+ mnLuminance ( 50 )
+{
+ Initialize();
+}
+
+// -----------------------------------------------------------------------
+SvColorControl::SvColorControl( Window* pParent, const ResId& rResId ) :
+ Control ( pParent, rResId ),
+ mpBitmap ( NULL ),
+ mpReadAccess ( NULL ),
+ mnLuminance ( 50 )
+{
+ Initialize();
+}
+
+
+// -----------------------------------------------------------------------
+SvColorControl::~SvColorControl()
+{
+ delete mpBitmap;
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Initialize()
+{
+ SetLineColor( Color( COL_BLACK ) );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::CreateBitmap()
+{
+ const Size aSize( GetOutputSizePixel() );
+
+ if( mpBitmap && mpBitmap->GetSizePixel() != aSize )
+ delete mpBitmap, mpBitmap = NULL;
+
+ if( !mpBitmap )
+ mpBitmap = new Bitmap( aSize, 24 );
+
+ BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
+
+ if( pWriteAccess )
+ {
+ USHORT nX = (USHORT) aSize.Width();
+ USHORT nY = (USHORT) aSize.Height();
+
+ UINT16 nHue, nSat;
+ ColorHSB aColHSB( 0, 0, mnLuminance );
+
+ for( USHORT i = 0; i < nY; i++ )
+ {
+ nSat = (UINT16) FRound( 100 - ( 100.0 * i + 0.5 ) / nY );
+
+ for( USHORT j = 0; j < nX; j++ )
+ {
+ nHue = (UINT16) FRound( ( 360.0 * j + 0.5 ) / nX );
+
+ aColHSB.SetHue( nHue );
+ aColHSB.SetSat( nSat );
+
+ // mpBitmap always has a bit count of 24 => use of SetPixel(...) is safe
+ pWriteAccess->SetPixel( i, j, BitmapColor( aColHSB.GetRGB() ) );
+ }
+ }
+
+ mpBitmap->ReleaseAccess( pWriteAccess );
+ }
+
+ SetColor( maColor );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::ShowPosition( const Point& rPos )
+{
+ // Explizites Abfragen des Bereichs, da schon mal ein Wert < 0 vorhanden ist
+ if( mpBitmap )
+ {
+ long nX = rPos.X();
+ long nY = rPos.Y();
+ if( nX < 0L )
+ nX = 0L;
+ else if( nX >= mpBitmap->GetSizePixel().Width() )
+ nX = mpBitmap->GetSizePixel().Width() - 1L;
+
+ if( nY < 0L )
+ nY= 0L;
+ else if( nY >= mpBitmap->GetSizePixel().Height() )
+ nY = mpBitmap->GetSizePixel().Height() - 1L;
+
+ Point aPos = maPosition;
+ maPosition.X() = nX - 2;
+ maPosition.Y() = nY - 2;
+ Invalidate( Rectangle( aPos, Size( 5, 5) ) );
+ Invalidate( Rectangle( maPosition, Size( 5, 5) ) );
+
+ if( ( mpReadAccess = mpBitmap->AcquireReadAccess() ) != NULL )
+ {
+ // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
+ maColor = mpReadAccess->GetPixel( nY, nX );
+ mpBitmap->ReleaseAccess( mpReadAccess );
+ mpReadAccess = NULL;
+ }
+ }
+}
+// -----------------------------------------------------------------------
+void SvColorControl::MouseMove( const MouseEvent& rMEvt )
+{
+ if( rMEvt.IsLeft() )
+ {
+ ShowPosition( rMEvt.GetPosPixel() );
+ Modify();
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if( rMEvt.IsLeft() && !rMEvt.IsShift() )
+ {
+ //ShowPointer( FALSE );
+ CaptureMouse();
+ ShowPosition( rMEvt.GetPosPixel() );
+ Modify();
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::MouseButtonUp( const MouseEvent& )
+{
+ //ShowPointer( TRUE );
+ if( IsMouseCaptured() )
+ ReleaseMouse();
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Paint( const Rectangle& rRect )
+{
+ if( !mpBitmap )
+ CreateBitmap();
+
+ Bitmap aOutputBitmap( *mpBitmap );
+
+ if( GetBitCount() <= 8 )
+ aOutputBitmap.Dither();
+
+ DrawBitmap( rRect.TopLeft(), rRect.GetSize(), rRect.TopLeft(), rRect.GetSize(), aOutputBitmap );
+
+ // Positions-Control (Fadenkreuz oder Aehnliches)
+ Point aPos1( maPosition );
+ Point aPos2( maPosition );
+ aPos2.X() += 4;
+ DrawLine( aPos1, aPos2 );
+ aPos2.X() -= 4;
+ aPos2.Y() += 4;
+ DrawLine( aPos1, aPos2 );
+ aPos1.Y() += 4;
+ aPos2.X() += 4;
+ DrawLine( aPos1, aPos2 );
+ aPos1.X() += 4;
+ aPos2.Y() -= 4;
+ DrawLine( aPos1, aPos2 );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Resize()
+{
+ CreateBitmap();
+ Control::Resize();
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Modify()
+{
+ maModifyHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::SetColor( const ColorHSB& rCol, BOOL bSetColor )
+{
+ if( bSetColor )
+ maColor = rCol.GetRGB();
+
+ if( mpBitmap )
+ {
+ USHORT nX = (USHORT) mpBitmap->GetSizePixel().Width();
+ USHORT nY = (USHORT) mpBitmap->GetSizePixel().Height();
+ INT16 nZ = rCol.GetBri();
+
+ SetLuminance( nZ );
+ nX = rCol.GetHue() * nX / 360; // Farbe
+ nY = nY - rCol.GetSat() * nY / 100; // Saettigung
+ ShowPosition( Point( nX, nY ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::SetColor( const Color& rCol )
+{
+ maColor = rCol;
+
+ if( mpBitmap )
+ {
+ ColorHSB aColHsb( rCol );
+ SetColor( aColHsb, FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::SetLuminance( short nLum )
+{
+ if( nLum != mnLuminance && nLum >= 0 && nLum <= 100 )
+ {
+ mnLuminance = nLum;
+
+ if( mnLuminance < 40 )
+ SetLineColor( Color( COL_WHITE ) );
+ else
+ SetLineColor( Color( COL_BLACK ) );
+
+ CreateBitmap();
+
+ long nX = maPosition.X() + 2;
+ long nY = maPosition.Y() + 2;
+
+ if( mpBitmap && ( ( mpReadAccess = mpBitmap->AcquireReadAccess() ) != NULL ) )
+ {
+ // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
+ maColor = mpReadAccess->GetPixel( nY, nX );
+ mpBitmap->ReleaseAccess( mpReadAccess );
+ mpReadAccess = NULL;
+ }
+
+ Invalidate();
+ }
+}
+
+
+// -----------------------
+// - ColorPreviewControl -
+// -----------------------
+
+
+// -----------------------------------------------------------------------
+ColorPreviewControl::ColorPreviewControl( Window* pParent, WinBits nStyle ) :
+ Control ( pParent, nStyle )
+{
+ SetFillColor( maColor );
+ SetLineColor( maColor );
+}
+
+// -----------------------------------------------------------------------
+ColorPreviewControl::ColorPreviewControl( Window* pParent, const ResId& rResId ) :
+ Control ( pParent, rResId )
+{
+ SetFillColor( maColor );
+ SetLineColor( maColor );
+}
+
+
+// -----------------------------------------------------------------------
+ColorPreviewControl::~ColorPreviewControl()
+{
+}
+
+// -----------------------------------------------------------------------
+void ColorPreviewControl::Paint( const Rectangle& rRect )
+{
+ DrawRect( rRect );
+}
+
+// -----------------------------------------------------------------------
+void ColorPreviewControl::SetColor( const Color& rCol )
+{
+ if( rCol != maColor )
+ {
+ maColor = rCol;
+ SetFillColor( maColor );
+ SetLineColor( maColor );
+ Invalidate();
+ }
+}
+
+
+// -----------------------
+// - ColorMixingControl -
+// -----------------------
+
+
+// -----------------------------------------------------------------------
+ColorMixingControl::ColorMixingControl( Window* pParent, WinBits nStyle,
+ USHORT nRows, USHORT nColumns ) :
+ ValueSet ( pParent, nStyle ),
+ mnRows ( nRows ),
+ mnColumns ( nColumns )
+{
+ Initialize();
+}
+
+// -----------------------------------------------------------------------
+ColorMixingControl::ColorMixingControl( Window* pParent, const ResId& rResId,
+ USHORT nRows, USHORT nColumns ) :
+ ValueSet ( pParent, rResId ),
+ mnRows ( nRows ),
+ mnColumns ( nColumns )
+{
+ Initialize();
+}
+
+
+// -----------------------------------------------------------------------
+ColorMixingControl::~ColorMixingControl()
+{
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::Initialize()
+{
+ SetColCount( mnColumns );
+
+ Color aColor;
+ String aStr;
+ for( USHORT i = 1; i <= mnRows * mnColumns; i++ )
+ {
+ InsertItem( i, aColor, aStr );
+ }
+
+ /*maColor[ 0 ] = Color( COL_LIGHTRED );
+ maColor[ 1 ] = Color( COL_LIGHTGREEN );
+ maColor[ 2 ] = Color( COL_YELLOW );
+ maColor[ 3 ] = Color( COL_LIGHTBLUE );*/
+
+ SetColor( CMC_TOPLEFT, Color( COL_LIGHTRED ) );
+ SetColor( CMC_BOTTOMRIGHT, Color( COL_LIGHTBLUE ) );
+
+ SetColor( CMC_TOPRIGHT, Color( COL_LIGHTGREEN ) );
+ SetColor( CMC_BOTTOMLEFT, Color( COL_YELLOW ) );
+
+ /*FillColumn( 0 );
+ FillColumn( mnColumns - 1 );
+ for( i = 0; i < mnRows; i++ )
+ FillRow( i );*/
+}
+
+// -----------------------------------------------------------------------
+Color ColorMixingControl::CalcDifferenceColor( USHORT nCol1, USHORT nCol2,
+ USHORT nSteps )
+{
+ // Die Berechnung ist noch etwas ungenau, daher sollte besser mit floats
+ // gearbeitet werden... (muss !!!)
+ Color aColor( GetItemColor( nCol1 ) );
+ Color aColor2( GetItemColor( nCol2 ) );
+
+ aColor.SetRed( (UINT8) ( ( aColor2.GetRed() - aColor.GetRed() ) / nSteps ) );
+ aColor.SetGreen( (UINT8) ( ( aColor2.GetGreen() - aColor.GetGreen() ) / nSteps ) );
+ aColor.SetBlue( (UINT8) ( ( aColor2.GetBlue() - aColor.GetBlue() ) / nSteps ) );
+
+ return( aColor );
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::FillRow( USHORT nRow )
+{
+ USHORT nCol1 = nRow * mnColumns + 1;
+ USHORT nCol2 = ( nRow + 1 ) * mnColumns;
+ Color aColor( GetItemColor( nCol1 ) );
+ Color aDiffColor( CalcDifferenceColor( nCol1, nCol2, mnColumns - 1 ) );
+
+ for( USHORT i = nCol1 + 1; i < nCol2; i++ )
+ {
+ aColor.SetRed( aColor.GetRed() + aDiffColor.GetRed() );
+ aColor.SetGreen( aColor.GetGreen() + aDiffColor.GetGreen() );
+ aColor.SetBlue( aColor.GetBlue() + aDiffColor.GetBlue() );
+
+ SetItemColor( i, aColor );
+ SetItemText( i, GetRGBString( aColor ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::FillColumn( USHORT nColumn )
+{
+ USHORT nCol1 = nColumn + 1;
+ USHORT nCol2 = nColumn + ( mnRows - 1 ) * mnColumns + 1;
+ Color aColor( GetItemColor( nCol1 ) );
+ Color aDiffColor( CalcDifferenceColor( nCol1, nCol2, mnRows - 1 ) );
+
+ for( USHORT i = nCol1 + mnColumns; i < nCol2; i = i + mnColumns )
+ {
+ aColor.SetRed( aColor.GetRed() + aDiffColor.GetRed() );
+ aColor.SetGreen( aColor.GetGreen() + aDiffColor.GetGreen() );
+ aColor.SetBlue( aColor.GetBlue() + aDiffColor.GetBlue() );
+
+ SetItemColor( i, aColor );
+ SetItemText( i, GetRGBString( aColor ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::SetRows( USHORT nRows )
+{
+ mnRows = nRows;
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::SetColumns( USHORT nColumns )
+{
+ mnColumns = nColumns;
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::SetColor( CMCPosition ePos, const Color& rCol )
+{
+ if( rCol != maColor[ ePos ] )
+ {
+ maColor[ ePos ] = rCol;
+ USHORT nPos = 0;
+ USHORT nColumn = 0;
+ String aStr( GetRGBString( rCol ) );
+
+ switch( ePos )
+ {
+ case CMC_TOPLEFT:
+ nPos = 1;
+ nColumn = 0;
+ break;
+
+ case CMC_TOPRIGHT:
+ nPos = mnColumns;
+ nColumn = mnColumns - 1;
+ break;
+
+ case CMC_BOTTOMLEFT:
+ nPos = ( mnRows - 1 ) * mnColumns + 1;
+ nColumn = 0;
+ break;
+
+ case CMC_BOTTOMRIGHT:
+ nPos = mnRows * mnColumns;
+ nColumn = mnColumns - 1;
+ break;
+ case CMC_OTHER:
+ break; // -Wall not handled.
+ }
+ SetItemColor( nPos, rCol );
+ SetItemText( nPos, aStr );
+ FillColumn( nColumn );
+
+ for( USHORT i = 0; i < mnRows; i++ )
+ FillRow( i );
+ }
+}
+
+// -----------------------------------------------------------------------
+String ColorMixingControl::GetRGBString( const Color& rColor )
+{
+ String aStr( String::CreateFromInt32(rColor.GetRed()) );
+ aStr += ' ';
+ aStr += String::CreateFromInt32(rColor.GetGreen());
+ aStr += ' ';
+ aStr += String::CreateFromInt32(rColor.GetBlue());
+
+ return aStr;
+}
+// -----------------------------------------------------------------------
+CMCPosition ColorMixingControl::GetCMCPosition() const
+{
+ CMCPosition ePos = CMC_OTHER;
+ USHORT nPos = GetSelectItemId();
+
+ if( nPos == 1 )
+ ePos = CMC_TOPLEFT;
+ else if( nPos == mnColumns )
+ ePos = CMC_TOPRIGHT;
+ else if( nPos == ( mnRows - 1 ) * mnColumns + 1 )
+ ePos = CMC_BOTTOMLEFT;
+ else if( nPos == mnRows * mnColumns )
+ ePos = CMC_BOTTOMRIGHT;
+
+ return( ePos );
+}
+
+
+// ------------
+// - ColorHSB -
+// ------------
+
+// Erste Ansaetze gingen auf die Berechnung von Sven Hannover zurueck
+// Der jetzige Algorithmus stammt im weitesten Sinne aus dem Foley/VanDam
+
+
+/**************************************************************************
+|*
+|* ColorHSB::ColorHSB()
+|*
+|* Beschreibung RGB nach HSB
+|* Ersterstellung SOH 02.10.97
+|*
+**************************************************************************/
+
+ColorHSB::ColorHSB( const Color& rColor )
+{
+ UINT8 c[3];
+ UINT8 cMax, cMin;
+
+ c[0] = rColor.GetRed();
+ c[1] = rColor.GetGreen();
+ c[2] = rColor.GetBlue();
+
+ cMax = c[0];
+ if( c[1] > cMax )
+ cMax = c[1];
+ if( c[2] > cMax )
+ cMax = c[2];
+
+ // Brightness = max(R, G, B);
+ mnBri = cMax * 100 / 255;
+
+ cMin = c[0];
+ if( c[1] < cMin )
+ cMin = c[1];
+ if( c[2] < cMin )
+ cMin = c[2];
+
+ UINT8 cDelta = cMax - cMin;
+
+ // Saturation = max - min / max
+ if( mnBri > 0 )
+ mnSat = cDelta * 100 / cMax;
+ else
+ mnSat = 0;
+
+ if( mnSat == 0 )
+ mnHue = 0; // Default = undefined
+ else
+ {
+ double dHue = 0;
+
+ if( c[0] == cMax )
+ {
+ dHue = (double)( c[1] - c[2] ) / (double)cDelta;
+ }
+ else if( c[1] == cMax )
+ {
+ dHue = 2.0 + (double)( c[2] - c[0] ) / (double)cDelta;
+ }
+ else if ( c[2] == cMax )
+ {
+ dHue = 4.0 + (double)( c[0] - c[1] ) / (double)cDelta;
+ }
+ // else dHue = ??? -Wall FIXME
+ dHue *= 60.0;
+
+ if( dHue < 0.0 )
+ dHue += 360.0;
+
+ mnHue = (UINT16) dHue;
+ }
+}
+
+/**************************************************************************
+|*
+|* ColorHSB::GetRGB()
+|*
+|* Beschreibung HSB nach RGB
+|* Ersterstellung SOH 02.10.97
+|*
+**************************************************************************/
+
+Color ColorHSB::GetRGB() const
+{
+ UINT8 cR,cG,cB;
+ UINT8 nB = (UINT8) ( mnBri * 255 / 100 );
+
+ if( mnSat == 0 )
+ {
+ cR = nB;
+ cG = nB;
+ cB = nB;
+ }
+ else
+ {
+ double dH = mnHue;
+ double f;
+ UINT16 n;
+ if( dH == 360.0 )
+ dH = 0.0;
+
+ dH /= 60.0;
+ n = (UINT16) dH;
+ f = dH - n;
+
+ // #107375# Doing the calculation completely in floating
+ // point, the former optimization gave sometimes negative
+ // results for c and was pointless anyway
+ UINT8 a = static_cast<UINT8>( nB * ( 100.0 - mnSat ) / 100.0 );
+ UINT8 b = static_cast<UINT8>( nB * ( 100.0 - mnSat * f ) / 100.0 );
+ UINT8 c = static_cast<UINT8>( nB * ( 100.0 - mnSat * ( 1.0 - f ) ) / 100.0 );
+
+ switch( n )
+ {
+ case 0: cR = nB; cG = c; cB = a; break;
+ case 1: cR = b; cG = nB; cB = a; break;
+ case 2: cR = a; cG = nB; cB = c; break;
+ case 3: cR = a; cG = b; cB = nB; break;
+ case 4: cR = c; cG = a; cB = nB; break;
+ case 5: cR = nB; cG = a; cB = b; break;
+ default: cR = 0; cG = 0; cB = 0; break; // -Wall ????
+ }
+ }
+
+ return( Color( cR, cG, cB ) );
+}
+
+// ------------
+// - ColorCMYK -
+// ------------
+
+
+// -----------------------------------------------------------------------
+ColorCMYK::ColorCMYK( const Color& rColor )
+{
+ mnCyan = 255 - rColor.GetRed();
+ mnMagenta = 255 - rColor.GetGreen();
+ mnYellow = 255 - rColor.GetBlue();
+
+ mnKey = Min( Min( mnCyan, mnMagenta ), mnYellow );
+
+ mnCyan = mnCyan - mnKey;
+ mnMagenta = mnMagenta - mnKey;
+ mnYellow = mnYellow - mnKey;
+}
+
+// -----------------------------------------------------------------------
+Color ColorCMYK::GetRGB() const
+{
+ int nTmp = Max( 0, 255 - ( mnCyan + mnKey ) );
+ UINT8 cR = (UINT8) nTmp;
+ nTmp = Max( 0, 255 - ( mnMagenta + mnKey ) );
+ UINT8 cG = (UINT8) nTmp;
+ nTmp = Max( 0, 255 - ( mnYellow + mnKey ) );
+ UINT8 cB = (UINT8) nTmp;
+
+ return( Color( cR, cG, cB ) );
+}
+
+
diff --git a/svtools/source/dialogs/colrdlg.cxx b/svtools/source/dialogs/colrdlg.cxx
new file mode 100644
index 000000000000..a52cc4b0834c
--- /dev/null
+++ b/svtools/source/dialogs/colrdlg.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#ifndef GCC
+#endif
+
+#include <svtools/svtdata.hxx>
+#include "colrdlg.hrc"
+#include <svtools/colrdlg.hxx>
+
+// ---------------
+// - ColorDialog -
+// ---------------
+
+SvColorDialog::SvColorDialog( Window* pWindow ) :
+ ModalDialog ( pWindow, SvtResId( DLG_COLOR ) ),
+ maColMixCtrl ( this, SvtResId( VAL_SET_COLOR ), 8, 8 ),
+ maBtn1 ( this, SvtResId( BTN_1 ) ),
+ maBtn2 ( this, SvtResId( BTN_2 ) ),
+ //maBtn3 ( this, SvtResId( BTN_3 ) ),
+ //maBtn4 ( this, SvtResId( BTN_4 ) ),
+ //maFtRGB ( this, SvtResId( FT_RGB ) ),
+ maCtlColor ( this, SvtResId( CTL_COLOR ) ),
+
+ maFtCyan ( this, SvtResId( FT_CYAN ) ),
+ maNumCyan ( this, SvtResId( NUM_CYAN ) ),
+ maFtMagenta ( this, SvtResId( FT_MAGENTA ) ),
+ maNumMagenta ( this, SvtResId( NUM_MAGENTA ) ),
+ maFtYellow ( this, SvtResId( FT_YELLOW ) ),
+ maNumYellow ( this, SvtResId( NUM_YELLOW ) ),
+ maFtKey ( this, SvtResId( FT_KEY ) ),
+ maNumKey ( this, SvtResId( NUM_KEY ) ),
+
+ maFtRed ( this, SvtResId( FT_RED ) ),
+ maNumRed ( this, SvtResId( NUM_RED ) ),
+ maFtGreen ( this, SvtResId( FT_GREEN ) ),
+ maNumGreen ( this, SvtResId( NUM_GREEN ) ),
+ maFtBlue ( this, SvtResId( FT_BLUE ) ),
+ maNumBlue ( this, SvtResId( NUM_BLUE ) ),
+
+ maFtHue ( this, SvtResId( FT_HUE ) ),
+ maNumHue ( this, SvtResId( NUM_HUE ) ),
+ maFtSaturation ( this, SvtResId( FT_SATURATION ) ),
+ maNumSaturation ( this, SvtResId( NUM_SATURATION ) ),
+ maFtLuminance ( this, SvtResId( FT_LUMINANCE ) ),
+ maNumLuminance ( this, SvtResId( NUM_LUMINANCE ) ),
+
+ maCtlPreview ( this, SvtResId( CTL_PREVIEW ) ),
+ maCtlPreviewOld ( this, SvtResId( CTL_PREVIEW_OLD ) ),
+
+ maBtnOK ( this, SvtResId( BTN_OK ) ),
+ maBtnCancel ( this, SvtResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, SvtResId( BTN_HELP ) )
+{
+ FreeResource();
+
+ maColMixCtrl.SetDoubleClickHdl( LINK( this, SvColorDialog, ClickMixCtrlHdl ) );
+ maColMixCtrl.SetSelectHdl( LINK( this, SvColorDialog, SelectMixCtrlHdl ) );
+
+ Link aLink( LINK( this, SvColorDialog, ColorModifyHdl ) );
+ maCtlColor.SetModifyHdl( aLink );
+
+ maNumRed.SetModifyHdl( aLink );
+ maNumGreen.SetModifyHdl( aLink );
+ maNumBlue.SetModifyHdl( aLink );
+
+ maNumCyan.SetModifyHdl( aLink );
+ maNumMagenta.SetModifyHdl( aLink );
+ maNumYellow.SetModifyHdl( aLink );
+ maNumKey.SetModifyHdl( aLink );
+
+ maNumHue.SetModifyHdl( aLink );
+ maNumSaturation.SetModifyHdl( aLink );
+ maNumLuminance.SetModifyHdl( aLink );
+
+ aLink = ( LINK( this, SvColorDialog, ClickBtnHdl ) );
+ maBtn1.SetClickHdl( aLink );
+ maBtn2.SetClickHdl( aLink );
+ //maBtn3.SetClickHdl( aLink );
+ //maBtn4.SetClickHdl( aLink );
+
+ maColMixCtrl.SetExtraSpacing( 0 );
+}
+
+
+// -----------------------------------------------------------------------
+SvColorDialog::~SvColorDialog()
+{
+}
+
+// -----------------------------------------------------------------------
+void SvColorDialog::Initialize()
+{
+ maNumRed.SetValue( maColor.GetRed() );
+ maNumGreen.SetValue( maColor.GetGreen() );
+ maNumBlue.SetValue( maColor.GetBlue() );
+
+ ColorCMYK aColorCMYK( maColor );
+
+ long aCyan = (long) ( (double)aColorCMYK.GetCyan() * 100.0 / 255.0 + 0.5 );
+ long aMagenta = (long) ( (double)aColorCMYK.GetMagenta() * 100.0 / 255.0 + 0.5 );
+ long aYellow = (long) ( (double)aColorCMYK.GetYellow() * 100.0 / 255.0 + 0.5 );
+ long aKey = (long) ( (double)aColorCMYK.GetKey() * 100.0 / 255.0 + 0.5 );
+ maNumCyan.SetValue( aCyan );
+ maNumMagenta.SetValue( aMagenta );
+ maNumYellow.SetValue( aYellow );
+ maNumKey.SetValue( aKey );
+
+ ColorHSB aColorHSB( maColor );
+ maNumHue.SetValue( aColorHSB.GetHue() );
+ maNumSaturation.SetValue( aColorHSB.GetSat() );
+ maNumLuminance.SetValue( aColorHSB.GetBri() );
+
+ maCtlColor.SetColor( aColorHSB );
+
+ maColMixCtrl.SelectItem( 1 );
+
+ maCtlPreview.SetColor( maColor );
+ maCtlPreviewOld.SetColor( maColor );
+}
+
+// -----------------------------------------------------------------------
+void SvColorDialog::SetColor( const Color& rColor )
+{
+ maColor = rColor;
+}
+
+// -----------------------------------------------------------------------
+const Color& SvColorDialog::GetColor() const
+{
+ return( maColor );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvColorDialog, ColorModifyHdl, void *, p )
+{
+ UINT16 n = 0x00; // 1 == RGB, 2 == CMYK, 4 == HSB
+
+ if( p == &maCtlColor )
+ {
+ maColor = maCtlColor.GetColor();
+ maNumRed.SetValue( maColor.GetRed() );
+ maNumGreen.SetValue( maColor.GetGreen() );
+ maNumBlue.SetValue( maColor.GetBlue() );
+
+ n = 7;
+ }
+ else if( p == &maNumRed )
+ {
+ maColor.SetRed( (UINT8)maNumRed.GetValue() );
+ maCtlColor.SetColor( maColor );
+ n = 6;
+ }
+ else if( p == &maNumGreen )
+ {
+ maColor.SetGreen( (UINT8)maNumGreen.GetValue() );
+ maCtlColor.SetColor( maColor );
+ n = 6;
+ }
+ else if( p == &maNumBlue )
+ {
+ maColor.SetBlue( (UINT8)maNumBlue.GetValue() );
+ maCtlColor.SetColor( maColor );
+ n = 6;
+ }
+ else if( p == &maNumHue ||
+ p == &maNumSaturation ||
+ p == &maNumLuminance )
+ {
+
+ ColorHSB aColorHSB( (UINT16) maNumHue.GetValue(),
+ (UINT16) maNumSaturation.GetValue(),
+ (UINT16) maNumLuminance.GetValue() );
+ maCtlColor.SetColor( aColorHSB );
+ maColor = maCtlColor.GetColor();
+ n = 3;
+ }
+ else if( p == &maNumCyan ||
+ p == &maNumMagenta ||
+ p == &maNumYellow ||
+ p == &maNumKey )
+ {
+ long aCyan = (long) ( (double)maNumCyan.GetValue() * 255.0 / 100.0 + 0.5 );
+ long aMagenta = (long) ( (double)maNumMagenta.GetValue() * 255.0 / 100.0 + 0.5 );
+ long aYellow = (long) ( (double)maNumYellow.GetValue() * 255.0 / 100.0 + 0.5 );
+ long aKey = (long) ( (double)maNumKey.GetValue() * 255.0 / 100.0 + 0.5 );
+
+ ColorCMYK aColorCMYK( (UINT16) aCyan,
+ (UINT16) aMagenta,
+ (UINT16) aYellow,
+ (UINT16) aKey );
+ maColor = aColorCMYK.GetRGB();
+ maCtlColor.SetColor( maColor );
+ n = 5;
+ }
+
+ if( n & 1 ) // RGB setzen
+ {
+ maNumRed.SetValue( maColor.GetRed() );
+ maNumGreen.SetValue( maColor.GetGreen() );
+ maNumBlue.SetValue( maColor.GetBlue() );
+ }
+ if( n & 2 ) // CMYK setzen
+ {
+ ColorCMYK aColorCMYK( maColor );
+ long aCyan = (long) ( (double)aColorCMYK.GetCyan() * 100.0 / 255.0 + 0.5 );
+ long aMagenta = (long) ( (double)aColorCMYK.GetMagenta() * 100.0 / 255.0 + 0.5 );
+ long aYellow = (long) ( (double)aColorCMYK.GetYellow() * 100.0 / 255.0 + 0.5 );
+ long aKey = (long) ( (double)aColorCMYK.GetKey() * 100.0 / 255.0 + 0.5 );
+ maNumCyan.SetValue( aCyan );
+ maNumMagenta.SetValue( aMagenta );
+ maNumYellow.SetValue( aYellow );
+ maNumKey.SetValue( aKey );
+ }
+ if( n & 4 ) // HSB setzen
+ {
+ ColorHSB aColorHSB( maColor );
+ maNumHue.SetValue( aColorHSB.GetHue() );
+ maNumSaturation.SetValue( aColorHSB.GetSat() );
+ maNumLuminance.SetValue( aColorHSB.GetBri() );
+ }
+
+ maCtlPreview.SetColor( maColor );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvColorDialog, ClickBtnHdl, void *, p )
+{
+ /*
+ Color aColor = maCtlColor.GetColor();
+ if( p == &maBtn1 )
+ maColMixCtrl.SetColor( CMC_TOPLEFT, aColor );
+ if( p == &maBtn2 )
+ maColMixCtrl.SetColor( CMC_TOPRIGHT, aColor );
+ if( p == &maBtn3 )
+ maColMixCtrl.SetColor( CMC_BOTTOMLEFT, aColor );
+ if( p == &maBtn4 )
+ maColMixCtrl.SetColor( CMC_BOTTOMRIGHT, aColor );
+ */
+
+ if( p == &maBtn1 )
+ {
+ CMCPosition ePos = maColMixCtrl.GetCMCPosition();
+ if( ePos != CMC_OTHER )
+ maColMixCtrl.SetColor( ePos, maColor );
+ }
+ else if( p == &maBtn2 )
+ {
+ USHORT nPos = maColMixCtrl.GetSelectItemId();
+ maColor = maColMixCtrl.GetItemColor( nPos );
+ maCtlColor.SetColor( maColor );
+ ColorModifyHdl( &maCtlColor );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvColorDialog, ClickMixCtrlHdl, void *, EMPTYARG )
+{
+ USHORT nPos = maColMixCtrl.GetSelectItemId();
+ CMCPosition ePos = maColMixCtrl.GetCMCPosition();
+
+ if( ePos != CMC_OTHER )
+ maColMixCtrl.SetColor( ePos, maColor );
+ else
+ {
+ maColor = maColMixCtrl.GetItemColor( nPos );
+ maCtlColor.SetColor( maColor );
+ ColorModifyHdl( &maCtlColor );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( SvColorDialog, SelectMixCtrlHdl, void *, EMPTYARG )
+{
+ //USHORT nPos = maColMixCtrl.GetSelectItemId();
+ //maFtRGB.SetText( maColMixCtrl.GetItemText( nPos ) );
+
+ CMCPosition ePos = maColMixCtrl.GetCMCPosition();
+ if( ePos == CMC_OTHER )
+ maBtn1.Enable( FALSE );
+ else
+ maBtn1.Enable();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+short SvColorDialog::Execute()
+{
+ Initialize();
+
+ short nRet = ModalDialog::Execute();
+
+ return( nRet );
+}
+
diff --git a/svtools/source/dialogs/colrdlg.hrc b/svtools/source/dialogs/colrdlg.hrc
new file mode 100644
index 000000000000..41329df6e366
--- /dev/null
+++ b/svtools/source/dialogs/colrdlg.hrc
@@ -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.
+ *
+ ************************************************************************/
+#define DLG_COLOR 996
+
+#define VAL_SET_COLOR 2
+#define BTN_1 1
+#define BTN_2 2
+#define BTN_3 3
+#define BTN_4 4
+#define FT_RGB 12
+
+#define CTL_COLOR 1
+
+#define FT_RED 1
+#define NUM_RED 1
+#define FT_GREEN 2
+#define NUM_GREEN 2
+#define FT_BLUE 3
+#define NUM_BLUE 3
+
+#define FT_CYAN 7
+#define NUM_CYAN 7
+#define FT_MAGENTA 8
+#define NUM_MAGENTA 8
+#define FT_YELLOW 9
+#define NUM_YELLOW 9
+#define FT_KEY 10
+#define NUM_KEY 10
+
+#define FT_HUE 4
+#define NUM_HUE 4
+#define FT_SATURATION 5
+#define NUM_SATURATION 5
+#define FT_LUMINANCE 6
+#define NUM_LUMINANCE 6
+
+#define CTL_PREVIEW 3
+#define CTL_PREVIEW_OLD 4
+
+#define BTN_OK 1
+#define BTN_CANCEL 1
+#define BTN_HELP 1
+
diff --git a/svtools/source/dialogs/colrdlg.src b/svtools/source/dialogs/colrdlg.src
new file mode 100644
index 000000000000..ad9a5c1aa015
--- /dev/null
+++ b/svtools/source/dialogs/colrdlg.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 "colrdlg.hrc"
+#define DIFF 3
+ModalDialog DLG_COLOR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 165 + DIFF ) ;
+ Moveable = TRUE ;
+ Text [ en-US ] = "Color" ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 205 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 205 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 205 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Control VAL_SET_COLOR
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 91 , 100 ) ;
+ TabStop = TRUE ;
+ };
+ Control CTL_COLOR
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 100 , 6 ) ;
+ Size = MAP_APPFONT ( 100 , 100 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_CYAN
+ {
+ Pos = MAP_APPFONT ( 6 , 110 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "~Cyan" ;
+ };
+ FixedText FT_MAGENTA
+ {
+ Pos = MAP_APPFONT ( 6 , 123 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "~Magenta" ;
+ };
+ FixedText FT_YELLOW
+ {
+ Pos = MAP_APPFONT ( 6 , 136 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "~Yellow" ;
+ };
+ FixedText FT_KEY
+ {
+ Pos = MAP_APPFONT ( 6 , 149 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "~Key" ;
+ };
+ MetricField NUM_CYAN
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 42 , 109 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 100 ;
+ Last = 100 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = " %" ;
+ };
+ MetricField NUM_MAGENTA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 42 , 122 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 100 ;
+ Last = 100 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = " %" ;
+ };
+ MetricField NUM_YELLOW
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 42 , 135 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 100 ;
+ Last = 100 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = " %" ;
+ };
+ MetricField NUM_KEY
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 42 , 148 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 100 ;
+ Last = 100 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = " %" ;
+ };
+ FixedText FT_RED
+ {
+ Pos = MAP_APPFONT ( 72 , 123 + DIFF ) ;
+ Size = MAP_APPFONT ( 33 , 10 ) ;
+ Text [ en-US ] = "~Red" ;
+ };
+ FixedText FT_GREEN
+ {
+ Pos = MAP_APPFONT ( 72 , 136 + DIFF ) ;
+ Size = MAP_APPFONT ( 33 , 10 ) ;
+ Text [ en-US ] = "~Green" ;
+ };
+ FixedText FT_BLUE
+ {
+ Pos = MAP_APPFONT ( 72 , 149 + DIFF ) ;
+ Size = MAP_APPFONT ( 33 , 10 ) ;
+ Text [ en-US ] = "~Blue" ;
+ };
+ NumericField NUM_RED
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 122 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 255 ;
+ Last = 255 ;
+ };
+ NumericField NUM_GREEN
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 135 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 255 ;
+ Last = 255 ;
+ };
+ NumericField NUM_BLUE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 148 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 255 ;
+ Last = 255 ;
+ };
+ FixedText FT_HUE
+ {
+ Pos = MAP_APPFONT ( 135 , 123 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "H~ue" ;
+ };
+ NumericField NUM_HUE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 171 , 122 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 359 ;
+ Last = 359 ;
+ };
+ FixedText FT_SATURATION
+ {
+ Pos = MAP_APPFONT ( 135 , 136 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "~Saturation" ;
+ };
+ NumericField NUM_SATURATION
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 171 , 135 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 100 ;
+ Last = 100 ;
+ };
+ FixedText FT_LUMINANCE
+ {
+ Pos = MAP_APPFONT ( 135 , 149 + DIFF ) ;
+ Size = MAP_APPFONT ( 34 , 10 ) ;
+ Text [ en-US ] = "Bright~ness" ;
+ };
+ NumericField NUM_LUMINANCE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 171 , 148 + DIFF ) ;
+ Size = MAP_APPFONT ( 26 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Maximum = 100 ;
+ Last = 100 ;
+ };
+ PushButton BTN_1
+ {
+ Pos = MAP_APPFONT ( 80 , 109 ) ;
+ Size = MAP_APPFONT ( 17 , 12 ) ;
+ Text = "~<--" ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_2
+ {
+ Pos = MAP_APPFONT ( 100 , 109 ) ;
+ Size = MAP_APPFONT ( 17 , 12 ) ;
+ Text = "--~>" ;
+ TabStop = TRUE ;
+ };
+ Control CTL_PREVIEW_OLD
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 200 , 109 ) ;
+ Size = MAP_APPFONT ( 26 , 51 + DIFF ) ;
+ TabStop = TRUE ;
+ };
+ Control CTL_PREVIEW
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 229 , 109 ) ;
+ Size = MAP_APPFONT ( 26 , 51 + DIFF ) ;
+ TabStop = TRUE ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/dialogs/filedlg.cxx b/svtools/source/dialogs/filedlg.cxx
new file mode 100644
index 000000000000..5567651c0480
--- /dev/null
+++ b/svtools/source/dialogs/filedlg.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_svtools.hxx"
+
+#include <filedlg.hxx>
+#include <filedlg2.hxx>
+
+PathDialog::PathDialog( Window* _pParent, WinBits nStyle, BOOL bCreateDir ) :
+ ModalDialog( _pParent, WB_STDMODAL | nStyle )
+{
+ pImpFileDlg = new ImpSvFileDlg;
+ pImpFileDlg->CreateDialog( this, nStyle, WINDOW_PATHDIALOG, bCreateDir );
+}
+
+PathDialog::~PathDialog()
+{
+ delete pImpFileDlg;
+}
+
+short PathDialog::Execute()
+{
+ pImpFileDlg->GetDialog()->PreExecute();
+ short n = ModalDialog::Execute();
+ return n;
+}
+
+UniString PathDialog::GetPath() const
+{
+ return pImpFileDlg->GetDialog()->GetPath();
+}
+
+void PathDialog::SetPath( const UniString& rPath )
+{
+ pImpFileDlg->GetDialog()->SetPath( rPath );
+}
+
+void PathDialog::SetPath( const Edit& rEdit )
+{
+ pImpFileDlg->GetDialog()->SetPath( rEdit );
+}
+
+long PathDialog::OK()
+{
+ if( aOKHdlLink.IsSet() )
+ return aOKHdlLink.Call( this );
+ else
+ return TRUE;
+}
+
+
+FileDialog::FileDialog( Window* _pParent, WinBits nStyle ) :
+ PathDialog( _pParent, WB_STDMODAL | nStyle )
+{
+ // Dadurch dass hier bei VCL nicht der CTOR mit ResType verwendet wird,
+ // wurde im PathDialog-CTOR leider ein ImpPathDialog angelegt...
+ // So zwar scheisse, aber der Dialog ist eh' nur ein Hack:
+ pImpFileDlg->CreateDialog( this, nStyle, WINDOW_FILEDIALOG, FALSE );
+}
+
+FileDialog::~FileDialog()
+{
+}
+
+void FileDialog::AddFilter( const UniString& rFilter, const UniString& rMask )
+{
+ ((ImpFileDialog*)pImpFileDlg->GetDialog())->AddFilter( rFilter, rMask );
+}
+
+void FileDialog::RemoveFilter( const UniString& rFilter )
+{
+ ((ImpFileDialog*)pImpFileDlg->GetDialog())->RemoveFilter( rFilter );
+}
+
+void FileDialog::RemoveAllFilter()
+{
+ ((ImpFileDialog*)pImpFileDlg->GetDialog())->RemoveAllFilter();
+}
+
+void FileDialog::SetCurFilter( const UniString& rFilter )
+{
+ ((ImpFileDialog*)pImpFileDlg->GetDialog())->SetCurFilter( rFilter );
+}
+
+UniString FileDialog::GetCurFilter() const
+{
+ return ((ImpFileDialog*)pImpFileDlg->GetDialog())->GetCurFilter();
+}
+
+void FileDialog::FileSelect()
+{
+ aFileHdlLink.Call( this );
+}
+
+void FileDialog::FilterSelect()
+{
+ aFilterHdlLink.Call( this );
+}
+
+USHORT FileDialog::GetFilterCount() const
+{
+ return ((ImpFileDialog*)pImpFileDlg->GetDialog())->GetFilterCount();
+}
+
+UniString FileDialog::GetFilterName( USHORT nPos ) const
+{
+ return ((ImpFileDialog*)pImpFileDlg->GetDialog())->GetFilterName( nPos );
+}
+
+UniString FileDialog::GetFilterType( USHORT nPos ) const
+{
+ return ((ImpFileDialog*)pImpFileDlg->GetDialog())->GetFilterType( nPos );
+}
+
+void FileDialog::SetOkButtonText( const UniString& rText )
+{
+ pImpFileDlg->SetOkButtonText( rText );
+}
+
+void FileDialog::SetCancelButtonText( const UniString& rText )
+{
+ pImpFileDlg->SetCancelButtonText( rText );
+}
diff --git a/svtools/source/dialogs/filedlg2.cxx b/svtools/source/dialogs/filedlg2.cxx
new file mode 100644
index 000000000000..b0e77d658931
--- /dev/null
+++ b/svtools/source/dialogs/filedlg2.cxx
@@ -0,0 +1,1362 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <vcl/svapp.hxx>
+#ifndef _SV_BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/svtdata.hxx>
+
+#include <filedlg2.hxx>
+#include <filedlg.hxx>
+#include <filedlg2.hrc>
+#include <vcl/msgbox.hxx>
+#include <vos/security.hxx>
+#include <com/sun/star/i18n/XCollator.hpp>
+
+#include <svtools/stdctrl.hxx>
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+#include <svtools/helpid.hrc>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+
+DECLARE_LIST( UniStringList, UniString* )
+
+#define STD_BTN_WIDTH 80
+#define STD_BTN_HEIGHT 26
+
+#ifndef UNX
+ #define ALLFILES "*.*"
+#else
+ #define ALLFILES "*"
+#endif
+// #define STD_BTN_WIDTH 90
+// #define STD_BTN_HEIGHT 35
+
+#define INITCONTROL( p, ControlClass, nBits, aPos, aSize, aTitel, nHelpId ) \
+ p = new ControlClass( GetPathDialog(), WinBits( nBits ) ); \
+ p->SetHelpId( nHelpId ); \
+ p->SetPosSizePixel( aPos, aSize ); \
+ p->SetText( aTitel ); \
+ p->Show();
+
+
+inline BOOL IsPrintable( sal_Unicode c )
+{
+ return c >= 32 && c != 127 ? TRUE : FALSE;
+}
+
+long
+KbdListBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
+ sal_Unicode cCharCode = aKeyEvt.GetCharCode();
+
+ if ( IsPrintable ( cCharCode ) )
+ {
+ USHORT nCurrentPos = GetSelectEntryPos();
+ USHORT nEntries = GetEntryCount();
+
+ for ( USHORT i = 1; i < nEntries; i++ )
+ {
+ UniString aEntry = GetEntry ( (i + nCurrentPos) % nEntries );
+ aEntry.EraseLeadingChars( ' ' );
+ aEntry.ToUpperAscii();
+ UniString aCompare( cCharCode );
+ aCompare.ToUpperAscii();
+
+ if ( aEntry.CompareTo( aCompare, 1 ) == COMPARE_EQUAL )
+ {
+ SelectEntryPos ( (i + nCurrentPos) % nEntries );
+ break;
+ }
+ }
+ }
+ else
+ if ( aKeyEvt.GetKeyCode().GetCode() == KEY_RETURN )
+ {
+ DoubleClick();
+ }
+ }
+
+ return ListBox::PreNotify ( rNEvt );
+}
+
+ImpPathDialog::ImpPathDialog( PathDialog* pDlg, RESOURCE_TYPE nType, BOOL bCreateDir )
+{
+ pSvPathDialog = pDlg;
+ nDirCount = 0;
+
+ // initialize Controls if not used as a base class
+ if ( nType == WINDOW_PATHDIALOG )
+ {
+ InitControls();
+ if( pNewDirBtn )
+ pNewDirBtn->Enable( bCreateDir );
+ }
+
+ pDlg->SetHelpId( HID_FILEDLG_PATHDLG );
+
+ lang::Locale aLocale = Application::GetSettings().GetLocale();
+ xCollator = ::vcl::unohelper::CreateCollator();
+ if( xCollator.is() )
+ xCollator->loadDefaultCollator( aLocale, 1 );
+ DBG_ASSERT( xCollator.is(), "not collator service for path dialog" );
+}
+
+ImpPathDialog::~ImpPathDialog()
+{
+ delete pEdit;
+ delete pDirTitel;
+ delete pDirList;
+ delete pDirPath;
+ delete pDriveList;
+ delete pDriveTitle;
+ delete pLoadBtn;
+ delete pOkBtn;
+ delete pCancelBtn;
+ delete pNewDirBtn;
+# if defined(UNX) || defined(OS2)
+ delete pHomeBtn;
+# endif
+}
+
+void ImpPathDialog::InitControls()
+{
+ PathDialog* pDlg = GetPathDialog();
+ pDlg->SetText( UniString( SvtResId( STR_FILEDLG_SELECT ) ) );
+
+ Size a3Siz = pDlg->LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
+ Size a6Siz = pDlg->LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
+ Size aBtnSiz = pDlg->LogicToPixel( Size( 50, 14 ), MAP_APPFONT );
+ Size aFTSiz = pDlg->LogicToPixel( Size( 142, 10 ), MAP_APPFONT );
+ Size aEDSiz = pDlg->LogicToPixel( Size( 142, 12 ), MAP_APPFONT );
+ Point aPnt( a6Siz.Width(), a6Siz.Height() );
+ long nLbH1 = pDlg->LogicToPixel( Size( 0, 93 ), MAP_APPFONT ).Height();
+ long nH = 0;
+ UniString aEmptyStr;
+
+ INITCONTROL( pDirTitel, FixedText, 0,
+ aPnt, aFTSiz, UniString( SvtResId( STR_FILEDLG_DIR ) ), HID_FILEDLG_DIR );
+ aPnt.Y() += aFTSiz.Height() + a3Siz.Height();
+
+ INITCONTROL( pEdit, Edit, WB_BORDER, aPnt, aEDSiz, aPath.GetFull(), HID_FILEDLG_EDIT );
+
+ aPnt.Y() += aEDSiz.Height() + a3Siz.Height();
+#ifndef UNX
+ long nLbH2 = pDlg->LogicToPixel( Size( 0, 60 ), MAP_APPFONT ).Height();
+ INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER,
+ aPnt, Size( aEDSiz.Width(), nLbH1 ), aEmptyStr, HID_FILEDLG_DIRS );
+ aPnt.Y() += nLbH1 + a6Siz.Height();
+ INITCONTROL( pDriveTitle, FixedText, 0,
+ aPnt, aFTSiz, UniString( SvtResId( STR_FILEDLG_DRIVES ) ), HID_FILEDLG_DRIVE );
+ aPnt.Y() += aFTSiz.Height() + a3Siz.Height();
+ INITCONTROL( pDriveList, ListBox, WB_DROPDOWN,
+ aPnt, Size( aEDSiz.Width(), nLbH2 ), aEmptyStr, HID_FILEDLG_DRIVES );
+ nH = aPnt.Y() + aEDSiz.Height() + a6Siz.Height();
+#else
+ long nNewH = nLbH1 + 3 * a3Siz.Height() +
+ aFTSiz.Height() + aEDSiz.Height();
+ INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER,
+ aPnt, Size( aEDSiz.Width(), nNewH ), aEmptyStr, HID_FILEDLG_DIRS );
+ nH = aPnt.Y() + nNewH + a6Siz.Height();
+ pDriveTitle = NULL;
+ pDriveList = NULL;
+#endif
+
+ long nExtraWidth = pDlg->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "(W)" ) ) )+10;
+ String aOkStr = Button::GetStandardText( BUTTON_OK );
+ long nTextWidth = pDlg->GetTextWidth( aOkStr )+nExtraWidth;
+ if( nTextWidth > aBtnSiz.Width() )
+ aBtnSiz.Width() = nTextWidth;
+
+ String aCancelStr = Button::GetStandardText( BUTTON_CANCEL );
+ nTextWidth = pDlg->GetTextWidth( aCancelStr )+nExtraWidth;
+ if( nTextWidth > aBtnSiz.Width() )
+ aBtnSiz.Width() = nTextWidth;
+
+ String aNewDirStr( SvtResId( STR_FILEDLG_NEWDIR ) );
+ nTextWidth = pDlg->GetTextWidth( aNewDirStr )+nExtraWidth;
+ if( nTextWidth > aBtnSiz.Width() )
+ aBtnSiz.Width() = nTextWidth;
+#if defined(UNX) || defined(OS2)
+ String aHomeDirStr( SvtResId( STR_FILEDLG_HOME ) );
+ nTextWidth = pDlg->GetTextWidth( aHomeDirStr )+nExtraWidth;
+ if( nTextWidth > aBtnSiz.Width() )
+ aBtnSiz.Width() = nTextWidth;
+#endif
+
+ aPnt.X() = 2 * a6Siz.Width() + aEDSiz.Width();
+ aPnt.Y() = a6Siz.Height();
+ INITCONTROL( pOkBtn, PushButton, WB_DEFBUTTON,
+ aPnt, aBtnSiz, aOkStr, 0 );
+ aPnt.Y() += aBtnSiz.Height() + a3Siz.Height();
+ INITCONTROL( pCancelBtn, CancelButton, 0,
+ aPnt, aBtnSiz, aCancelStr, 0 );
+ aPnt.Y() += aBtnSiz.Height() + a3Siz.Height();
+ INITCONTROL( pNewDirBtn, PushButton, WB_DEFBUTTON,
+ aPnt, aBtnSiz, aNewDirStr, HID_FILEDLG_NEWDIR );
+#if defined(UNX) || defined(OS2)
+ aPnt.Y() += aBtnSiz.Height() + a3Siz.Height();
+ INITCONTROL( pHomeBtn, PushButton, WB_DEFBUTTON,
+ aPnt, aBtnSiz, aHomeDirStr, HID_FILEDLG_HOME );
+#else
+ pHomeBtn = NULL;
+#endif
+
+ pDirPath = 0;
+ pLoadBtn = 0;
+ // Dialogbreite == OKBtn-Position + OKBtn-Breite + Rand
+ long nW = aPnt.X() + aBtnSiz.Width() + a6Siz.Width();
+
+ pDlg->SetOutputSizePixel( Size( nW, nH ) ); // Groesse ggf. auch Resource wird geplaettet?
+
+ if (pDirList)
+ pDirList->SetDoubleClickHdl(LINK( this, ImpPathDialog, DblClickHdl) );
+
+ if (pDirList)
+ pDirList->SetSelectHdl( LINK( this, ImpPathDialog, SelectHdl ) );
+
+ if (pDriveList)
+ pDriveList->SetSelectHdl( LINK( this, ImpPathDialog, SelectHdl ) );
+
+ if (pOkBtn)
+ pOkBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
+
+ if (pCancelBtn)
+ pCancelBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
+
+ if (pHomeBtn)
+ pHomeBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
+
+ if (pNewDirBtn)
+ pNewDirBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
+
+ nOwnChilds = pDlg->GetChildCount();
+}
+
+
+
+IMPL_LINK( ImpPathDialog, SelectHdl, ListBox *, p )
+{
+ if( p == pDriveList )
+ {
+ UniString aDrive( pDriveList->GetSelectEntry(), 0, 2);
+ aDrive += '\\';
+ SetPath( aDrive );
+ }
+ else
+ if( p == pDirList )
+ {
+ // isolate the pure name of the entry
+ // removing trainling stuff and leading spaces
+ UniString aEntry( pDirList->GetSelectEntry() );
+
+ aEntry.EraseLeadingChars( ' ' );
+ USHORT nPos = aEntry.Search( '/' );
+ aEntry.Erase( nPos );
+
+ // build the absolute path to the selected item
+ DirEntry aNewPath;
+ aNewPath.ToAbs();
+
+ USHORT nCurPos = pDirList->GetSelectEntryPos();
+
+ // Wird nach oben gewechselt
+ if( nCurPos < nDirCount )
+ aNewPath = aNewPath[nDirCount-nCurPos-1];
+ else
+ aNewPath += aEntry;
+
+ pEdit->SetText( aNewPath.GetFull() );
+ }
+
+ return 0;
+}
+
+
+IMPL_LINK( ImpPathDialog, ClickHdl, Button*, pBtn )
+{
+ if ( pBtn == pOkBtn || pBtn == pLoadBtn )
+ {
+ DirEntry aFile( pEdit->GetText() );
+
+ // Existiert File / File ueberschreiben
+ if( IsFileOk( aFile ) )
+ {
+ // Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden
+ aPath = aFile;
+ aPath.ToAbs();
+ GetPathDialog()->EndDialog( TRUE );
+ }
+ else
+ {
+ DirEntry aCheck( aPath );
+ aCheck += aFile;
+ if( aCheck.Exists() )
+ {
+ aCheck.ToAbs();
+ SetPath( aCheck.GetFull() );
+ pEdit->SetSelection( Selection( 0x7FFFFFFF, 0x7FFFFFFF ) );
+ }
+ }
+ }
+ else
+ if ( pBtn == pCancelBtn )
+ {
+ GetPathDialog()->EndDialog( FALSE );
+ }
+ else
+ if ( pBtn == pHomeBtn )
+ {
+ ::rtl::OUString aHomeDir;
+ NAMESPACE_VOS( OSecurity ) aSecurity;
+ if ( aSecurity.getHomeDir( aHomeDir ) )
+ {
+ DirEntry aFile ( aHomeDir );
+ if ( IsFileOk( aFile ) )
+ {
+ aFile.ToAbs();
+ SetPath( aFile.GetFull() );
+ }
+ }
+ }
+ else
+ if ( pBtn == pNewDirBtn )
+ {
+ DirEntry aFile( pEdit->GetText() );
+ if( ! aFile.Exists() && ! FileStat( aFile ).IsKind( FSYS_KIND_WILD ) )
+ aFile.MakeDir();
+
+ if( IsFileOk ( aFile ) )
+ {
+ aFile.ToAbs();
+ SetPath( aFile.GetFull() );
+ }
+ }
+
+ return 0;
+}
+
+
+IMPL_LINK( ImpPathDialog, DblClickHdl, ListBox*, pBox )
+{
+ // isolate the pure name of the entry
+ // removing trainling stuff and leading spaces
+ UniString aEntry( pBox->GetSelectEntry() );
+
+ aEntry.EraseLeadingChars( ' ' );
+ USHORT nPos = aEntry.Search( '/' );
+ aEntry.Erase( nPos );
+
+ // build the absolute path to the selected item
+ DirEntry aNewPath;
+ aNewPath.ToAbs();
+ if( pBox == pDirList )
+ {
+ USHORT nCurPos = pDirList->GetSelectEntryPos();
+
+ // Wenn es schon das aktuelle ist, dann mache nichts
+ if( nCurPos == nDirCount-1 )
+ return 0;
+
+ // Wird nach oben gewechselt
+ if( nCurPos < nDirCount )
+ aNewPath = aNewPath[nDirCount-nCurPos-1];
+ else
+ aNewPath += aEntry;
+ }
+ else
+ aNewPath += aEntry;
+
+ pSvPathDialog->EnterWait();
+
+ if( FileStat( aNewPath ).GetKind() & FSYS_KIND_DIR )
+ {
+ // Neuen Pfad setzen und Listboxen updaten
+ aPath = aNewPath;
+ if( !aPath.SetCWD( TRUE ) )
+ {
+ ErrorBox aBox( GetPathDialog(),
+ WB_OK_CANCEL | WB_DEF_OK,
+ UniString( SvtResId( STR_FILEDLG_CANTCHDIR ) ) );
+ if( aBox.Execute() == RET_CANCEL )
+ GetPathDialog()->EndDialog( FALSE );
+ }
+ UpdateEntries( TRUE );
+ }
+
+ pSvPathDialog->LeaveWait();
+ return 0;
+}
+
+void ImpPathDialog::UpdateEntries( const BOOL )
+{
+ UniString aTabString;
+ DirEntry aTmpPath;
+ aTmpPath.ToAbs();
+
+ nDirCount = aTmpPath.Level();
+
+ pDirList->SetUpdateMode( FALSE );
+ pDirList->Clear();
+
+ for( USHORT i = nDirCount; i > 0; i-- )
+ {
+ UniString aName( aTabString );
+ aName += aTmpPath[i-1].GetName();
+ pDirList->InsertEntry( aName );
+ aTabString.AppendAscii( " ", 2 );
+ }
+
+ // scan the directory
+ DirEntry aCurrent;
+ aCurrent.ToAbs();
+
+ Dir aDir( aCurrent, FSYS_KIND_DIR|FSYS_KIND_FILE );
+
+ USHORT nEntries = aDir.Count();
+ if( nEntries )
+ {
+ UniStringList aSortDirList;
+ for ( USHORT n = 0; n < nEntries; n++ )
+ {
+ DirEntry& rEntry = aDir[n];
+ UniString aName( rEntry.GetName() );
+ if( aName.Len() && ( aName.GetChar(0) != '.' ) && rEntry.Exists() )
+ {
+ if( FileStat( rEntry ).GetKind() & FSYS_KIND_DIR )
+ {
+ ULONG l = 0;
+ if( xCollator.is() )
+ {
+ for( l = 0; l < aSortDirList.Count(); l++ )
+ if( xCollator->compareString( *aSortDirList.GetObject(l), aName ) > 0 )
+ break;
+ }
+ aSortDirList.Insert( new UniString( aName ), l );
+ }
+ }
+ }
+
+ for( ULONG l = 0; l < aSortDirList.Count(); l++ )
+ {
+ UniString aEntryStr( aTabString );
+ aEntryStr += *aSortDirList.GetObject(l);
+ pDirList->InsertEntry( aEntryStr );
+ delete aSortDirList.GetObject(l);
+ }
+ }
+
+ UpdateDirs( aTmpPath );
+}
+
+void ImpPathDialog::UpdateDirs( const DirEntry& rTmpPath )
+{
+ pDirList->SelectEntryPos( nDirCount-1 );
+ pDirList->SetTopEntry( nDirCount > 1
+ ? nDirCount - 2
+ : nDirCount - 1 );
+ pDirList->SetUpdateMode( TRUE );
+ pDirList->Invalidate();
+ pDirList->Update();
+
+ UniString aDirName = rTmpPath.GetFull();
+ if( pDirPath )
+ pDirPath->SetText( aDirName );
+ else
+ pEdit->SetText( aDirName );
+}
+
+BOOL ImpPathDialog::IsFileOk( const DirEntry& rDirEntry )
+{
+ if( FileStat( rDirEntry ).GetKind() & (FSYS_KIND_WILD | FSYS_KIND_DEV) )
+ return FALSE;
+ else
+ {
+ // Datei vorhanden ?
+ if( ! rDirEntry.Exists() )
+ {
+ UniString aQueryTxt( SvtResId( STR_FILEDLG_ASKNEWDIR ) );
+ aQueryTxt.SearchAndReplaceAscii( "%s", rDirEntry.GetFull() );
+ QueryBox aQuery( GetPathDialog(),
+ WB_YES_NO | WB_DEF_YES,
+ aQueryTxt );
+ if( aQuery.Execute() == RET_YES )
+ rDirEntry.MakeDir();
+ else
+ return FALSE;
+ }
+ if( !FileStat( rDirEntry ).IsKind( FSYS_KIND_DIR ) )
+ {
+ UniString aBoxText( SvtResId( STR_FILEDLG_CANTOPENDIR ) );
+ aBoxText.AppendAscii( "\n[" );
+ aBoxText += rDirEntry.GetFull();
+ aBoxText.AppendAscii( "]" );
+ InfoBox aBox( GetPathDialog(), aBoxText );
+ aBox.Execute();
+ return FALSE;
+ }
+ }
+ return GetPathDialog()->OK() != 0;
+}
+
+
+void ImpPathDialog::PreExecute()
+{
+ // Neues Verzeichnis setzen und Listboxen updaten
+ aPath.SetCWD( TRUE );
+ UpdateEntries( TRUE );
+
+ // Zusaetzliche Buttons anordnen
+ Point aPos;
+ Size aSize;
+ long nDY;
+ if( pLoadBtn )
+ {
+ aPos = pLoadBtn->GetPosPixel();
+ aSize = pLoadBtn->GetSizePixel();
+ nDY = pLoadBtn->GetSizePixel().Height() * 2;
+ }
+ else
+ {
+ aPos = pCancelBtn->GetPosPixel();
+ aSize = pCancelBtn->GetSizePixel();
+ nDY = pCancelBtn->GetPosPixel().Y() - pOkBtn->GetPosPixel().Y();
+ }
+
+ // Standard-Controls anpassen
+ long nMaxWidth = 0;
+
+ // Maximale Breite ermitteln
+ USHORT nChilds = GetPathDialog()->GetChildCount();
+ USHORT n;
+ for ( n = nOwnChilds; n < nChilds; n++ )
+ {
+ Window* pChild = GetPathDialog()->GetChild( n );
+ pChild = pChild->GetWindow( WINDOW_CLIENT );
+ if( pChild->GetType() != WINDOW_WINDOW )
+ {
+ long nWidth = pChild->GetTextWidth( pChild->GetText() ) + 12;
+ if( nMaxWidth < nWidth )
+ nMaxWidth = nWidth;
+ nWidth = pChild->GetSizePixel().Width();
+ if( nMaxWidth < nWidth )
+ nMaxWidth = nWidth;
+ }
+ }
+
+ if( nMaxWidth > aSize.Width() )
+ {
+ Size aDlgSize = GetPathDialog()->GetOutputSizePixel();
+ GetPathDialog()->SetOutputSizePixel( Size( aDlgSize.Width()+nMaxWidth-aSize.Width(), aDlgSize.Height() ) );
+ aSize.Width() = nMaxWidth;
+
+ if( pOkBtn )
+ pOkBtn->SetSizePixel( aSize );
+ if( pCancelBtn )
+ pCancelBtn->SetSizePixel( aSize );
+ if( pLoadBtn )
+ pLoadBtn->SetSizePixel( aSize );
+ }
+ else
+ nMaxWidth = aSize.Width();
+
+ for ( n = nOwnChilds; n < nChilds; n++ )
+ {
+ Window* pChild = GetPathDialog()->GetChild( n );
+ pChild = pChild->GetWindow( WINDOW_CLIENT );
+ if( pChild->GetType() != WINDOW_WINDOW )
+ {
+ aPos.Y() += nDY;
+ pChild->SetPosSizePixel( aPos, aSize );
+ }
+ else
+ {
+ Size aDlgSize = GetPathDialog()->GetOutputSizePixel();
+ long nExtra = Min( aDlgSize.Height(), (long)160);
+ GetPathDialog()->SetOutputSizePixel( Size( aDlgSize.Width()+nExtra, aDlgSize.Height() ) );
+ Size aSz( nExtra, nExtra );
+ aSz.Width() -= 8;
+ aSz.Height() -= 8;
+ Point aCtrlPos( aDlgSize.Width() + 2, (aDlgSize.Height()-aSz.Height())/2 );
+ pChild->SetPosSizePixel( aCtrlPos, aSz );
+ }
+ }
+
+ // Laufwerke-LB fuellen
+ if( pDriveList )
+ {
+ DirEntry aTmpDirEntry;
+ Dir aDir( aTmpDirEntry, FSYS_KIND_BLOCK );
+
+ USHORT nCount = aDir.Count(), i;
+ for( i = 0; i < nCount; ++i )
+ {
+ DirEntry& rEntry = aDir[i];
+ UniString aStr = rEntry.GetFull( FSYS_STYLE_HOST, FALSE );
+
+ UniString aVolume = rEntry.GetVolume() ;
+ aStr.ToUpperAscii();
+ if ( aVolume.Len() )
+ {
+ aStr += ' ';
+ aStr += aVolume;
+ }
+ pDriveList->InsertEntry( aStr );
+
+ }
+ UniString aPathStr = aPath.GetFull();
+
+ for ( i = 0; i < pDriveList->GetEntryCount(); ++i )
+ {
+ UniString aEntry = pDriveList->GetEntry(i);
+ xub_StrLen nLen = aEntry.Len();
+ nLen = nLen > 2 ? 2 : nLen;
+ if ( aEntry.CompareIgnoreCaseToAscii( aPathStr, nLen ) == COMPARE_EQUAL )
+ {
+ pDriveList->SelectEntryPos(i);
+ break;
+ }
+ }
+ }
+}
+
+void ImpPathDialog::PostExecute()
+{
+}
+
+void ImpPathDialog::SetPath( UniString const & rPath )
+{
+ aPath = DirEntry( rPath );
+
+ pSvPathDialog->EnterWait();
+
+ DirEntry aFile( rPath );
+ // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
+ // -> abschneiden und merken
+ if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() )
+ aFile.CutName();
+
+ // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
+ pEdit->SetText( rPath );
+ aFile.SetCWD( TRUE );
+ UpdateEntries( TRUE );
+
+ pSvPathDialog->LeaveWait();
+}
+
+void ImpPathDialog::SetPath( Edit const & rEdit )
+{
+ UniString aPresetText = rEdit.GetText();
+ if( aPresetText.Len() )
+ SetPath( aPresetText );
+}
+
+
+UniString ImpPathDialog::GetPath() const
+{
+ DirEntry aFile( pEdit->GetText() );
+ aFile.ToAbs();
+ return aFile.GetFull();
+}
+
+
+ImpFileDialog::ImpFileDialog( PathDialog* pDlg, WinBits nWinBits, RESOURCE_TYPE nType ) :
+ ImpPathDialog( pDlg, nType, FALSE )
+{
+ bOpen = (nWinBits & WB_SAVEAS) == 0;
+
+ SvtResId aSvtResId = bOpen ? STR_FILEDLG_OPEN : STR_FILEDLG_SAVE;
+
+ // Titel setzen
+ GetFileDialog()->SetText( UniString( aSvtResId ) );
+ nDirCount = 0;
+
+ // initialize Controls if not used as a base class
+ if ( nType == WINDOW_FILEDIALOG )
+ InitControls();
+
+ pDlg->SetHelpId( HID_FILEDLG_OPENDLG );
+
+}
+
+ImpFileDialog::~ImpFileDialog()
+{
+ ImpFilterItem* pItem = aFilterList.First();
+ while( pItem )
+ {
+ delete pItem;
+ pItem = aFilterList.Next();
+ }
+
+ delete pFileTitel;
+ if (pFileList && ( pFileList != pDirList ) )
+ delete pFileList;
+
+ delete pTypeTitel;
+ delete pTypeList;
+}
+
+void ImpFileDialog::InitControls()
+{
+ UniString aEmptyStr;
+
+ const int nW = 160;
+ const int nH = 48; // Um den Dialog in eine akzeptable Form zu bringen
+
+ INITCONTROL( pFileTitel, FixedText, 0,
+ Point(10, 12), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_FILE ) ), HID_FILEDLG_FILE );
+ INITCONTROL( pEdit, Edit, WB_BORDER,
+ Point(10, 31), Size(nW, 20), aEmptyStr, HID_FILEDLG_EDIT ); // aMask()
+ INITCONTROL( pFileList, ListBox, WB_SORT | WB_AUTOHSCROLL | WB_BORDER,
+ Point(10, 58), Size(nW, 180-nH), aEmptyStr, HID_FILEDLG_FILES );
+
+ INITCONTROL( pDirTitel, FixedText, 0,
+ Point(nW+20, 12), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_DIR ) ), HID_FILEDLG_DIR );
+ INITCONTROL( pDirPath, FixedInfo, WB_PATHELLIPSIS,
+ Point(nW+20, 33), Size(nW, 20), aPath.GetFull(), HID_FILEDLG_PATH );
+ INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER,
+ Point(nW+20, 58), Size(nW, 180-nH ), aEmptyStr, HID_FILEDLG_DIRS );
+
+ INITCONTROL( pTypeTitel, FixedText, 0,
+ Point(10, 246-nH), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_TYPE ) ), HID_FILEDLG_TYPE );
+
+#ifndef UNX
+ INITCONTROL( pTypeList, ListBox, WB_DROPDOWN,
+ Point(10, 265-nH ), Size(nW, 100 ), aEmptyStr, HID_FILEDLG_TYPES );
+
+ INITCONTROL( pDriveTitle, FixedText, 0,
+ Point(nW+20, 246-nH), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_DRIVES ) ), HID_FILEDLG_DRIVE );
+ INITCONTROL( pDriveList, ListBox, WB_DROPDOWN,
+ Point(nW+20, 265-nH ), Size(nW, 100 ), aEmptyStr, HID_FILEDLG_DRIVES );
+ pNewDirBtn = NULL;
+ pHomeBtn = NULL;
+#else
+ INITCONTROL( pTypeList, ListBox, WB_DROPDOWN,
+ Point(10, 265-nH ), Size(2*nW+20, 100 ), aEmptyStr, HID_FILEDLG_TYPES );
+
+ pDriveTitle = NULL;
+ pDriveList = NULL;
+ pNewDirBtn = NULL;
+ pHomeBtn = NULL;
+#endif
+
+ const long nButtonStartX = 2*nW+20+15;
+ INITCONTROL( pOkBtn, PushButton, WB_DEFBUTTON,
+ Point(nButtonStartX, 10), Size(STD_BTN_WIDTH, STD_BTN_HEIGHT),
+ Button::GetStandardText( BUTTON_OK ), 0 );
+ INITCONTROL( pCancelBtn, CancelButton, 0,
+ Point(nButtonStartX, 45 ), Size(STD_BTN_WIDTH, STD_BTN_HEIGHT),
+ Button::GetStandardText( BUTTON_CANCEL ), 0 );
+
+ pLoadBtn = 0;
+
+ GetFileDialog()->SetOutputSizePixel( Size(nButtonStartX+STD_BTN_WIDTH+10, 298-nH) );
+
+ nOwnChilds = GetPathDialog()->GetChildCount();
+
+ // Handler setzen
+ if (pDriveList)
+ pDriveList->SetSelectHdl( LINK( this, ImpFileDialog, SelectHdl ) );
+
+ if (pDirList)
+ pDirList->SetDoubleClickHdl(LINK( this, ImpFileDialog, DblClickHdl) );
+
+ if (pOkBtn)
+ pOkBtn->SetClickHdl( LINK( this, ImpFileDialog, ClickHdl) );
+
+ if (pCancelBtn)
+ pCancelBtn->SetClickHdl( LINK( this, ImpFileDialog, ClickHdl) );
+
+ if( pFileList )
+ {
+ pFileList->SetSelectHdl( LINK( this, ImpFileDialog, SelectHdl ) );
+ pFileList->SetDoubleClickHdl( LINK( this, ImpFileDialog, DblClickHdl ) );
+ }
+
+ if( pTypeList )
+ pTypeList->SetSelectHdl( LINK( this, ImpFileDialog, DblClickHdl ) );
+}
+
+IMPL_LINK( ImpFileDialog, SelectHdl, ListBox *, p )
+{
+ if( p == pDriveList )
+ {
+ UniString aDrive ( pDriveList->GetSelectEntry(), 0, 2);
+ aDrive += '\\';
+ SetPath( aDrive );
+ }
+ else if (p == pFileList)
+ {
+ // Ausgewaehltes File in das Edit stellen
+ pEdit->SetText( pFileList->GetSelectEntry() );
+ GetFileDialog()->FileSelect();
+ }
+ return 0;
+}
+
+
+IMPL_LINK( ImpFileDialog, DblClickHdl, ListBox *, pBox )
+{
+ // isolate the pure name of the entry
+ // removing trailing stuff and leading spaces
+ UniString aEntry( pBox->GetSelectEntry() );
+
+ aEntry.EraseLeadingChars( ' ' );
+ USHORT nPos = aEntry.Search( '/' );
+ aEntry.Erase( nPos );
+
+ // build the absolute path to the selected item
+ DirEntry aNewPath;
+ aNewPath.ToAbs();
+
+ if( ( pDirList != pFileList ) && ( pBox == pDirList ) )
+ {
+ // SVLOOK
+ USHORT nCurPos = pDirList->GetSelectEntryPos();
+
+ // Wenn es schon das aktuelle ist, dann mache nichts
+ if( nCurPos == nDirCount-1 )
+ return 0;
+
+ // Wird nach oben gewechselt
+ if( nCurPos < nDirCount )
+ aNewPath = aNewPath[nDirCount-nCurPos-1];
+ else
+ aNewPath += aEntry;
+ }
+ else
+ {
+ // non-SVLOOK
+ if( aEntry == UniString( SvtResId( STR_FILEDLG_GOUP ) ) )
+ aEntry.AssignAscii( ".." );
+ aNewPath += aEntry;
+ }
+
+ if( pBox == pFileList )
+ {
+ DirEntry aFile( aEntry );
+
+ // Abfrage, ob File ueberschrieben werden soll...
+ if( !FileStat(aFile).IsKind(FSYS_KIND_DIR) && IsFileOk( aFile ) )
+ {
+ // dann kompletten Pfad mit Filenamen merken und Dialog beenden
+ aPath = aNewPath;
+ GetFileDialog()->EndDialog( TRUE );
+ }
+ }
+
+ GetFileDialog()->EnterWait();
+
+ UniString aFull = aNewPath.GetFull();
+
+ if( ( ( pBox == pDirList ) && ( pDirList != pFileList ) ) ||
+ ( ( pDirList == pFileList ) && FileStat( aNewPath ).GetKind() & FSYS_KIND_DIR ) )
+ {
+ // Neuen Pfad setzen und Listboxen updaten
+ aPath = aNewPath;
+ if( !aPath.SetCWD( TRUE ) )
+ {
+ if( ErrorBox( GetFileDialog(), WB_OK_CANCEL|WB_DEF_OK,
+ UniString( SvtResId( STR_FILEDLG_CANTCHDIR ) ) ).Execute() == RET_CANCEL )
+ {
+ GetFileDialog()->EndDialog( FALSE );
+ }
+ }
+ UpdateEntries( TRUE );
+ GetFileDialog()->FileSelect();
+ }
+
+ if( pBox == pTypeList )
+ {
+ // Neue Maske setzen, und Listboxen updaten
+ USHORT nCurPos = pTypeList->GetSelectEntryPos();
+ if( nCurPos+1 > (USHORT)aFilterList.Count() )
+ aMask = UniString::CreateFromAscii( ALLFILES );
+ else
+ {
+ UniString aFilterListMask = aFilterList.GetObject( nCurPos )->aMask;
+// if( aFilterListMask.Search( ';' ) == STRING_NOTFOUND ) // kein ; in der Maske
+// aMask = WildCard( aFilterListMask, '\0' );
+// else // ; muss beruecksichtigt werden
+ aMask = WildCard( aFilterListMask, ';' );
+ }
+
+ pEdit->SetText( aMask() );
+ UpdateEntries( FALSE );
+ GetFileDialog()->FilterSelect();
+ }
+
+ GetFileDialog()->LeaveWait();
+
+ return 0;
+}
+
+IMPL_LINK( ImpFileDialog, ClickHdl, Button*, pBtn )
+{
+ if( ( pBtn == pOkBtn ) || ( pBtn == pLoadBtn ) )
+ {
+ DirEntry aFile( pEdit->GetText() );
+
+ // Existiert File / File ueberschreiben
+ if( IsFileOk( aFile ) )
+ {
+ // Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden
+ aPath = aFile;
+ aPath.ToAbs();
+ GetFileDialog()->EndDialog( TRUE );
+ }
+ else
+ {
+ GetFileDialog()->EnterWait();
+
+ // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
+ // -> abschneiden und merken
+ if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() )
+ {
+ aMask = aFile.CutName();
+ }
+
+ // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
+ pEdit->SetText( aMask() );
+ aFile.SetCWD( TRUE );
+ UpdateEntries( TRUE );
+
+ GetFileDialog()->LeaveWait();
+ }
+ }
+ else if( pBtn == pCancelBtn )
+ GetFileDialog()->EndDialog( FALSE );
+
+ return 0;
+}
+
+void ImpFileDialog::UpdateEntries( const BOOL bWithDirs )
+{
+ GetFileDialog()->EnterWait();
+
+ UniString aTabString;
+ DirEntry aTmpPath;
+ aTmpPath.ToAbs();
+ nDirCount = aTmpPath.Level();
+
+ if( pFileList )
+ {
+ pFileList->SetUpdateMode( FALSE );
+ pFileList->Clear();
+ }
+
+ if( bWithDirs && (pDirList != pFileList) )
+ {
+ pDirList->SetUpdateMode( FALSE );
+ pDirList->Clear();
+
+ for( USHORT i = nDirCount; i > 0; i-- )
+ {
+ UniString aEntryStr( aTabString );
+ aEntryStr += aTmpPath[i-1].GetName();
+ pDirList->InsertEntry( aEntryStr );
+ aTabString.AppendAscii( " ", 2 );
+ }
+ }
+
+ // for the combined box insert a '..'
+ // (this happens only if WB_3DLOOK is not set)
+
+ if( pDirList == pFileList && nDirCount != 1 )
+ pFileList->InsertEntry( UniString( SvtResId( STR_FILEDLG_GOUP ) ) );
+
+ // scan the directory
+ DirEntry aCurrent;
+ aCurrent.ToAbs();
+ Dir aDir( aCurrent, FSYS_KIND_DIR|FSYS_KIND_FILE );
+ USHORT nEntries = aDir.Count();
+
+ // TempMask, weil Vergleich case-sensitiv
+ BOOL bMatchCase = FALSE; //aCurrent.IsCaseSensitive();
+ UniString aWildCard( aMask.GetWildCard() );
+ if ( !bMatchCase )
+ aWildCard.ToLowerAscii();
+ WildCard aTmpMask( aWildCard, ';' );
+ if ( nEntries )
+ {
+ UniStringList aSortDirList;
+ for ( USHORT n = 0; n < nEntries; n++ )
+ {
+ DirEntry& rEntry = aDir[n];
+ UniString aName( rEntry.GetName() );
+
+ if( aName.Len() &&
+ ( ( ( aName.GetChar(0) != '.' ) ||
+ ( ( aName.GetChar(0) == '.' ) && ( aMask.GetWildCard() ).GetChar(0) == '.' ) )
+ && rEntry.Exists() ) )
+ {
+ FileStat aFileStat( rEntry );
+ UniString aTmpName( aName );
+ if ( !bMatchCase )
+ aTmpName.ToLowerAscii();
+ if( ( aFileStat.GetKind() & FSYS_KIND_FILE ) && aTmpMask.Matches( aTmpName ) )
+ {
+ if( pFileList )
+ pFileList->InsertEntry( aName );
+ }
+ else if( bWithDirs && ( aFileStat.GetKind() & FSYS_KIND_DIR ) )
+ {
+ if( pDirList == pFileList )
+ {
+ UniString aEntryStr( aName );
+ aEntryStr += '/';
+ pDirList->InsertEntry( aEntryStr );
+ }
+ else
+ {
+ ULONG l = 0;
+ if( xCollator.is() )
+ {
+ for( l = 0; l < aSortDirList.Count(); l++ )
+ if( xCollator->compareString( *aSortDirList.GetObject(l), aName ) > 0 )
+ break;
+ }
+ aSortDirList.Insert( new UniString( aName ), l );
+ }
+ }
+ }
+ }
+ for( ULONG l = 0; l < aSortDirList.Count(); l++ )
+ {
+ UniString aEntryStr( aTabString );
+ aEntryStr += *aSortDirList.GetObject(l);
+ pDirList->InsertEntry( aEntryStr );
+ delete aSortDirList.GetObject(l);
+ }
+ }
+
+ if( bWithDirs )
+ UpdateDirs( aTmpPath );
+
+ if( pFileList )
+ {
+ if ( pDirList == pFileList && nDirCount > 1 )
+ pFileList->SelectEntryPos( 1 );
+ else
+ pFileList->SetNoSelection();
+ pFileList->SetUpdateMode( TRUE );
+ pFileList->Invalidate();
+ pFileList->Update();
+ }
+
+ if( pDriveList )
+ {
+ if( pDirList->GetEntryCount() > 0 )
+ {
+ UniString aStr( pDirList->GetEntry( 0 ) );
+ aStr.Erase( 2 );
+ aStr.ToLowerAscii();
+ pDriveList->SelectEntry( aStr );
+ }
+ }
+
+ GetFileDialog()->LeaveWait();
+}
+
+BOOL ImpFileDialog::IsFileOk( const DirEntry& rDirEntry )
+{
+ if( FileStat( rDirEntry ).GetKind() & (FSYS_KIND_WILD | FSYS_KIND_DEV) )
+ return FALSE;
+ if( FileStat( rDirEntry ).GetKind() & FSYS_KIND_DIR )
+ {
+ if( pFileList )
+ return FALSE;
+ }
+ else if( bOpen )
+ {
+ // Datei vorhanden ?
+ if( !FileStat( rDirEntry ).IsKind( FSYS_KIND_FILE ) )
+ {
+ UniString aErrorString( SvtResId( STR_FILEDLG_CANTOPENFILE ) );
+ aErrorString.AppendAscii( "\n[" );
+ aErrorString += rDirEntry.GetFull();
+ aErrorString += ']';
+ InfoBox aBox( GetFileDialog(),
+ aErrorString );
+ aBox.Execute();
+ return FALSE;
+ }
+ }
+ else
+ {
+ // Datei vorhanden ?
+ if( FileStat( ExtendFileName( rDirEntry ) ).IsKind( FSYS_KIND_FILE ) )
+ {
+ UniString aQueryString( SvtResId( STR_FILEDLG_OVERWRITE ) );
+ aQueryString.AppendAscii( "\n[" );
+ aQueryString += rDirEntry.GetFull();
+ aQueryString += ']';
+ QueryBox aBox( GetFileDialog(),
+ WinBits( WB_YES_NO | WB_DEF_NO ),
+ aQueryString );
+ if( aBox.Execute() != RET_YES )
+ return FALSE;
+ }
+ }
+ return GetFileDialog()->OK() != 0;
+}
+
+void ImpFileDialog::SetPath( UniString const & rPath )
+{
+ aPath = DirEntry( rPath );
+ GetFileDialog()->EnterWait();
+
+ DirEntry aFile( rPath );
+
+ // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
+ // -> abschneiden und merken
+ if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() )
+ {
+ aMask = aFile.CutName();
+
+ // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
+ if( pDirList )
+ {
+ UniString aWildCard( aMask.GetWildCard() );
+ pEdit->SetText( aWildCard );
+ }
+ else
+ pEdit->SetText( rPath );
+ }
+
+ aFile.SetCWD( TRUE );
+
+ UpdateEntries( TRUE );
+
+ GetFileDialog()->LeaveWait();
+}
+
+void ImpFileDialog::SetPath( Edit const& rEdit )
+{
+ UniString aPresetText = rEdit.GetText();
+ if( aPresetText.Len() )
+ SetPath( aPresetText );
+}
+
+
+void ImpFileDialog::AddFilter( const UniString& rFilter, const UniString& rMask )
+{
+ aFilterList.Insert( new ImpFilterItem( rFilter, rMask ), LIST_APPEND );
+ if( pTypeList )
+ pTypeList->InsertEntry( rFilter, LISTBOX_APPEND );
+
+ if( !GetCurFilter().Len() )
+ SetCurFilter( rFilter );
+}
+
+void ImpFileDialog::RemoveFilter( const UniString& rFilter )
+{
+ ImpFilterItem* pItem = aFilterList.First();
+ while( pItem && pItem->aName != rFilter )
+ pItem = aFilterList.Next();
+
+ if( pItem )
+ {
+ delete aFilterList.Remove();
+ if( pTypeList )
+ pTypeList->RemoveEntry( rFilter );
+ }
+}
+
+void ImpFileDialog::RemoveAllFilter()
+{
+ ImpFilterItem* pItem = aFilterList.First();
+ while( pItem )
+ {
+ delete pItem;
+ pItem = aFilterList.Next();
+ }
+ aFilterList.Clear();
+
+ if( pTypeList )
+ pTypeList->Clear();
+}
+
+void ImpFileDialog::SetCurFilter( const UniString& rFilter )
+{
+ if( !pTypeList )
+ return;
+
+ ImpFilterItem* pItem = aFilterList.First();
+ while( pItem && pItem->aName != rFilter )
+ pItem = aFilterList.Next();
+
+ if( pItem )
+ pTypeList->SelectEntryPos( (USHORT)aFilterList.GetCurPos() );
+ else
+ pTypeList->SetNoSelection();
+}
+
+UniString ImpFileDialog::GetCurFilter() const
+{
+ UniString aFilter;
+ if ( pTypeList )
+ aFilter = pTypeList->GetSelectEntry();
+ return aFilter;
+}
+
+void ImpFileDialog::PreExecute()
+{
+ // ListBoxen erst unmittelbar vor Execute fuellen
+ // (damit vor Execute der Pfad umgesetzt werden kann, ohne das immer die
+ // Listboxen sofort upgedatet werden)
+
+ GetFileDialog()->EnterWait();
+
+ // Wenn kein Filter vorhanden, dann auch keine FilterBox
+ if( pTypeList && !pTypeList->GetEntryCount() )
+ {
+ // pTypeList->InsertEntry( "* (all files)" );
+ pTypeTitel->Disable();
+ pTypeList->Disable();
+ }
+
+ if( pTypeList )
+ {
+ USHORT nCurType = pTypeList->GetSelectEntryPos();
+ if( nCurType < aFilterList.Count() )
+ {
+ UniString aFilterListMask = aFilterList.GetObject( nCurType )->aMask;
+ if( aFilterListMask.Search( ';' ) == STRING_NOTFOUND ) // kein ; in der Maske
+ aMask = WildCard( aFilterListMask, '\0' );
+ else // ; in der Maske, muss in der Wildcard beruecksichtigt werden
+ aMask = WildCard( aFilterListMask, ';' );
+ }
+ else
+ aMask = UniString::CreateFromAscii( ALLFILES );
+ }
+ else
+ aMask = UniString::CreateFromAscii( ALLFILES );
+
+ // Neue Maske setzen
+ if( pEdit->GetText().Len() == 0 )
+ pEdit->SetText( aMask() );
+
+ ImpPathDialog::PreExecute();
+
+ GetFileDialog()->LeaveWait();
+}
+
+UniString ImpFileDialog::GetPath() const
+{
+ DirEntry aFile( pEdit->GetText() );
+ return ExtendFileName( aFile );
+}
+
+UniString ImpFileDialog::ExtendFileName( DirEntry aEntry ) const
+{
+ aEntry.ToAbs();
+ // das ganze Theater hier ohnehin nur machen, wenn Dateiname
+ // ohne Extension angegeben wurde
+ if( !aEntry.GetExtension().Len() )
+ {
+ UniString aPostfix; // hier kommt die ausgesuchte Extension herein
+
+ // ist ein Filter mit Extension gesetzt?
+ USHORT nChosenFilterPos = pTypeList->GetSelectEntryPos();
+ if( nChosenFilterPos != LISTBOX_ENTRY_NOTFOUND )
+ {
+ UniString aExtensionMask = GetFileDialog()->GetFilterType( nChosenFilterPos );
+ // aExtension ist z.B. *.sdw, alles bis einschliesslich Punkt abschneiden
+ UniString aExtension = aExtensionMask.Copy( aExtensionMask.Search( '.' )+1 );
+
+ // hat der Filter ueberhaupt eine Extension
+ if( aExtension.Len() )
+ {
+ // keine Wildcards enthalten?
+ if( ( aExtension.Search( '*' ) == STRING_NOTFOUND ) &&
+ ( aExtension.Search( '?' ) == STRING_NOTFOUND ) )
+ {
+ // OK, Filter hat Extension ohne Wildcards -> verwenden
+ aPostfix = aExtension;
+ }
+ else
+ {
+ // Filter hat Extension mit Wildcards (z.B. *.*) -> nicht verwenden
+ aPostfix.Erase();
+ }
+ }
+ else
+ {
+ // Filter hatte keine Extension (schwer vorstellbar) -> nichts anhaengen
+ aPostfix.Erase();
+ }
+ }
+ else
+ {
+ // kein Filter gefunden (merkw�rdig) -> Default-Extension anhaengen
+ aPostfix = GetFileDialog()->GetDefaultExt();
+ }
+
+ // jetzt kann es mit dem Anhaengen losgehen
+ const sal_Unicode* pExt = aPostfix.GetBuffer();
+ while( *pExt == '*' || *pExt == '?' )
+ pExt++;
+
+ if( *pExt )
+ {
+ UniString aName = aEntry.GetName();
+ if( *pExt != '.' )
+ aName += '.';
+ aName += pExt;
+ aEntry.SetName( aName );
+ }
+ }
+ return aEntry.GetFull();
+}
+
+
+void ImpSvFileDlg::CreateDialog( PathDialog* pSvDlg, WinBits nStyle, RESOURCE_TYPE nType, BOOL bCreate )
+{
+ delete pDlg;
+ if ( nType == WINDOW_PATHDIALOG )
+ pDlg = new ImpPathDialog( pSvDlg, nType, bCreate );
+ else
+ pDlg = new ImpFileDialog( pSvDlg, nStyle, nType );
+}
+
+
diff --git a/svtools/source/dialogs/filedlg2.hxx b/svtools/source/dialogs/filedlg2.hxx
new file mode 100644
index 000000000000..4d32565a2775
--- /dev/null
+++ b/svtools/source/dialogs/filedlg2.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 _FILEDLG2_HXX
+#define _FILEDLG2_HXX
+
+#include <tools/debug.hxx>
+#include <tools/fsys.hxx>
+#ifndef _SV_BUTTON_HXX //autogen wg. PushButton
+#include <vcl/button.hxx>
+#endif
+#include <vcl/unohelp.hxx>
+
+class FixedText;
+class Edit;
+class ListBox;
+class ListBox;
+class Button;
+
+class PathDialog;
+class FileDialog;
+class ImpPathDialog;
+
+struct ImpFilterItem
+{
+ String aName;
+ String aMask;
+
+ ImpFilterItem( const String & rFilter, const String & rMask )
+ {
+ aName = rFilter;
+ aMask = rMask;
+ }
+};
+
+DECLARE_LIST( ImpFilterList, ImpFilterItem* )
+#include <vcl/lstbox.hxx>
+
+class KbdListBox : public ListBox
+{
+public:
+
+ KbdListBox( Window* pParent, WinBits nStyle = WB_BORDER )
+ : ListBox ( pParent, nStyle )
+ {};
+
+virtual long PreNotify( NotifyEvent& rNEvt );
+
+};
+
+
+class ImpPathDialog
+{
+ friend class ImpFileDialog;
+
+private:
+ PathDialog* pSvPathDialog;
+ Edit* pEdit;
+ FixedText* pDirTitel;
+ KbdListBox* pDirList;
+ FixedText* pDirPath;
+ ListBox* pDriveList;
+ FixedText* pDriveTitle;
+ PushButton* pLoadBtn;
+ PushButton* pOkBtn;
+ PushButton* pCancelBtn;
+ PushButton* pHomeBtn;
+ PushButton* pNewDirBtn;
+
+ USHORT nOwnChilds;
+
+ DirEntry aPath; // aktuell angewaehlter Pfad
+ USHORT nDirCount; // Anzahl der Verzeichnis-
+ // Verschachtelungen
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator >
+ xCollator;
+
+protected:
+
+ virtual void UpdateEntries( const BOOL bWithDirs );
+ void UpdateDirs( const DirEntry& rTmpPath );
+
+ BOOL IsFileOk( const DirEntry& rDirEntry );
+ void InitControls();
+
+ DECL_LINK( SelectHdl, ListBox * );
+ DECL_LINK( DblClickHdl, ListBox * );
+ DECL_LINK( ClickHdl, Button * );
+
+public:
+ ImpPathDialog( PathDialog* pDlg, RESOURCE_TYPE nType, BOOL bCreateDir );
+ virtual ~ImpPathDialog();
+
+ virtual void SetPath( const String& rPath );
+ virtual void SetPath( const Edit& rEdit );
+ virtual String GetPath() const;
+
+ virtual void PreExecute();
+ virtual void PostExecute();
+
+ PathDialog* GetPathDialog() const { return pSvPathDialog; }
+
+ void SetOkButtonText( const String& rText ) { pOkBtn->SetText( rText ); }
+ void SetCancelButtonText( const String& rText ) { pCancelBtn->SetText( rText ); }
+
+};
+
+
+class ImpFileDialog : public ImpPathDialog
+{
+private:
+ FixedText* pFileTitel;
+ ListBox* pFileList;
+ FixedText* pTypeTitel;
+ ListBox* pTypeList;
+
+ WildCard aMask; // aktuelle Maske
+
+ ImpFilterList aFilterList; // Filterliste
+ USHORT nCurFilter; // aktueller Filter
+
+ BOOL bOpen; // TRUE = Open; FALSE = SAVEAS
+
+protected:
+ void InitControls();
+
+ String ExtendFileName( DirEntry aEntry ) const;
+
+ DECL_LINK( SelectHdl, ListBox * );
+ DECL_LINK( DblClickHdl, ListBox * );
+ DECL_LINK( ClickHdl, Button * );
+
+ virtual void UpdateEntries( const BOOL bWithDirs );
+ BOOL IsFileOk( const DirEntry& rDirEntry );
+
+public:
+ ImpFileDialog( PathDialog* pDlg, WinBits nStyle, RESOURCE_TYPE nType );
+ virtual ~ImpFileDialog();
+
+ void AddFilter( const String& rFilter, const String& rMask );
+ void RemoveFilter( const String& rFilter );
+ void RemoveAllFilter();
+ void SetCurFilter( const String& rFilter );
+ String GetCurFilter() const;
+
+ USHORT GetFilterCount() const { return (USHORT)aFilterList.Count(); }
+ inline String GetFilterName( USHORT nPos ) const;
+ inline String GetFilterType( USHORT nPos ) const;
+
+ virtual void SetPath( const String& rPath );
+ virtual void SetPath( const Edit& rEdit );
+ virtual String GetPath() const;
+
+ virtual void PreExecute();
+
+ FileDialog* GetFileDialog() const { return (FileDialog*)GetPathDialog(); }
+};
+
+inline String ImpFileDialog::GetFilterName( USHORT nPos ) const
+{
+ String aName;
+ ImpFilterItem* pItem = aFilterList.GetObject( nPos );
+ if ( pItem )
+ aName = pItem->aName;
+ return aName;
+}
+
+inline String ImpFileDialog::GetFilterType( USHORT nPos ) const
+{
+ String aFilterMask;
+ ImpFilterItem* pItem = aFilterList.GetObject( nPos );
+ if ( pItem )
+ aFilterMask = pItem->aMask;
+ return aFilterMask;
+}
+
+class ImpSvFileDlg
+{
+private:
+ ImpPathDialog* pDlg;
+
+public:
+ ImpSvFileDlg() { pDlg = 0; }
+ ~ImpSvFileDlg() { delete pDlg; }
+
+ ImpPathDialog* GetDialog() const { return pDlg; }
+ void CreateDialog( PathDialog* pCreateFrom, WinBits nStyle, RESOURCE_TYPE nType, BOOL bCreate );
+
+ void SetOkButtonText( const String& rText ) { pDlg->SetOkButtonText( rText ); } // ihr habts ja nicht anders gewollt
+ void SetCancelButtonText( const String& rText ) { pDlg->SetCancelButtonText( rText ); }
+
+};
+
+#endif // _FILEDLG2_HXX
diff --git a/svtools/source/dialogs/filedlg2.src b/svtools/source/dialogs/filedlg2.src
new file mode 100644
index 000000000000..977a0d6f430b
--- /dev/null
+++ b/svtools/source/dialogs/filedlg2.src
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <filedlg2.hrc>
+String STR_FILEDLG_SELECT
+{
+ Text [ en-US ] = "Select Directory" ;
+};
+String STR_FILEDLG_CANTCHDIR
+{
+ Text [ en-US ] = "Cannot change to directory" ;
+};
+String STR_FILEDLG_OPEN
+{
+ Text [ en-US ] = "Open" ;
+};
+String STR_FILEDLG_FILE
+{
+ Text [ en-US ] = "~File" ;
+};
+String STR_FILEDLG_DIR
+{
+ Text [ en-US ] = "~Directory" ;
+};
+String STR_FILEDLG_TYPE
+{
+ Text [ en-US ] = "File ~type" ;
+};
+String STR_FILEDLG_CANTOPENFILE
+{
+ Text [ en-US ] = "Can't open file" ;
+};
+String STR_FILEDLG_CANTOPENDIR
+{
+ Text [ en-US ] = "Can't open directory" ;
+};
+String STR_FILEDLG_OVERWRITE
+{
+ Text [ en-US ] = "This file already exists. \nOverwrite ?" ;
+};
+String STR_FILEDLG_GOUP
+{
+ Text [ en-US ] = "Up One Level" ;
+};
+String STR_FILEDLG_SAVE
+{
+ Text [ en-US ] = "Save" ;
+};
+String STR_FILEDLG_DRIVES
+{
+ Text [ en-US ] = "D~rive" ;
+};
+String STR_FILEDLG_HOME
+{
+ Text [ en-US ] = "User Directory" ;
+};
+String STR_FILEDLG_NEWDIR
+{
+ Text [ en-US ] = "Create Directory" ;
+};
+String STR_FILEDLG_ASKNEWDIR
+{
+ Text [ en-US ] = "Do you want the directory %s to be created ?" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/dialogs/formats.src b/svtools/source/dialogs/formats.src
new file mode 100644
index 000000000000..f8ce80f62f2f
--- /dev/null
+++ b/svtools/source/dialogs/formats.src
@@ -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.
+ *
+ ************************************************************************/
+
+#include "sores.hxx"
+
+String STR_FORMAT_STRING
+{
+ Text [ en-US ] = "Unformatted text" ;
+};
+String STR_FORMAT_BITMAP
+{
+ Text [ en-US ] = "Bitmap";
+};
+String STR_FORMAT_GDIMETAFILE
+{
+ Text [ en-US ] = "GDI metafile";
+};
+String STR_FORMAT_RTF
+{
+ Text [ en-US ] = "Formatted text [RTF]" ;
+};
+String STR_FORMAT_ID_DRAWING
+{
+ Text [ en-US ] = "Drawing format";
+};
+String STR_FORMAT_ID_SVXB
+{
+ Text [ en-US ] = "SVXB (StarView bitmap/animation)";
+};
+String STR_FORMAT_ID_INTERNALLINK_STATE
+{
+ Text [ en-US ] = "Status Info from Svx Internal Link";
+};
+String STR_FORMAT_ID_SOLK
+{
+ Text [ en-US ] = "SOLK (%PRODUCTNAME Link)";
+};
+String STR_FORMAT_ID_NETSCAPE_BOOKMARK
+{
+ Text [ en-US ] = "Netscape Bookmark";
+};
+String STR_FORMAT_ID_STARSERVER
+{
+ Text [ en-US ] = "Star server format";
+};
+String STR_FORMAT_ID_STAROBJECT
+{
+ Text [ en-US ] = "Star object format";
+};
+String STR_FORMAT_ID_APPLETOBJECT
+{
+ Text [ en-US ] = "Applet object";
+};
+String STR_FORMAT_ID_PLUGIN_OBJECT
+{
+ Text [ en-US ] = "Plug-in object";
+};
+String STR_FORMAT_ID_STARWRITER_30
+{
+ Text [ en-US ] = "StarWriter 3.0 object";
+};
+String STR_FORMAT_ID_STARWRITER_40
+{
+ Text [ en-US ] = "StarWriter 4.0 object";
+};
+String STR_FORMAT_ID_STARWRITER_50
+{
+ Text [ en-US ] = "StarWriter 5.0 object";
+};
+String STR_FORMAT_ID_STARWRITERWEB_40
+{
+ Text [ en-US ] = "StarWriter/Web 4.0 object";
+};
+String STR_FORMAT_ID_STARWRITERWEB_50
+{
+ Text [ en-US ] = "StarWriter/Web 5.0 object";
+};
+String STR_FORMAT_ID_STARWRITERGLOB_40
+{
+ Text [ en-US ] = "StarWriter/Master 4.0 object";
+};
+String STR_FORMAT_ID_STARWRITERGLOB_50
+{
+ Text [ en-US ] = "StarWriter/Master 5.0 object";
+};
+String STR_FORMAT_ID_STARDRAW
+{
+ Text [ en-US ] = "StarDraw object";
+};
+String STR_FORMAT_ID_STARDRAW_40
+{
+ Text [ en-US ] = "StarDraw 4.0 object";
+};
+String STR_FORMAT_ID_STARIMPRESS_50
+{
+ Text [ en-US ] = "StarImpress 5.0 object";
+};
+String STR_FORMAT_ID_STARDRAW_50
+{
+ Text [ en-US ] = "StarDraw 5.0 object";
+};
+String STR_FORMAT_ID_STARCALC
+{
+ Text [ en-US ] = "StarCalc object";
+};
+String STR_FORMAT_ID_STARCALC_40
+{
+ Text [ en-US ] = "StarCalc 4.0 object";
+};
+String STR_FORMAT_ID_STARCALC_50
+{
+ Text [ en-US ] = "StarCalc 5.0 object";
+};
+String STR_FORMAT_ID_STARCHART
+{
+ Text [ en-US ] = "StarChart object";
+};
+String STR_FORMAT_ID_STARCHART_40
+{
+ Text [ en-US ] = "StarChart 4.0 object";
+};
+String STR_FORMAT_ID_STARCHART_50
+{
+ Text [ en-US ] = "StarChart 5.0 object";
+};
+String STR_FORMAT_ID_STARIMAGE
+{
+ Text [ en-US ] = "StarImage object";
+};
+String STR_FORMAT_ID_STARIMAGE_40
+{
+ Text [ en-US ] = "StarImage 4.0 object";
+};
+String STR_FORMAT_ID_STARIMAGE_50
+{
+ Text [ en-US ] = "StarImage 5.0 object";
+};
+String STR_FORMAT_ID_STARMATH
+{
+ Text [ en-US ] = "StarMath object";
+};
+String STR_FORMAT_ID_STARMATH_40
+{
+ Text [ en-US ] = "StarMath 4.0 object";
+};
+String STR_FORMAT_ID_STARMATH_50
+{
+ Text [ en-US ] = "StarMath 5.0 object";
+};
+String STR_FORMAT_ID_STAROBJECT_PAINTDOC
+{
+ Text [ en-US ] = "StarObject Paint object";
+};
+String STR_FORMAT_ID_HTML
+{
+ Text [ en-US ] = "HTML (HyperText Markup Language)";
+};
+String STR_FORMAT_ID_HTML_SIMPLE
+{
+ Text [ en-US ] = "HTML format";
+};
+String STR_FORMAT_ID_BIFF_5
+{
+ Text [ en-US ] = "Biff5 (Microsoft Excel 5.0/95)";
+};
+String STR_FORMAT_ID_BIFF_8
+{
+ Text [ en-US ] = "Biff8 (Microsoft Excel 97/2000/XP)";
+};
+String STR_FORMAT_ID_SYLK
+{
+ Text [ en-US ] = "Sylk";
+};
+String STR_FORMAT_ID_LINK
+{
+ Text [ en-US ] = "DDE link" ;
+};
+String STR_FORMAT_ID_DIF
+{
+ Text [ en-US ] = "DIF";
+};
+String STR_FORMAT_ID_MSWORD_DOC
+{
+ Text [ en-US ] = "Microsoft Word object";
+};
+String STR_FORMAT_ID_STAR_FRAMESET_DOC
+{
+ Text [ en-US ] = "StarFrameSet object";
+};
+String STR_FORMAT_ID_OFFICE_DOC
+{
+ Text [ en-US ] = "Office document object";
+};
+String STR_FORMAT_ID_NOTES_DOCINFO
+{
+ Text [ en-US ] = "Notes document info";
+};
+String STR_FORMAT_ID_SFX_DOC
+{
+ Text [ en-US ] = "Sfx document";
+};
+String STR_FORMAT_ID_STARCHARTDOCUMENT_50
+{
+ Text [ en-US ] = "StarChart 5.0 object";
+};
+String STR_FORMAT_ID_GRAPHOBJ
+{
+ Text [ en-US ] = "Graphic object";
+};
+String STR_FORMAT_ID_STARWRITER_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Writer object";
+};
+String STR_FORMAT_ID_STARWRITERWEB_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Writer/Web object";
+};
+String STR_FORMAT_ID_STARWRITERGLOB_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Writer/Master object";
+};
+String STR_FORMAT_ID_STARDRAW_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Draw object";
+};
+String STR_FORMAT_ID_STARIMPRESS_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Impress object";
+};
+String STR_FORMAT_ID_STARCALC_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Calc object";
+};
+String STR_FORMAT_ID_STARCHART_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Chart object";
+};
+String STR_FORMAT_ID_STARMATH_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION Math object";
+};
+String STR_FORMAT_ID_WMF
+{
+ Text [ en-US ] = "Windows metafile";
+};
+String STR_FORMAT_ID_DBACCESS_QUERY
+{
+ Text [ en-US ] = "Data source object";
+};
+String STR_FORMAT_ID_DBACCESS_TABLE
+{
+ Text [ en-US ] = "Data source table";
+};
+String STR_FORMAT_ID_DBACCESS_COMMAND
+{
+ Text [ en-US ] = "SQL query";
+};
+String STR_FORMAT_ID_DIALOG_60
+{
+ Text [ en-US ] = "%PRODUCTXMLFILEFORMATNAME %PRODUCTXMLFILEFORMATVERSION dialog";
+};
+String STR_FORMAT_ID_FILEGRPDESCRIPTOR
+{
+ Text [ en-US ] = "Link";
+};
+String STR_FORMAT_ID_HTML_NO_COMMENT
+{
+ Text [ en-US ] = "HTML format without comments";
+};
+
diff --git a/svtools/source/dialogs/insdlg.cxx b/svtools/source/dialogs/insdlg.cxx
new file mode 100644
index 000000000000..3f7700805995
--- /dev/null
+++ b/svtools/source/dialogs/insdlg.cxx
@@ -0,0 +1,389 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _INSDLG_CXX
+
+// include ---------------------------------------------------------------
+
+#include <svtools/insdlg.hxx>
+#include "sores.hxx"
+#include <svtools/svtdata.hxx>
+
+#include <tools/rc.hxx>
+#include <unotools/configmgr.hxx>
+#include <sot/clsids.hxx>
+#include <sot/stg.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+using namespace ::com::sun::star;
+
+//---------------------------------------------
+// this struct conforms to the Microsoft
+// OBJECTDESCRIPTOR -> see oleidl.h
+// (MS platform sdk)
+//---------------------------------------------
+
+struct OleObjectDescriptor
+{
+ sal_uInt32 cbSize;
+ ClsId clsid;
+ sal_uInt32 dwDrawAspect;
+ Size sizel;
+ Point pointl;
+ sal_uInt32 dwStatus;
+ sal_uInt32 dwFullUserTypeName;
+ sal_uInt32 dwSrcOfCopy;
+};
+
+/********************** SvObjectServerList ********************************
+**************************************************************************/
+PRV_SV_IMPL_OWNER_LIST( SvObjectServerList, SvObjectServer )
+
+/*************************************************************************
+|* SvObjectServerList::SvObjectServerList()
+|*
+|* Beschreibung
+*************************************************************************/
+const SvObjectServer * SvObjectServerList::Get( const String & rHumanName ) const
+{
+ for( ULONG i = 0; i < Count(); i++ )
+ {
+ if( rHumanName == GetObject( i ).GetHumanName() )
+ return &GetObject( i );
+ }
+ return NULL;
+}
+
+/*************************************************************************
+|* SvObjectServerList::SvObjectServerList()
+|*
+|* Beschreibung
+*************************************************************************/
+const SvObjectServer * SvObjectServerList::Get( const SvGlobalName & rName ) const
+{
+ for( ULONG i = 0; i < Count(); i++ )
+ {
+ if( rName == GetObject( i ).GetClassName() )
+ return &GetObject( i );
+ }
+ return NULL;
+}
+
+void SvObjectServerList::Remove( const SvGlobalName & rName )
+{
+ SvObjectServer * pS = (SvObjectServer *)aTypes.First();
+ while( pS )
+ {
+ if( rName == pS->GetClassName() )
+ {
+ Remove();
+ pS = (SvObjectServer *)aTypes.GetCurObject();
+ }
+ else
+ pS = (SvObjectServer *)aTypes.Next();
+ }
+}
+
+//---------------------------------------------------------------------
+void SvObjectServerList::FillInsertObjects()
+/* [Beschreibung]
+
+ Die Liste wird mit allen Typen gef"ullt, die im Insert-Dialog
+ ausgew"ahlt werden k"onnen.
+*/
+{
+ try{
+ uno::Reference< lang::XMultiServiceFactory > _globalMSFactory= comphelper::getProcessServiceFactory();
+ if( _globalMSFactory.is())
+ {
+ ::rtl::OUString sProviderService =
+ ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" );
+ uno::Reference< lang::XMultiServiceFactory > sProviderMSFactory(
+ _globalMSFactory->createInstance( sProviderService ), uno::UNO_QUERY );
+
+ if( sProviderMSFactory.is())
+ {
+ ::rtl::OUString sReaderService =
+ ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" );
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aPathProp;
+ aPathProp.Name = ::rtl::OUString::createFromAscii( "nodepath" );
+ aPathProp.Value <<= ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Embedding/ObjectNames");
+ aArguments[0] <<= aPathProp;
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ sProviderMSFactory->createInstanceWithArguments( sReaderService,aArguments ),
+ uno::UNO_QUERY );
+
+ if( xNameAccess.is())
+ {
+ uno::Sequence< ::rtl::OUString > seqNames= xNameAccess->getElementNames();
+ sal_Int32 nInd;
+
+ ::rtl::OUString aStringProductName( RTL_CONSTASCII_USTRINGPARAM( "%PRODUCTNAME" ) );
+ sal_Int32 nStringProductNameLength = aStringProductName.getLength();
+
+ ::rtl::OUString aStringProductVersion( RTL_CONSTASCII_USTRINGPARAM( "%PRODUCTVERSION" ) );
+ sal_Int32 nStringProductVersionLength = aStringProductVersion.getLength();
+
+ // TODO/LATER: Do the request only once ( needs incompatible change )
+ ::rtl::OUString aProductName;
+ ::rtl::OUString aProductVersion;
+ uno::Any aProperty =
+ ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ if ( !( aProperty >>= aProductName ) )
+ {
+ OSL_ENSURE( sal_False, "Coudn't get PRODUCTNAME variable!\n" );
+ aProductName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice" ) );
+ }
+ aProperty = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
+ if ( !( aProperty >>= aProductVersion ) )
+ {
+ OSL_ENSURE( sal_False, "Coudn't get PRODUCTVERSION variable!\n" );
+ }
+
+ for( nInd = 0; nInd < seqNames.getLength(); nInd++ )
+ {
+ uno::Reference< container::XNameAccess > xEntry ;
+ xNameAccess->getByName( seqNames[nInd] ) >>= xEntry;
+ if ( xEntry.is() )
+ {
+ ::rtl::OUString aUIName;
+ ::rtl::OUString aClassID;
+ xEntry->getByName( ::rtl::OUString::createFromAscii("ObjectUIName") ) >>= aUIName;
+ xEntry->getByName( ::rtl::OUString::createFromAscii("ClassID") ) >>= aClassID;
+
+ if ( aUIName.getLength() )
+ {
+ // replace %PRODUCTNAME
+ sal_Int32 nIndex = aUIName.indexOf( aStringProductName );
+ while( nIndex != -1 )
+ {
+ aUIName = aUIName.replaceAt( nIndex, nStringProductNameLength, aProductName );
+ nIndex = aUIName.indexOf( aStringProductName );
+ }
+
+ // replace %PRODUCTVERSION
+ nIndex = aUIName.indexOf( aStringProductVersion );
+ while( nIndex != -1 )
+ {
+ aUIName = aUIName.replaceAt( nIndex, nStringProductVersionLength, aProductVersion );
+ nIndex = aUIName.indexOf( aStringProductVersion );
+ }
+ }
+
+ SvGlobalName aClassName;
+ if( aClassName.MakeId( String( aClassID )))
+ {
+ if( !Get( aClassName ) )
+ // noch nicht eingetragen
+ Append( SvObjectServer( aClassName, String( aUIName.getStr() ) ) );
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+#ifdef WNT
+ SvGlobalName aOleFact( SO3_OUT_CLASSID );
+ String aOleObj( SvtResId( STR_FURTHER_OBJECT ) );
+ Append( SvObjectServer( aOleFact, aOleObj ) );
+#endif
+
+ }catch( container::NoSuchElementException)
+ {
+ }catch( uno::Exception)
+ {
+ }
+ catch(...)
+ {
+ }
+}
+
+String SvPasteObjectHelper::GetSotFormatUIName( SotFormatStringId nId )
+{
+ struct SotResourcePair
+ {
+ SotFormatStringId mnSotId;
+ USHORT mnResId;
+ };
+
+ static const SotResourcePair aSotResourcePairs[] =
+ {
+ { SOT_FORMAT_STRING, STR_FORMAT_STRING },
+ { SOT_FORMAT_BITMAP, STR_FORMAT_BITMAP },
+ { SOT_FORMAT_GDIMETAFILE, STR_FORMAT_GDIMETAFILE },
+ { SOT_FORMAT_RTF, STR_FORMAT_RTF },
+ { SOT_FORMATSTR_ID_DRAWING, STR_FORMAT_ID_DRAWING },
+ { SOT_FORMATSTR_ID_SVXB, STR_FORMAT_ID_SVXB },
+ { SOT_FORMATSTR_ID_INTERNALLINK_STATE, STR_FORMAT_ID_INTERNALLINK_STATE },
+ { SOT_FORMATSTR_ID_SOLK, STR_FORMAT_ID_SOLK },
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, STR_FORMAT_ID_NETSCAPE_BOOKMARK },
+ { SOT_FORMATSTR_ID_STARSERVER, STR_FORMAT_ID_STARSERVER },
+ { SOT_FORMATSTR_ID_STAROBJECT, STR_FORMAT_ID_STAROBJECT },
+ { SOT_FORMATSTR_ID_APPLETOBJECT, STR_FORMAT_ID_APPLETOBJECT },
+ { SOT_FORMATSTR_ID_PLUGIN_OBJECT, STR_FORMAT_ID_PLUGIN_OBJECT },
+ { SOT_FORMATSTR_ID_STARWRITER_30, STR_FORMAT_ID_STARWRITER_30 },
+ { SOT_FORMATSTR_ID_STARWRITER_40, STR_FORMAT_ID_STARWRITER_40 },
+ { SOT_FORMATSTR_ID_STARWRITER_50, STR_FORMAT_ID_STARWRITER_50 },
+ { SOT_FORMATSTR_ID_STARWRITERWEB_40, STR_FORMAT_ID_STARWRITERWEB_40 },
+ { SOT_FORMATSTR_ID_STARWRITERWEB_50, STR_FORMAT_ID_STARWRITERWEB_50 },
+ { SOT_FORMATSTR_ID_STARWRITERGLOB_40, STR_FORMAT_ID_STARWRITERGLOB_40 },
+ { SOT_FORMATSTR_ID_STARWRITERGLOB_50, STR_FORMAT_ID_STARWRITERGLOB_50 },
+ { SOT_FORMATSTR_ID_STARDRAW, STR_FORMAT_ID_STARDRAW },
+ { SOT_FORMATSTR_ID_STARDRAW_40, STR_FORMAT_ID_STARDRAW_40 },
+ { SOT_FORMATSTR_ID_STARIMPRESS_50, STR_FORMAT_ID_STARIMPRESS_50 },
+ { SOT_FORMATSTR_ID_STARDRAW_50, STR_FORMAT_ID_STARDRAW_50 },
+ { SOT_FORMATSTR_ID_STARCALC, STR_FORMAT_ID_STARCALC },
+ { SOT_FORMATSTR_ID_STARCALC_40, STR_FORMAT_ID_STARCALC_40 },
+ { SOT_FORMATSTR_ID_STARCALC_50, STR_FORMAT_ID_STARCALC_50 },
+ { SOT_FORMATSTR_ID_STARCHART, STR_FORMAT_ID_STARCHART },
+ { SOT_FORMATSTR_ID_STARCHART_40, STR_FORMAT_ID_STARCHART_40 },
+ { SOT_FORMATSTR_ID_STARCHART_50, STR_FORMAT_ID_STARCHART_50 },
+ { SOT_FORMATSTR_ID_STARIMAGE, STR_FORMAT_ID_STARIMAGE },
+ { SOT_FORMATSTR_ID_STARIMAGE_40, STR_FORMAT_ID_STARIMAGE_40 },
+ { SOT_FORMATSTR_ID_STARIMAGE_50, STR_FORMAT_ID_STARIMAGE_50 },
+ { SOT_FORMATSTR_ID_STARMATH, STR_FORMAT_ID_STARMATH },
+ { SOT_FORMATSTR_ID_STARMATH_40, STR_FORMAT_ID_STARMATH_40 },
+ { SOT_FORMATSTR_ID_STARMATH_50, STR_FORMAT_ID_STARMATH_50 },
+ { SOT_FORMATSTR_ID_STAROBJECT_PAINTDOC, STR_FORMAT_ID_STAROBJECT_PAINTDOC },
+ { SOT_FORMATSTR_ID_HTML, STR_FORMAT_ID_HTML },
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, STR_FORMAT_ID_HTML_SIMPLE },
+ { SOT_FORMATSTR_ID_BIFF_5, STR_FORMAT_ID_BIFF_5 },
+ { SOT_FORMATSTR_ID_BIFF_8, STR_FORMAT_ID_BIFF_8 },
+ { SOT_FORMATSTR_ID_SYLK, STR_FORMAT_ID_SYLK },
+ { SOT_FORMATSTR_ID_LINK, STR_FORMAT_ID_LINK },
+ { SOT_FORMATSTR_ID_DIF, STR_FORMAT_ID_DIF },
+ { SOT_FORMATSTR_ID_MSWORD_DOC, STR_FORMAT_ID_MSWORD_DOC },
+ { SOT_FORMATSTR_ID_STAR_FRAMESET_DOC, STR_FORMAT_ID_STAR_FRAMESET_DOC },
+ { SOT_FORMATSTR_ID_OFFICE_DOC, STR_FORMAT_ID_OFFICE_DOC },
+ { SOT_FORMATSTR_ID_NOTES_DOCINFO, STR_FORMAT_ID_NOTES_DOCINFO },
+ { SOT_FORMATSTR_ID_SFX_DOC, STR_FORMAT_ID_SFX_DOC },
+ { SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50,STR_FORMAT_ID_STARCHARTDOCUMENT_50 },
+ { SOT_FORMATSTR_ID_GRAPHOBJ, STR_FORMAT_ID_GRAPHOBJ },
+ { SOT_FORMATSTR_ID_STARWRITER_60, STR_FORMAT_ID_STARWRITER_60 },
+ { SOT_FORMATSTR_ID_STARWRITERWEB_60, STR_FORMAT_ID_STARWRITERWEB_60 },
+ { SOT_FORMATSTR_ID_STARWRITERGLOB_60, STR_FORMAT_ID_STARWRITERGLOB_60 },
+ { SOT_FORMATSTR_ID_STARDRAW_60, STR_FORMAT_ID_STARDRAW_60 },
+ { SOT_FORMATSTR_ID_STARIMPRESS_60, STR_FORMAT_ID_STARIMPRESS_60 },
+ { SOT_FORMATSTR_ID_STARCALC_60, STR_FORMAT_ID_STARCALC_60 },
+ { SOT_FORMATSTR_ID_STARCHART_60, STR_FORMAT_ID_STARCHART_60 },
+ { SOT_FORMATSTR_ID_STARMATH_60, STR_FORMAT_ID_STARMATH_60 },
+ { SOT_FORMATSTR_ID_WMF, STR_FORMAT_ID_WMF },
+ { SOT_FORMATSTR_ID_DBACCESS_QUERY, STR_FORMAT_ID_DBACCESS_QUERY },
+ { SOT_FORMATSTR_ID_DBACCESS_TABLE, STR_FORMAT_ID_DBACCESS_TABLE },
+ { SOT_FORMATSTR_ID_DBACCESS_COMMAND, STR_FORMAT_ID_DBACCESS_COMMAND },
+ { SOT_FORMATSTR_ID_DIALOG_60, STR_FORMAT_ID_DIALOG_60 },
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, STR_FORMAT_ID_FILEGRPDESCRIPTOR },
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, STR_FORMAT_ID_HTML_NO_COMMENT }
+ };
+
+ String aUIName;
+ USHORT nResId = 0;
+
+ for( sal_uInt32 i = 0, nCount = sizeof( aSotResourcePairs ) / sizeof( aSotResourcePairs[ 0 ] ); ( i < nCount ) && !nResId; i++ )
+ {
+ if( aSotResourcePairs[ i ].mnSotId == nId )
+ nResId = aSotResourcePairs[ i ].mnResId;
+ }
+
+ if( nResId )
+ aUIName = String( SvtResId( nResId ) );
+ else
+ aUIName = SotExchange::GetFormatName( nId );
+
+ return aUIName;
+}
+// -----------------------------------------------------------------------------
+sal_Bool SvPasteObjectHelper::GetEmbeddedName(const TransferableDataHelper& rData,String& _rName,String& _rSource,SotFormatStringId& _nFormat)
+{
+ sal_Bool bRet = sal_False;
+ if( _nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE || _nFormat == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
+ {
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE, aFlavor );
+
+ uno::Any aAny;
+ if( rData.HasFormat( aFlavor ) &&
+ ( aAny = rData.GetAny( aFlavor ) ).hasValue() )
+ {
+ uno::Sequence< sal_Int8 > anySequence;
+ aAny >>= anySequence;
+
+ OleObjectDescriptor* pOleObjDescr =
+ reinterpret_cast< OleObjectDescriptor* >( anySequence.getArray( ) );
+
+ // determine the user friendly description of the embedded object
+ if ( pOleObjDescr->dwFullUserTypeName )
+ {
+ // we set the pointer to the start of user friendly description
+ // string. it starts at &OleObjectDescriptor + dwFullUserTypeName.
+ // dwFullUserTypeName is the offset in bytes.
+ // the user friendly description string is '\0' terminated.
+ const sal_Unicode* pUserTypeName =
+ reinterpret_cast< sal_Unicode* >(
+ reinterpret_cast< sal_Char* >( pOleObjDescr ) +
+ pOleObjDescr->dwFullUserTypeName );
+
+ _rName.Append( pUserTypeName );
+ // the following statement was here for historical reasons, it is commented out since it causes bug i49460
+ // _nFormat = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
+ }
+
+ // determine the source of the embedded object
+ if ( pOleObjDescr->dwSrcOfCopy )
+ {
+ // we set the pointer to the start of source string
+ // it starts at &OleObjectDescriptor + dwSrcOfCopy.
+ // dwSrcOfCopy is the offset in bytes.
+ // the source string is '\0' terminated.
+ const sal_Unicode* pSrcOfCopy =
+ reinterpret_cast< sal_Unicode* >(
+ reinterpret_cast< sal_Char* >( pOleObjDescr ) +
+ pOleObjDescr->dwSrcOfCopy );
+
+ _rSource.Append( pSrcOfCopy );
+ }
+ else
+ _rSource =
+ String( SvtResId( STR_UNKNOWN_SOURCE ) );
+ }
+ bRet = sal_True;
+ }
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+
diff --git a/svtools/source/dialogs/makefile.mk b/svtools/source/dialogs/makefile.mk
new file mode 100755
index 000000000000..99c4b59b76ae
--- /dev/null
+++ b/svtools/source/dialogs/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=svtools
+TARGET=dialogs
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES= filedlg2.src \
+ so3res.src \
+ formats.src \
+ prnsetup.src \
+ printdlg.src \
+ colrdlg.src \
+ addresstemplate.src \
+ wizardmachine.src
+
+
+EXCEPTIONSFILES= $(SLO)$/addresstemplate.obj \
+ $(SLO)$/insdlg.obj \
+ $(SLO)$/roadmapwizard.obj \
+ $(SLO)$/printdlg.obj \
+ $(SLO)$/wizardmachine.obj
+
+
+SLOFILES= \
+ $(SLO)$/insdlg.obj \
+ $(SLO)$/roadmapwizard.obj \
+ $(SLO)$/wizardmachine.obj \
+ $(SLO)$/addresstemplate.obj \
+ $(SLO)$/filedlg.obj \
+ $(SLO)$/filedlg2.obj \
+ $(SLO)$/prnsetup.obj \
+ $(SLO)$/printdlg.obj \
+ $(SLO)$/colctrl.obj \
+ $(SLO)$/colrdlg.obj \
+ $(SLO)$/property.obj \
+ $(SLO)$/wizdlg.obj \
+ $(SLO)$/mcvmath.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/dialogs/mcvmath.cxx b/svtools/source/dialogs/mcvmath.cxx
new file mode 100644
index 000000000000..d07c41acba04
--- /dev/null
+++ b/svtools/source/dialogs/mcvmath.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_svtools.hxx"
+
+#include <mcvmath.hxx>
+
+// ---------------------------------------------------------------------
+// die folgenden Tabellen enthalten sin(phi) * 2**14
+// fuer phi= 360Grad*2**-32 bis 360 Grad
+// def. fuer x: phi=360Grad * 2**(x-16)
+// d.h. x = 16 -> 360 Grad
+// x = -16 -> (2**-16) * 360 Grad
+// x: -16 ... 0 ... 15
+//x= 0, 1, 2, 3, 4, 5, 6, 7,
+// 8, 9, 10, 11, 12, 13, 14, 15
+
+static const short CosTab[16] =
+{
+ 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16383,
+ 16379, 16364, 16305, 16069, 15137, 11585, 0, -16383
+};
+static const short SinTab[16]=
+{
+ 2, 3, 6, 13, 25, 50, 101, 201,
+ 402, 804, 1606, 3196, 6270, 11585, 16384, 0
+};
+
+/**************************************************************************
+|*
+|* ImpMultBig2()
+|*
+|* Beschreibung Multiplikation fuer FixPoint-Berechnungen
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+// first parameter should be the bigger one
+
+Fix ImpMultBig2( const Fix& a, const Fix& b )
+{
+ Fix f;
+ f.x = (((b.x+FIX_A2)>>FIX_P2)*a.x+FIX_A3)>>FIX_P3;
+ return f;
+}
+
+/**************************************************************************
+|*
+|* ImpMultBig2()
+|*
+|* Beschreibung Multiplikation fuer FixPoint-Berechnungen
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+// first parameter should be the bigger one
+
+FixCpx ImpMultBig2( const FixCpx& ra, const FixCpx& rb )
+{
+ Fix rr = ImpMultBig2(ra.r,rb.r)-ImpMultBig2(ra.i,rb.i);
+ Fix ii = ImpMultBig2(ra.r,rb.i)+ImpMultBig2(ra.i,rb.r);
+ return FixCpx( rr,ii );
+}
+
+/**************************************************************************
+|*
+|* ImpSqrt()
+|*
+|* Beschreibung Wurzelfunktion fuer FixPoint-Berechnungen
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+USHORT ImpSqrt( ULONG nRadi )
+{
+ register ULONG inf = 1;
+ register ULONG sup = nRadi;
+ register ULONG sqr;
+
+ if ( !nRadi )
+ return 0;
+
+ while ( (inf<<1) <= sup )
+ {
+ sup >>= 1;
+ inf <<= 1;
+ }
+ sqr = (sup+inf) >> 1; // Anfangswert der Iteration
+
+ sqr = (nRadi/sqr + sqr) >> 1; // 2 Newton-Iterationen reichen fuer
+ sqr = (nRadi/sqr + sqr) >> 1; // +- 1 Digit
+
+ return sal::static_int_cast< USHORT >(sqr);
+}
+
+/**************************************************************************
+|*
+|* ImpExPI()
+|*
+|* Beschreibung EXPI-Funktion fuer FixPoint-Berechnungen
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+// e**(i*nPhi), Einheit nPhi: 2**16 == 360 Grad
+
+FixCpx ImpExPI( USHORT nPhi )
+{
+ short i;
+ FixCpx aIter(1L); // e**(0*i)
+ FixCpx Mul;
+ const char Sft=14-FIX_POST;
+
+ for ( i = 15; i >= 0; i-- )
+ {
+ if ( (1L<<i) & nPhi )
+ {
+ Mul.r.x = CosTab[i]>>Sft; // e**(i(phi1+phi2)) =
+ Mul.i.x = SinTab[i]>>Sft; // e**(i*phi1)) * e**(i*phi2))
+ aIter *= Mul;
+ }
+ }
+
+ return aIter;
+}
+
+/**************************************************************************
+|*
+|* ImpATanx2()
+|*
+|* Beschreibung ATANX2-Funktion fuer FixPoint-Berechnungen
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+// use for x*x+y*y==1 only
+
+static USHORT ImpATanx2( const Fix& rX, const Fix& rY )
+{
+ USHORT phi0 = 0; // result angel higher part
+ USHORT phi = 0; // dito lower part
+ long x = rX.x;
+ long y = rY.x;
+ long z;
+ const char Sft=14-FIX_POST;
+ short i;
+ FixCpx aTry;
+ FixCpx aInc;
+ FixCpx aIter(1L);
+ BOOL Small = FALSE;
+
+ if ( (x==0) && (y==0) )
+ return 0;
+
+ if ( y < 0)
+ {
+ // reduce 3. to 1. quadrant (0..90 Degree)
+ phi0 += 180L * 65536L / 360L;
+ // turn 180 degree
+ y *= -1;
+ x *= -1;
+ }
+
+ if ( x < 0)
+ {
+ // 2. to 1. q.
+ phi0 += 90L * 65536L / 360L;
+ // turn 90 degree clockwise
+ z = y;
+ y = -x;
+ x = z;
+ }
+
+ for ( i = 13; i >= 0; i-- )
+ {
+ aInc.r.x = CosTab[i]>>Sft; // e**(i(phi1+phi2)) =
+ aInc.i.x = SinTab[i]>>Sft; // e**(i*phi1)) * e**(i*phi2))
+ aTry = aIter*aInc;
+
+ if ( Small )
+ {
+ // is try ok
+ if ( aTry.r.x >= x )
+ {
+ aIter = aTry;
+ phi += (1<<i);
+ }
+ }
+ else
+ {
+ // is try ok
+ if ( aTry.i.x <= y )
+ {
+ aIter = aTry;
+ phi += (1<<i);
+
+ if ( i > 11 )
+ Small=TRUE;
+ }
+ }
+ }
+
+ return phi0+phi;
+}
+
+/**************************************************************************
+|*
+|* ImpATan2()
+|*
+|* Beschreibung ATAN-Funktion fuer FixPoint-Berechnungen
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+USHORT ImpATan2( const short x, const short y )
+{
+ Fix rRad = ImpSqrt(ULONG(long(x)*x+long(y)*y));
+
+ if ( !rRad.x )
+ return 0;
+ Fix fx = x;
+ fx.DivBig( rRad ); // Normiere auf Einheitskreis
+ Fix fy = y;
+ fy.DivBig( rRad );
+
+ return ImpATanx2( fx, fy );
+}
+
+/**************************************************************************
+|*
+|* ImpCartToPolar()
+|*
+|* Beschreibung Koordinaaten-Wandlung
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+void ImpCartToPolar( const short x, const short y, Fix& rRad, USHORT& rPhi )
+{
+ rRad = Fix( ImpSqrt( ULONG( long(x)*x+long(y)*y ) ) );
+
+ if ( !rRad.x )
+ rPhi=0;
+ else
+ {
+ // Normiere auf Einheitskreis
+ Fix fx = x;
+ fx.DivBig(rRad);
+ Fix fy = y;
+ fy.DivBig(rRad);
+ rPhi = ImpATanx2(fx, fy);
+ }
+}
+
+/**************************************************************************
+|*
+|* ImpPolarToCart()
+|*
+|* Beschreibung Koordinaaten-Wandlung
+|* Ersterstellung SH 01.07.93
+|* Letzte Aenderung SH 01.07.93
+|*
+**************************************************************************/
+
+void ImpPolarToCart( const Fix& rR, const USHORT Phi, short& rX, short& rY )
+{
+ FixCpx fc = ImpExPI( Phi ); // calculate sin() & cos()
+ fc.GetReal().MultBig( rR );
+ rX = sal::static_int_cast< short >(long( fc.GetReal() ));
+ fc.GetImag().MultBig( rR );
+ rY = sal::static_int_cast< short >(long( fc.GetImag() ));
+}
+
diff --git a/svtools/source/dialogs/mcvmath.hxx b/svtools/source/dialogs/mcvmath.hxx
new file mode 100644
index 000000000000..67d54fd80cf0
--- /dev/null
+++ b/svtools/source/dialogs/mcvmath.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 _MCVMATH_HXX
+#define _MCVMATH_HXX
+
+#include <tools/solar.h>
+
+class FixCpx;
+class ColWheel;
+
+// No of fractal bits
+// allowed range 0..14, must be even
+#define FIX_POST 14
+
+// scale for ...Big() -Functions
+#if (FIX_POST>=4)
+#define FIX_P2 4
+#define FIX_P3 (FIX_POST-FIX_P2)
+#else
+#define FIX_P2 0
+#define FIX_P3 FIX_POST
+#endif
+
+#if (FIX_POST>=1)
+#define FIX_ADD (1<<(FIX_POST-1))
+#else
+#define FIX_ADD 0
+#endif
+
+#if (FIX_P2>=1)
+#define FIX_A2 (1<<(FIX_P2-1))
+#else
+#define FIX_A2 0
+#endif
+
+#if (FIX_P3>=1)
+#define FIX_A3 (1<<(FIX_P3-1))
+#else
+#define FIX_A3 0
+#endif
+
+// -------
+// - Fix -
+// -------
+
+class Fix
+{
+private:
+ friend class FixCpx;
+ friend class ColWheel;
+
+// friend Fix ImpMultBig2( const Fix& a, const Fix& b );
+
+public:
+ long x;
+
+public:
+ Fix() { x=0; }
+ Fix( int i ) { x=(long(i)<<FIX_POST); }
+ Fix( short l ) { x=(long(l)<<FIX_POST); }
+ Fix( USHORT l ) { x=(long(l)<<FIX_POST); }
+ Fix( long l ) { x=(l<<FIX_POST); }
+ Fix( long Z, long N ) { x=(Z<<FIX_POST)/N; }
+
+ void SetInternVal( long nVal ) { x=nVal; }
+ long GetInternVal() const { return x; }
+
+ void operator+= ( const Fix& a ) { x+=a.x; }
+ void operator-= ( const Fix& a ) { x-=a.x; }
+ void operator*= ( const Fix& a ) { x=(x*a.x+FIX_ADD)>>FIX_POST; }
+ void operator/= ( const Fix& a ) { x=(x<<FIX_POST)/a.x; }
+ friend Fix operator- ( const Fix& a );
+
+ void MultBig( const Fix& a )
+ { x=((((a.x+FIX_A2)>>FIX_P2)*x+FIX_A3)>>FIX_P3); }
+ void DivBig( const Fix& a )
+ { x=((x<<FIX_P3)/a.x)<<FIX_P2; }
+
+ friend BOOL operator> ( const Fix& a, const Fix& b ) { return a.x > b.x; }
+ friend BOOL operator< ( const Fix& a, const Fix& b ) { return a.x < b.x; }
+
+ operator long() const { return (x+FIX_ADD) >> FIX_POST; }
+ operator double() const { return double(x)/(1<<FIX_POST); }
+
+ friend Fix operator+ ( const Fix& a, const Fix& b );
+ friend Fix operator- ( const Fix& a, const Fix& b );
+ friend Fix operator* ( const Fix& a, const Fix& b );
+ friend Fix operator/ ( const Fix& a, const Fix& b );
+
+ friend FixCpx operator-( const FixCpx& a );
+};
+
+// ----------
+// - FixCpx -
+// ----------
+
+class FixCpx
+{
+// friend FixCpx ImpMultBig2( const FixCpx& ra, const FixCpx& rb );
+
+public:
+ Fix r;
+ Fix i;
+
+public:
+ FixCpx() : r(), i() {}
+ FixCpx( Fix a ) : r( a ), i() {}
+ FixCpx( Fix a, Fix b ) : r( a ), i( b ) {}
+
+ Fix& GetReal() { return r; }
+ Fix& GetImag() { return i; }
+
+ void operator*= ( const FixCpx& ra );
+ void MultBig( const FixCpx& ra, const FixCpx& rb );
+
+ friend FixCpx operator+ ( const FixCpx& a, const FixCpx& b );
+ friend FixCpx operator- ( const FixCpx& a, const FixCpx& b );
+ friend FixCpx operator* ( const FixCpx& a, const FixCpx& b );
+ friend FixCpx operator/ ( const FixCpx& a, const FixCpx& b );
+ friend FixCpx operator- ( const FixCpx& a );
+};
+
+inline Fix operator- ( const Fix& a )
+{
+ Fix f;
+ f.x = -a.x;
+ return f;
+}
+
+inline Fix operator+ ( const Fix& a, const Fix& b )
+{
+ long l = a.x+b.x;
+ return *((Fix*)&l);
+}
+
+inline Fix operator- ( const Fix& a, const Fix& b )
+{
+ long l = a.x-b.x;
+ return *((Fix*)&l);
+}
+
+inline Fix operator* ( const Fix& a, const Fix& b )
+{
+ long l=(a.x*b.x+FIX_ADD)>>FIX_POST;
+ return *((Fix*)&l);
+}
+
+inline Fix operator/ ( const Fix& a, const Fix& b )
+{
+ long l=(a.x<<FIX_POST)/b.x;
+ return *((Fix*)&l);
+}
+
+inline FixCpx operator- ( const FixCpx& a )
+{
+ FixCpx fc;
+
+ fc.r.x = -a.r.x;
+ fc.i.x = -a.i.x;
+ return fc;
+}
+
+inline FixCpx operator+ ( const FixCpx& a, const FixCpx& b )
+{
+ return FixCpx( a.r+b.r, a.i+b.i );
+}
+
+inline FixCpx operator- ( const FixCpx& a, const FixCpx& b )
+{
+ return FixCpx( a.r-b.r, a.i-b.i );
+}
+
+inline void FixCpx::operator*= ( const FixCpx& ra )
+{
+ Fix rr = ra.r*r-ra.i*i;
+ i = ra.r*i+ra.i*r;
+ r = rr;
+}
+
+inline FixCpx operator* ( const FixCpx& a, const FixCpx& b )
+{
+ return FixCpx( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r );
+}
+
+inline FixCpx operator/ ( const FixCpx& a, const FixCpx& b )
+{
+ return FixCpx( (a.r*b.r+a.i*b.i)/(b.r*b.r+b.i*b.i),
+ (b.r*a.r-a.r*b.i)/(b.r*b.r+b.i*b.i) );
+}
+
+// -----------------------------------------------------------------------
+
+Fix ImpMultBig2( const Fix& a, const Fix& b );
+FixCpx ImpMultBig2( const FixCpx& ra, const FixCpx& rb );
+
+void ImpCartToPolar( const short x, const short y, Fix& rRad, USHORT& rPhi );
+void ImpPolarToCart( const Fix& rR, const USHORT Phi, short& rX, short& rY );
+
+USHORT ImpSqrt( ULONG nRadi );
+USHORT ImpATan2( const short x, const short y );
+FixCpx ImpExPI( USHORT nPhi );
+
+#endif // _MCVMATH_HXX
diff --git a/svtools/source/dialogs/printdlg.cxx b/svtools/source/dialogs/printdlg.cxx
new file mode 100644
index 000000000000..532fd3f61bb2
--- /dev/null
+++ b/svtools/source/dialogs/printdlg.cxx
@@ -0,0 +1,798 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <tools/debug.hxx>
+#ifndef _SV_APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _VCL_PRINT_HXX
+#include <vcl/print.hxx>
+#endif
+#include <vcl/msgbox.hxx>
+#include <vcl/jobset.hxx>
+#include <tools/urlobj.hxx>
+
+#include "printdlg.hrc"
+#include "controldims.hrc"
+#include <svtools/prnsetup.hxx>
+#include <svtools/printdlg.hxx>
+#include <svtools/svtdata.hxx>
+#include <filedlg.hxx>
+#include "svl/pickerhelper.hxx"
+#ifndef _SVT_HELPID_HRC
+#include <svtools/helpid.hrc>
+#endif
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+
+using rtl::OUString;
+using namespace com::sun::star;
+
+struct SvtPrinterImpl
+{
+ Printer* m_pTempPrinter;
+ sal_Bool m_bHelpDisabled;
+ PrintSheetRange m_eSheetRange;
+
+ SvtPrinterImpl() :
+ m_pTempPrinter( NULL ), m_bHelpDisabled( sal_False ), m_eSheetRange( PRINTSHEETS_ALL ) {}
+ ~SvtPrinterImpl() { delete m_pTempPrinter; }
+};
+
+#define TEMPPRINTER() mpPrinterImpl->m_pTempPrinter
+
+// =======================================================================
+
+PrintDialog::PrintDialog( Window* pWindow, bool bWithSheetsAndCells ) :
+ ModalDialog ( pWindow, SvtResId( DLG_SVT_PRNDLG_PRINTDLG ) ),
+ maFlPrinter ( this, SvtResId( FL_PRINTER ) ),
+ maFtName ( this, SvtResId( FT_NAME ) ),
+ maLbName ( this, SvtResId( LB_NAMES ) ),
+ maBtnProperties ( this, SvtResId( BTN_PROPERTIES ) ),
+ maFtStatus ( this, SvtResId( FT_STATUS ) ),
+ maFiStatus ( this, SvtResId( FI_STATUS ) ),
+ maFtType ( this, SvtResId( FT_TYPE ) ),
+ maFiType ( this, SvtResId( FI_TYPE ) ),
+ maFtLocation ( this, SvtResId( FT_LOCATION ) ),
+ maFiLocation ( this, SvtResId( FI_LOCATION ) ),
+ maFtComment ( this, SvtResId( FT_COMMENT ) ),
+ maFiComment ( this, SvtResId( FI_COMMENT ) ),
+ maCbxFilePrint ( this, SvtResId( CBX_FILEPRINT ) ),
+ maFiPrintFile ( this, SvtResId( FI_PRINTFILE ) ),
+ maFiFaxNo ( this, SvtResId( FI_FAXNO ) ),
+ maEdtFaxNo ( this, SvtResId( EDT_FAXNO ) ),
+ maFlPrint ( this, SvtResId( FL_PRINT ) ),
+ maRbtAllSheets ( this, SvtResId( RBT_ALL_SHEETS ) ),
+ maRbtSelectedSheets ( this, SvtResId( RBT_SELECTED_SHEETS ) ),
+ maRbtSelectedCells ( this, SvtResId( RBT_SELECTED_CELLS ) ),
+ maFlPrintRange ( this, SvtResId( FL_PRINTRANGE ) ),
+ maRbtAll ( this, SvtResId( RBT_ALL ) ),
+ maRbtPages ( this, SvtResId( RBT_PAGES ) ),
+ maRbtSelection ( this, SvtResId( RBT_SELECTION ) ),
+ maEdtPages ( this, SvtResId( EDT_PAGES ) ),
+ maFlSepCopiesRange ( this, SvtResId( FL_SEPCOPIESRANGE ) ),
+ maFlCopies ( this, SvtResId( FL_COPIES ) ),
+ maFtCopies ( this, SvtResId( FT_COPIES ) ),
+ maNumCopies ( this, SvtResId( NUM_COPIES ) ),
+ maImgCollate ( this, SvtResId( IMG_COLLATE ) ),
+ maImgNotCollate ( this, SvtResId( IMG_NOT_COLLATE ) ),
+ maCbxCollate ( this, SvtResId( CBX_COLLATE ) ),
+ maFlSepButtonLine ( this, SvtResId( FL_SEPBUTTONLINE ) ),
+ maBtnOptions ( this, SvtResId( BTN_OPTIONS ) ),
+ maBtnOK ( this, SvtResId( BTN_OK ) ),
+ maBtnCancel ( this, SvtResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, SvtResId( BTN_HELP ) ),
+ mbWithSheetsAndCells( bWithSheetsAndCells ),
+ maAllFilterStr ( SvtResId( STR_ALLFILTER ) )
+
+{
+ FreeResource();
+
+ mpPrinter = NULL;
+ mpPrinterImpl = new SvtPrinterImpl;
+ mnCopyCount = 1;
+ mnFirstPage = 0;
+ mnLastPage = 0;
+ mnMinPage = 1;
+ mnMaxPage = 65535;
+ meCheckRange = PRINTDIALOG_ALL;
+ mbAll = TRUE;
+ mbSelection = FALSE;
+ mbFromTo = FALSE;
+ mbRange = FALSE;
+ mbCollate = TRUE;
+ mbCollateCheck = TRUE;
+ mbOptions = FALSE;
+
+ maStatusTimer.SetTimeout( IMPL_PRINTDLG_STATUS_UPDATE );
+ maStatusTimer.SetTimeoutHdl( LINK( this, PrintDialog, ImplStatusHdl ) );
+ maBtnProperties.SetClickHdl( LINK( this, PrintDialog, ImplPropertiesHdl ) );
+ maLbName.SetSelectHdl( LINK( this, PrintDialog, ImplChangePrinterHdl ) );
+
+ maFiPrintFile.SetStyle( maFiPrintFile.GetStyle() | WB_PATHELLIPSIS );
+
+ Link aLink( LINK( this, PrintDialog, ImplModifyControlHdl ) );
+ maCbxFilePrint.SetClickHdl( aLink );
+ maRbtAll.SetClickHdl( aLink );
+ maRbtPages.SetClickHdl( aLink );
+ maRbtSelection.SetClickHdl( aLink );
+ maEdtPages.SetModifyHdl( aLink );
+ maNumCopies.SetModifyHdl( aLink );
+ maCbxCollate.SetClickHdl( aLink );
+ maBtnOptions.SetClickHdl( aLink );
+ maEdtFaxNo.SetModifyHdl( aLink );
+ maBtnOK.SetClickHdl( aLink );
+
+ maRbtAll.Check();
+ ImplSetImages();
+}
+
+// -----------------------------------------------------------------------
+
+PrintDialog::~PrintDialog()
+{
+ ImplFreePrnDlgListBox( &maLbName, FALSE );
+ delete mpPrinterImpl;
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::ImplSetImages()
+{
+ if( ! GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ maImgCollate.SetModeImage( Image( SvtResId( RID_IMG_PRNDLG_COLLATE ) ), BMP_COLOR_NORMAL );
+ maImgNotCollate.SetModeImage( Image( SvtResId( RID_IMG_PRNDLG_NOCOLLATE ) ), BMP_COLOR_NORMAL );
+ }
+ else
+ {
+ maImgCollate.SetModeImage( Image( SvtResId( RID_IMG_PRNDLG_COLLATE_HC ) ), BMP_COLOR_HIGHCONTRAST );
+ maImgNotCollate.SetModeImage( Image( SvtResId( RID_IMG_PRNDLG_NOCOLLATE_HC ) ), BMP_COLOR_HIGHCONTRAST );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::ImplSetInfo()
+{
+ const QueueInfo* pInfo = Printer::GetQueueInfo( maLbName.GetSelectEntry(), true );
+ if ( pInfo )
+ {
+ maFiType.SetText( pInfo->GetDriver() );
+ maFiLocation.SetText( pInfo->GetLocation() );
+ maFiComment.SetText( pInfo->GetComment() );
+ maFiStatus.SetText( ImplPrnDlgGetStatusText( *pInfo ) );
+ }
+ else
+ {
+ XubString aTempStr;
+ maFiType.SetText( aTempStr );
+ maFiLocation.SetText( aTempStr );
+ maFiComment.SetText( aTempStr );
+ maFiStatus.SetText( aTempStr );
+ }
+
+#ifdef UNX
+ if( pInfo && pInfo->GetLocation().EqualsAscii( "fax_queue" ) )
+ {
+ maFiPrintFile.Show( FALSE );
+ maCbxFilePrint.Show( FALSE );
+ maFiFaxNo.Show( TRUE );
+ maEdtFaxNo.Show( TRUE );
+ Printer* pPrinter = TEMPPRINTER() ? TEMPPRINTER() : mpPrinter;
+ maEdtFaxNo.SetText( pPrinter->GetJobValue( String::CreateFromAscii( "FAX#" ) ) );
+
+ Size aFTSize = maFiFaxNo.GetSizePixel();
+ long nTextWidth = maFiFaxNo.GetCtrlTextWidth( maFiFaxNo.GetText() ) + 10;
+ if ( aFTSize.Width() < nTextWidth )
+ {
+ long nDelta = nTextWidth - aFTSize.Width();
+ aFTSize.Width() = aFTSize.Width() + nDelta;
+ maFiFaxNo.SetSizePixel( aFTSize );
+ Size aEdtSize = maEdtFaxNo.GetSizePixel();
+ aEdtSize.Width() = aEdtSize.Width() - nDelta;
+ Point aEdtPos = maEdtFaxNo.GetPosPixel();
+ aEdtPos.X() = aEdtPos.X() + nDelta;
+ maEdtFaxNo.SetPosSizePixel( aEdtPos, aEdtSize );
+ }
+ }
+ else
+#endif
+ {
+ maFiPrintFile.Show( TRUE );
+ maCbxFilePrint.Show( TRUE );
+ maFiFaxNo.Show( FALSE );
+ maEdtFaxNo.Show( FALSE );
+ }
+
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::ImplCheckOK()
+{
+ // Ueberprueft, ob der OK-Button enabled ist
+ BOOL bEnable = TRUE;
+
+ if ( bEnable && maRbtPages.IsChecked() )
+ bEnable = maEdtPages.GetText().Len() > 0;
+
+ if ( bEnable )
+ {
+ if ( TEMPPRINTER() )
+ bEnable = TEMPPRINTER()->IsValid();
+ else
+ bEnable = mpPrinter->IsValid();
+ }
+
+ maBtnOK.Enable( bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::ImplInitControls()
+{
+ // Alles
+ if ( mbAll )
+ {
+ maRbtAll.Enable();
+ if( meCheckRange == PRINTDIALOG_ALL )
+ maRbtAll.Check( TRUE );
+ }
+ else
+ maRbtAll.Enable( FALSE );
+
+ // Selektion
+ if ( mbSelection )
+ {
+ maRbtSelection.Enable();
+ if ( meCheckRange == PRINTDIALOG_SELECTION )
+ maRbtSelection.Check( TRUE );
+ }
+ else
+ maRbtSelection.Enable( FALSE );
+
+ // Seiten
+ if ( mbRange )
+ {
+ maRbtPages.Enable();
+ maEdtPages.Show();
+ maEdtPages.SetText( maRangeText );
+
+ if( ( meCheckRange == PRINTDIALOG_FROMTO ) ||
+ ( meCheckRange == PRINTDIALOG_RANGE ) )
+ {
+ maRbtPages.Check( TRUE );
+ maEdtPages.Enable();
+ }
+ else
+ maEdtPages.Enable( FALSE );
+ }
+ else
+ {
+ maRbtPages.Enable( FALSE );
+ maEdtPages.Hide();
+ }
+
+ // Anzahl Kopien
+ maNumCopies.SetValue( mnCopyCount );
+
+ // Sortierung
+ maCbxCollate.Enable( mbCollate );
+ maCbxCollate.Check( mbCollateCheck );
+
+ // Zusaetze-Button
+ if ( mbOptions )
+ maBtnOptions.Show();
+
+ if ( !mbWithSheetsAndCells )
+ {
+ Size aMarginSize =
+ LogicToPixel( Size( RSC_SP_CTRL_GROUP_X, RSC_SP_CTRL_GROUP_Y ), MAP_APPFONT );
+ long nTempPos = maImgCollate.GetPosPixel().Y() +
+ maImgCollate.GetSizePixel().Height() + aMarginSize.Height();
+ long nDelta1 = maFlPrintRange.GetPosPixel().Y() - maFlPrint.GetPosPixel().Y();
+ long nDelta2 = maFlSepButtonLine.GetPosPixel().Y() - nTempPos;
+
+ maFlPrint.Hide();
+ maRbtAllSheets.Hide();
+ maRbtSelectedSheets.Hide();
+ maRbtSelectedCells.Hide();
+ maRbtSelection.Show();
+
+ Size aNewSize = GetSizePixel();
+ aNewSize.Height() -= nDelta2;
+ SetSizePixel( aNewSize );
+ aNewSize = maFlSepCopiesRange.GetSizePixel();
+ aNewSize.Height() -= nDelta2;
+ maFlSepCopiesRange.SetSizePixel( aNewSize );
+
+ long nDelta = nDelta1;
+ Window* pControls[] = { &maFlPrintRange, &maRbtAll,
+ &maRbtPages, &maEdtPages, &maRbtSelection, NULL,
+ &maFlSepButtonLine, &maBtnOptions, &maBtnOK,
+ &maBtnCancel, &maBtnHelp };
+ Window** pCtrl = pControls;
+ const sal_Int32 nCount = sizeof( pControls ) / sizeof( pControls[0] );
+ for ( sal_Int32 i = 0; i < nCount; ++i, ++pCtrl )
+ {
+ if ( NULL == *pCtrl )
+ {
+ nDelta = nDelta2;
+ continue;
+ }
+ Point aNewPos = (*pCtrl)->GetPosPixel();
+ aNewPos.Y() -= nDelta;
+ (*pCtrl)->SetPosPixel( aNewPos );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::ImplFillDialogData()
+{
+ if ( maRbtAll.IsChecked() )
+ meCheckRange = PRINTDIALOG_ALL;
+ else if( maRbtSelection.IsChecked() )
+ meCheckRange = PRINTDIALOG_SELECTION;
+ else
+ {
+ meCheckRange = PRINTDIALOG_RANGE;
+ maRangeText = maEdtPages.GetText();
+ }
+
+ mnCopyCount = (USHORT) maNumCopies.GetValue();
+ mbCollateCheck = maCbxCollate.IsChecked();
+
+ // In Datei drucken
+ if ( maCbxFilePrint.IsChecked() )
+ mpPrinter->SetPrintFile( maFiPrintFile.GetText() );
+ mpPrinter->EnablePrintFile( maCbxFilePrint.IsChecked() );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrintDialog, ImplStatusHdl, Timer*, EMPTYARG )
+{
+ QueueInfo aInfo;
+ ImplPrnDlgUpdateQueueInfo( &maLbName, aInfo );
+ maFiStatus.SetText( ImplPrnDlgGetStatusText( aInfo ) );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrintDialog, ImplPropertiesHdl, void*, EMPTYARG )
+{
+ if ( !TEMPPRINTER() )
+ TEMPPRINTER() = new Printer( mpPrinter->GetJobSetup() );
+ TEMPPRINTER()->Setup( this );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrintDialog, ImplChangePrinterHdl, void*, EMPTYARG )
+{
+ TEMPPRINTER() = ImplPrnDlgListBoxSelect( &maLbName, &maBtnProperties,
+ mpPrinter, TEMPPRINTER() );
+ ImplSetInfo();
+ ImplCheckOK(); // Check if "OK" button can be enabled now!
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+bool PrintDialog::ImplGetFilename()
+{
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ static ::rtl::OUString aOldFile;
+ if( xFactory.is() )
+ {
+ uno::Sequence< uno::Any > aTempl( 1 );
+ aTempl.getArray()[0] <<= ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION;
+ uno::Reference< ui::dialogs::XFilePicker > xFilePicker(
+ xFactory->createInstanceWithArguments(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ),
+ aTempl ), uno::UNO_QUERY );
+ DBG_ASSERT( xFilePicker.is(), "could not get FilePicker service" );
+
+ uno::Reference< ui::dialogs::XFilterManager > xFilterMgr( xFilePicker, uno::UNO_QUERY );
+ if( xFilePicker.is() && xFilterMgr.is() )
+ {
+ try
+ {
+#ifdef UNX
+ // add PostScript and PDF
+ Printer* pPrinter = TEMPPRINTER() ? TEMPPRINTER() : mpPrinter;
+ bool bPS = true, bPDF = true;
+ if( pPrinter )
+ {
+ if( pPrinter->GetCapabilities( PRINTER_CAPABILITIES_PDF ) )
+ bPS = false;
+ else
+ bPDF = false;
+ }
+ if( bPS )
+ xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PostScript" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.ps" ) ) );
+ if( bPDF )
+ xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Portable Document Format" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.pdf" ) ) );
+#elif defined WNT
+ xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.PRN" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.prn" ) ) );
+#endif
+ // add arbitrary files
+ xFilterMgr->appendFilter( maAllFilterStr, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.*" ) ) );
+ }
+ catch( lang::IllegalArgumentException rExc )
+ {
+ DBG_ERRORFILE( "caught IllegalArgumentException when registering filter\n" );
+ }
+
+ if( aOldFile.getLength() )
+ {
+ INetURLObject aUrl( aOldFile, INET_PROT_FILE );
+ xFilePicker->setDefaultName( aUrl.GetLastName() );
+ aUrl.CutLastName();
+ xFilePicker->setDisplayDirectory( aUrl.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+
+ if( xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK )
+ {
+ uno::Sequence< ::rtl::OUString > aPathSeq( xFilePicker->getFiles() );
+ INetURLObject aObj( aPathSeq[0] );
+ maFiPrintFile.SetText( aOldFile = aObj.PathToFileName() );
+ return true;
+ }
+ return false;
+ }
+ }
+
+ // something went awry, lets try the old fashioned dialogue
+ Window* pDlgParent = IsReallyVisible() ? this : GetParent();
+ FileDialog aDlg( pDlgParent, WB_STDDIALOG | WB_SAVEAS );
+#ifdef WNT
+ aDlg.AddFilter( String( RTL_CONSTASCII_USTRINGPARAM( "*.prn" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "*.prn" ) ) );
+ aDlg.SetDefaultExt( String( RTL_CONSTASCII_USTRINGPARAM( "prn" ) ) );
+#elif defined UNX
+ aDlg.AddFilter( String( RTL_CONSTASCII_USTRINGPARAM( "PostScript" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "*.ps" ) ) );
+ aDlg.SetDefaultExt( String( RTL_CONSTASCII_USTRINGPARAM( "ps" ) ) );
+#endif
+
+ if( aOldFile.getLength() )
+ aDlg.SetPath( aOldFile );
+
+ if( aDlg.Execute() )
+ {
+ String aTargetFile = aDlg.GetPath();
+ maFiPrintFile.SetText( aOldFile = aTargetFile );
+ return true;
+ }
+
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrintDialog, ImplModifyControlHdl, void*, p )
+{
+ // Radiobuttons (Umfang)
+ if ( !p || (p == &maRbtAll) || (p == &maRbtPages) || (p == &maRbtSelection) )
+ {
+ BOOL bCheck = maRbtPages.IsChecked();
+ maEdtPages.Enable( bCheck );
+ if ( p == &maRbtPages )
+ maEdtPages.GrabFocus();
+ ImplCheckOK();
+ }
+
+ // Edit-Felder (Seiten)
+ if ( p == &maEdtPages )
+ ImplCheckOK();
+
+ if( p == &maEdtFaxNo )
+ {
+ Printer* pPrinter = TEMPPRINTER() ? TEMPPRINTER() : mpPrinter;
+ pPrinter->SetJobValue( String::CreateFromAscii( "FAX#" ), maEdtFaxNo.GetText() );
+ }
+
+ // Anzahl Kopien
+ BOOL bNumCopies = FALSE;
+
+ if ( !p || p == &maNumCopies )
+ {
+ if ( p )
+ bNumCopies = TRUE;
+ //BOOL bCopies = maNumCopies.GetValue() > 1;
+ maCbxCollate.Enable( mbCollate );
+
+ /*if ( !bCopies )
+ maCbxCollate.Check( FALSE );
+ else*/
+ if ( mbCollateCheck )
+ maCbxCollate.Check( TRUE );
+ }
+
+ // Sortieren
+ if ( !p || p == &maCbxCollate || bNumCopies )
+ {
+ BOOL bCheck = maCbxCollate.IsChecked();
+
+ if ( !bNumCopies )
+ mbCollateCheck = maCbxCollate.IsChecked();
+
+ if( bCheck )
+ {
+ maImgCollate.Show();
+ maImgNotCollate.Hide();
+ }
+ else
+ {
+ maImgCollate.Hide();
+ maImgNotCollate.Show();
+ }
+ }
+
+ // Zus"atze
+ if ( p == &maBtnOptions )
+ ClickOptionsHdl();
+
+ if( p == &maBtnOK )
+ {
+ EndDialog( maCbxFilePrint.IsChecked() ? ImplGetFilename() : TRUE );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long PrintDialog::ClickOptionsHdl()
+{
+ if ( maOptionsHdlLink.IsSet() )
+ return maOptionsHdlLink.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+long PrintDialog::OK()
+{
+ if ( maOKHdlLink.IsSet() )
+ return maOKHdlLink.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::EnableSheetRange( bool bEnable, PrintSheetRange eRange )
+{
+ if ( mbWithSheetsAndCells )
+ {
+ switch ( eRange )
+ {
+ case PRINTSHEETS_ALL :
+ maRbtAllSheets.Enable( bEnable != false );
+ break;
+ case PRINTSHEETS_SELECTED_SHEETS :
+ maRbtSelectedSheets.Enable( bEnable != false );
+ break;
+ case PRINTSHEETS_SELECTED_CELLS :
+ maRbtSelectedCells.Enable( bEnable != false );
+ break;
+ default:
+ DBG_ERRORFILE( "PrintDialog::EnableSheetRange(): invalid range" );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+bool PrintDialog::IsSheetRangeEnabled( PrintSheetRange eRange ) const
+{
+ if ( !mbWithSheetsAndCells )
+ return false;
+
+ bool bRet = false;
+ switch ( eRange )
+ {
+ case PRINTSHEETS_ALL :
+ bRet = maRbtAllSheets.IsEnabled() != FALSE;
+ break;
+ case PRINTSHEETS_SELECTED_SHEETS :
+ bRet = maRbtSelectedSheets.IsEnabled() != FALSE;
+ break;
+ case PRINTSHEETS_SELECTED_CELLS :
+ bRet = maRbtSelectedCells.IsEnabled() != FALSE;
+ break;
+ default:
+ DBG_ERRORFILE( "PrintDialog::IsSheetRangeEnabled(): invalid range" );
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::CheckSheetRange( PrintSheetRange eRange )
+{
+ if ( mbWithSheetsAndCells )
+ {
+ switch ( eRange )
+ {
+ case PRINTSHEETS_ALL :
+ maRbtAllSheets.Check();
+ break;
+ case PRINTSHEETS_SELECTED_SHEETS :
+ maRbtSelectedSheets.Check();
+ break;
+ case PRINTSHEETS_SELECTED_CELLS :
+ maRbtSelectedCells.Check();
+ break;
+ default:
+ DBG_ERRORFILE( "PrintDialog::CheckSheetRange(): invalid range" );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+PrintSheetRange PrintDialog::GetCheckedSheetRange() const
+{
+ PrintSheetRange eRange = PRINTSHEETS_ALL;
+ if ( mbWithSheetsAndCells )
+ {
+ if ( maRbtSelectedSheets.IsChecked() )
+ eRange = PRINTSHEETS_SELECTED_SHEETS;
+ else if ( maRbtSelectedCells.IsChecked() )
+ eRange = PRINTSHEETS_SELECTED_CELLS;
+ }
+ return eRange;
+}
+
+// -----------------------------------------------------------------------
+
+bool PrintDialog::IsSheetRangeChecked( PrintSheetRange eRange ) const
+{
+ if ( !mbWithSheetsAndCells )
+ return false;
+
+ bool bRet = false;
+ switch ( eRange )
+ {
+ case PRINTSHEETS_ALL :
+ bRet = maRbtAllSheets.IsChecked() != FALSE;
+ break;
+ case PRINTSHEETS_SELECTED_SHEETS :
+ bRet = maRbtSelectedSheets.IsChecked() != FALSE;
+ break;
+ case PRINTSHEETS_SELECTED_CELLS :
+ bRet = maRbtSelectedCells.IsChecked() != FALSE;
+ break;
+ default:
+ DBG_ERRORFILE( "PrintDialog::IsSheetRangeChecked(): invalid range" );
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PrintDialog::Notify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_GETFOCUS) && IsReallyVisible() )
+ ImplStatusHdl( &maStatusTimer );
+ else if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ if ( rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F1 && mpPrinterImpl->m_bHelpDisabled )
+ return 1; // do nothing
+ }
+
+ return ModalDialog::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_PRINTER )
+ {
+ TEMPPRINTER() = ImplPrnDlgUpdatePrinter( mpPrinter, TEMPPRINTER() );
+ Printer* pPrn;
+ if ( TEMPPRINTER() )
+ pPrn = TEMPPRINTER();
+ else
+ pPrn = mpPrinter;
+ ImplFillPrnDlgListBox( pPrn, &maLbName, &maBtnProperties );
+ ImplSetInfo();
+ ImplCheckOK();
+ }
+ else if ( rDCEvt.GetType() == DATACHANGED_SETTINGS )
+ ImplSetImages();
+
+ ModalDialog::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+short PrintDialog::Execute()
+{
+ if ( !mpPrinter || mpPrinter->IsPrinting() || mpPrinter->IsJobActive() )
+ {
+ DBG_ERRORFILE( "PrinterSetupDialog::Execute() - No Printer or printer is printing" );
+ return FALSE;
+ }
+
+ // check if the printer brings up its own dialog
+ // in that case leave the work to that dialog
+ if( mpPrinter->GetCapabilities( PRINTER_CAPABILITIES_EXTERNALDIALOG ) )
+ return TRUE;
+
+ Printer::updatePrinters();
+
+ // Controls initialisieren
+ ImplFillPrnDlgListBox( mpPrinter, &maLbName, &maBtnProperties );
+ ImplSetInfo();
+ maStatusTimer.Start();
+ ImplInitControls();
+ maNumCopies.GrabFocus();
+ maNumCopies.SetSelection( Selection( 0, maNumCopies.GetText().Len() ) );
+ ImplModifyControlHdl( NULL );
+
+ // Dialog starten
+ short nRet = ModalDialog::Execute();
+
+ // Wenn Dialog mit OK beendet wurde, dann die Daten updaten
+ if( nRet == TRUE )
+ {
+ if ( TEMPPRINTER() )
+ mpPrinter->SetPrinterProps( TEMPPRINTER() );
+ ImplFillDialogData();
+ }
+
+ maStatusTimer.Stop();
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+void PrintDialog::DisableHelp()
+{
+ mpPrinterImpl->m_bHelpDisabled = sal_True;
+ maBtnHelp.Disable();
+}
+
diff --git a/svtools/source/dialogs/printdlg.hrc b/svtools/source/dialogs/printdlg.hrc
new file mode 100644
index 000000000000..83b7b0b28c82
--- /dev/null
+++ b/svtools/source/dialogs/printdlg.hrc
@@ -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.
+ *
+ ************************************************************************/
+
+#include <svtools/svtools.hrc>
+
+#define FL_PRINTER 1
+#define LB_NAMES 2
+#define BTN_PROPERTIES 3
+#define FT_NAME 4
+#define FT_STATUS 5
+#define FI_STATUS 6
+#define FT_TYPE 7
+#define FI_TYPE 8
+#define FT_LOCATION 9
+#define FI_LOCATION 10
+#define FT_COMMENT 11
+#define FI_COMMENT 12
+#define CBX_FILEPRINT 13
+#define FI_PRINTFILE 14
+#define FI_FAXNO 15
+#define EDT_FAXNO 16
+
+#define FL_PRINT 20
+#define RBT_ALL_SHEETS 21
+#define RBT_SELECTED_SHEETS 22
+#define RBT_SELECTED_CELLS 23
+
+#define FL_PRINTRANGE 30
+#define RBT_ALL 31
+#define RBT_PAGES 32
+#define EDT_PAGES 33
+#define RBT_SELECTION 34
+
+#define FL_SEPCOPIESRANGE 35
+
+#define FL_COPIES 40
+#define FT_COPIES 41
+#define NUM_COPIES 42
+#define CBX_COLLATE 43
+#define IMG_COLLATE 44
+#define IMG_NOT_COLLATE 45
+
+#define FL_SEPBUTTONLINE 50
+#define BTN_OK 51
+#define BTN_CANCEL 52
+#define BTN_HELP 53
+#define BTN_OPTIONS 54
+
+#define STR_ALLFILTER 10
+
diff --git a/svtools/source/dialogs/printdlg.src b/svtools/source/dialogs/printdlg.src
new file mode 100644
index 000000000000..405accc63344
--- /dev/null
+++ b/svtools/source/dialogs/printdlg.src
@@ -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 "printdlg.hrc"
+
+#define IMAGE_MAGENTA_MASK Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; }
+
+ModalDialog DLG_SVT_PRNDLG_PRINTDLG
+{
+ SVLook = TRUE ;
+ OutputSize = TRUE ;
+ Moveable = TRUE ;
+ Size = MAP_APPFONT ( 265 , 210 ) ;
+ Text [ en-US ] = "Print" ;
+ FixedLine FL_PRINTER
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 253 , 8 ) ;
+ Text [ en-US ] = "Printer" ;
+ };
+ FixedText FT_NAME
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "~Name" ;
+ };
+ ListBox LB_NAMES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 13 ) ;
+ Size = MAP_APPFONT ( 130 , 80 ) ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ PushButton BTN_PROPERTIES
+ {
+ Pos = MAP_APPFONT ( 193 , 12 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ Text [ en-US ] = "Propert~ies..." ;
+ };
+ FixedText FT_STATUS
+ {
+ Pos = MAP_APPFONT ( 12 , 29 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "Status" ;
+ };
+ FixedText FI_STATUS
+ {
+ Pos = MAP_APPFONT ( 60 , 29 ) ;
+ Size = MAP_APPFONT ( 193 , 8 ) ;
+ };
+ FixedText FT_TYPE
+ {
+ Pos = MAP_APPFONT ( 12 , 40 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "Type" ;
+ };
+ FixedText FI_TYPE
+ {
+ Pos = MAP_APPFONT ( 60 , 40 ) ;
+ Size = MAP_APPFONT ( 193 , 8 ) ;
+ };
+ FixedText FT_LOCATION
+ {
+ Pos = MAP_APPFONT ( 12 , 51 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "Location" ;
+ };
+ FixedText FI_LOCATION
+ {
+ Pos = MAP_APPFONT ( 60 , 51 ) ;
+ Size = MAP_APPFONT ( 193 , 8 ) ;
+ };
+ FixedText FT_COMMENT
+ {
+ Pos = MAP_APPFONT ( 12 , 62 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "Comment" ;
+ };
+ FixedText FI_COMMENT
+ {
+ Pos = MAP_APPFONT ( 60 , 62 ) ;
+ Size = MAP_APPFONT ( 193 , 8 ) ;
+ };
+ FixedText FI_FAXNO
+ {
+ Pos = MAP_APPFONT ( 12 , 75 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "Fax number";
+ };
+ Edit EDT_FAXNO
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT ( 60 , 73 );
+ Size = MAP_APPFONT ( 188 , 12 );
+ };
+ CheckBox CBX_FILEPRINT
+ {
+ Pos = MAP_APPFONT ( 12 , 73 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "Print to file" ;
+ };
+ FixedText FI_PRINTFILE
+ {
+ Pos = MAP_APPFONT ( 90 , 74 ) ;
+ Size = MAP_APPFONT ( 163 , 8 ) ;
+ };
+ /*!!!
+ PushButton BTN_BROWSE
+ {
+ Pos = MAP_APPFONT ( 234 , 75 ) ;
+ Size = MAP_APPFONT ( 14 , 14 ) ;
+ Text = "~..." ;
+ Hide = TRUE ;
+ };
+ */
+ FixedLine FL_PRINT
+ {
+ Pos = MAP_APPFONT ( 6 , 91 ) ;
+ Size = MAP_APPFONT ( 117 , 8 ) ;
+ Text [ en-US ] = "Print" ;
+ };
+ RadioButton RBT_ALL_SHEETS
+ {
+ Pos = MAP_APPFONT ( 12 , 102 ) ;
+ Size = MAP_APPFONT ( 105 , 10 ) ;
+ Text [ en-US ] = "All sheets" ;
+ };
+ RadioButton RBT_SELECTED_SHEETS
+ {
+ Pos = MAP_APPFONT ( 12 , 115 ) ;
+ Size = MAP_APPFONT ( 105 , 10 ) ;
+ Text [ en-US ] = "Selected sheets" ;
+ };
+ RadioButton RBT_SELECTED_CELLS
+ {
+ Pos = MAP_APPFONT ( 12 , 128 ) ;
+ Size = MAP_APPFONT ( 105 , 10 ) ;
+ Text [ en-US ] = "Selected cells" ;
+ };
+ FixedLine FL_PRINTRANGE
+ {
+ Pos = MAP_APPFONT ( 6 , 141 ) ;
+ Size = MAP_APPFONT ( 117 , 8 ) ;
+ Text [ en-US ] = "Print range" ;
+ };
+ RadioButton RBT_ALL
+ {
+ Pos = MAP_APPFONT ( 12 , 152 ) ;
+ Size = MAP_APPFONT ( 105 , 10 ) ;
+ Text [ en-US ] = "All pages" ;
+ };
+ RadioButton RBT_PAGES
+ {
+ Pos = MAP_APPFONT ( 12 , 165 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Text [ en-US ] = "Pages" ;
+ };
+ Edit EDT_PAGES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 65 , 164 ) ;
+ Size = MAP_APPFONT ( 52 , 12 ) ;
+ };
+ RadioButton RBT_SELECTION
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 179 ) ;
+ Size = MAP_APPFONT ( 105 , 10 ) ;
+ Text [ en-US ] = "Selection" ;
+ };
+ FixedLine FL_SEPCOPIESRANGE
+ {
+ Pos = MAP_APPFONT( 126, 102 );
+ Size = MAP_APPFONT( 1, 74 );
+ Vert = TRUE;
+ };
+ FixedLine FL_COPIES
+ {
+ Pos = MAP_APPFONT ( 129 , 91 ) ;
+ Size = MAP_APPFONT ( 130 , 8 ) ;
+ Text [ en-US ] = "Copies" ;
+ };
+ FixedText FT_COPIES
+ {
+ Pos = MAP_APPFONT ( 135 , 104 ) ;
+ Size = MAP_APPFONT ( 63 , 8 ) ;
+ Text [ en-US ] = "Number of copies" ;
+ };
+ NumericField NUM_COPIES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 201 , 102 ) ;
+ Size = MAP_APPFONT ( 33 , 12 ) ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 1 ;
+ Maximum = 9999 ;
+ StrictFormat = TRUE ;
+ First = 1 ;
+ Last = 9999 ;
+ };
+ CheckBox CBX_COLLATE
+ {
+ Pos = MAP_APPFONT ( 201 , 123 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "Co~llate" ;
+ };
+ FixedImage IMG_COLLATE
+ {
+ Pos = MAP_APPFONT ( 132 , 117 ) ;
+ Size = MAP_APPFONT ( 67 , 22 ) ;
+ Hide = TRUE ;
+ };
+ FixedImage IMG_NOT_COLLATE
+ {
+ Pos = MAP_APPFONT ( 132 , 117 ) ;
+ Size = MAP_APPFONT ( 67 , 22 ) ;
+ Hide = TRUE ;
+ };
+ FixedLine FL_SEPBUTTONLINE
+ {
+ Pos = MAP_APPFONT( 0, 179 );
+ Size = MAP_APPFONT( 265, 8 );
+ };
+ PushButton BTN_OPTIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Options..." ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 100 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 153 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 209 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ String STR_ALLFILTER
+ {
+ Text [ en-US ] = "<All>";
+ };
+};
+
+Image RID_IMG_PRNDLG_COLLATE
+{
+ ImageBitmap = Bitmap { File = "collate.bmp" ; };
+ MaskColor = IMAGE_MAGENTA_MASK ;
+};
+
+Image RID_IMG_PRNDLG_NOCOLLATE
+{
+ ImageBitmap = Bitmap { File = "ncollate.bmp" ; };
+ MaskColor = IMAGE_MAGENTA_MASK ;
+};
+
+Image RID_IMG_PRNDLG_COLLATE_HC
+{
+ ImageBitmap = Bitmap { File = "collate_h.bmp" ; };
+ MaskColor = IMAGE_MAGENTA_MASK ;
+};
+
+Image RID_IMG_PRNDLG_NOCOLLATE_HC
+{
+ ImageBitmap = Bitmap { File = "ncollate_h.bmp" ; };
+ MaskColor = IMAGE_MAGENTA_MASK ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/dialogs/prnsetup.cxx b/svtools/source/dialogs/prnsetup.cxx
new file mode 100644
index 000000000000..ceef2a88642b
--- /dev/null
+++ b/svtools/source/dialogs/prnsetup.cxx
@@ -0,0 +1,403 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <tools/debug.hxx>
+#ifndef _VCL_PRINT_HXX
+#include <vcl/print.hxx>
+#endif
+
+#ifndef GCC
+#endif
+
+#include <svtools/svtdata.hxx>
+#include "prnsetup.hrc"
+#include <svtools/prnsetup.hxx>
+
+// =======================================================================
+
+void ImplFillPrnDlgListBox( const Printer* pPrinter,
+ ListBox* pBox, PushButton* pPropBtn )
+{
+ ImplFreePrnDlgListBox( pBox );
+
+ const std::vector<rtl::OUString>& rPrinters = Printer::GetPrinterQueues();
+ unsigned int nCount = rPrinters.size();
+ if ( nCount )
+ {
+ for( unsigned int i = 0; i < nCount; i++ )
+ pBox->InsertEntry( rPrinters[i] );
+ pBox->SelectEntry( pPrinter->GetName() );
+ }
+
+ pBox->Enable( nCount != 0 );
+ pPropBtn->Show( pPrinter->HasSupport( SUPPORT_SETUPDIALOG ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreePrnDlgListBox( ListBox* pBox, BOOL bClear )
+{
+ if ( bClear )
+ pBox->Clear();
+}
+
+// -----------------------------------------------------------------------
+
+Printer* ImplPrnDlgListBoxSelect( ListBox* pBox, PushButton* pPropBtn,
+ Printer* pPrinter, Printer* pTempPrinter )
+{
+ if ( pBox->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
+ {
+ const QueueInfo* pInfo = Printer::GetQueueInfo( pBox->GetSelectEntry(), true );
+ if( pInfo)
+ {
+ if ( !pTempPrinter )
+ {
+ if ( (pPrinter->GetName() == pInfo->GetPrinterName()) &&
+ (pPrinter->GetDriverName() == pInfo->GetDriver()) )
+ pTempPrinter = new Printer( pPrinter->GetJobSetup() );
+ else
+ pTempPrinter = new Printer( *pInfo );
+ }
+ else
+ {
+ if ( (pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
+ (pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
+ {
+ delete pTempPrinter;
+ pTempPrinter = new Printer( *pInfo );
+ }
+ }
+
+ pPropBtn->Enable( pTempPrinter->HasSupport( SUPPORT_SETUPDIALOG ) );
+ }
+ else
+ pPropBtn->Disable();
+ }
+ else
+ pPropBtn->Disable();
+
+ return pTempPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+Printer* ImplPrnDlgUpdatePrinter( Printer* pPrinter, Printer* pTempPrinter )
+{
+ XubString aPrnName;
+ if ( pTempPrinter )
+ aPrnName = pTempPrinter->GetName();
+ else
+ aPrnName = pPrinter->GetName();
+
+ if ( ! Printer::GetQueueInfo( aPrnName, false ) )
+ {
+ if ( pTempPrinter )
+ delete pTempPrinter;
+ pTempPrinter = new Printer;
+ }
+
+ return pTempPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplPrnDlgUpdateQueueInfo( ListBox* pBox, QueueInfo& rInfo )
+{
+ if ( pBox->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
+ {
+ const QueueInfo* pInfo = Printer::GetQueueInfo( pBox->GetSelectEntry(), true );
+ if( pInfo )
+ rInfo = *pInfo;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplPrnDlgAddString( XubString& rStr, const XubString& rAddStr )
+{
+ if ( rStr.Len() )
+ rStr.AppendAscii( "; " );
+ rStr += rAddStr;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplPrnDlgAddResString( XubString& rStr, USHORT nResId )
+{
+ SvtResId aResId( nResId );
+ XubString aAddStr( aResId );
+ ImplPrnDlgAddString( rStr, aAddStr );
+}
+
+// -----------------------------------------------------------------------
+
+XubString ImplPrnDlgGetStatusText( const QueueInfo& rInfo )
+{
+ XubString aStr;
+ ULONG nStatus = rInfo.GetStatus();
+
+ // Default-Printer
+ if ( rInfo.GetPrinterName().Len() &&
+ (rInfo.GetPrinterName() == Printer::GetDefaultPrinterName()) )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_DEFPRINTER );
+
+ // Status
+ if ( nStatus & QUEUE_STATUS_READY )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_READY );
+ if ( nStatus & QUEUE_STATUS_PAUSED )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAUSED );
+ if ( nStatus & QUEUE_STATUS_PENDING_DELETION )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PENDING );
+ if ( nStatus & QUEUE_STATUS_BUSY )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_BUSY );
+ if ( nStatus & QUEUE_STATUS_INITIALIZING )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_INITIALIZING );
+ if ( nStatus & QUEUE_STATUS_WAITING )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_WAITING );
+ if ( nStatus & QUEUE_STATUS_WARMING_UP )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_WARMING_UP );
+ if ( nStatus & QUEUE_STATUS_PROCESSING )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PROCESSING );
+ if ( nStatus & QUEUE_STATUS_PRINTING )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PRINTING );
+ if ( nStatus & QUEUE_STATUS_OFFLINE )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_OFFLINE );
+ if ( nStatus & QUEUE_STATUS_ERROR )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_ERROR );
+ if ( nStatus & QUEUE_STATUS_SERVER_UNKNOWN )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_SERVER_UNKNOWN );
+ if ( nStatus & QUEUE_STATUS_PAPER_JAM )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAPER_JAM );
+ if ( nStatus & QUEUE_STATUS_PAPER_OUT )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAPER_OUT );
+ if ( nStatus & QUEUE_STATUS_MANUAL_FEED )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_MANUAL_FEED );
+ if ( nStatus & QUEUE_STATUS_PAPER_PROBLEM )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAPER_PROBLEM );
+ if ( nStatus & QUEUE_STATUS_IO_ACTIVE )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_IO_ACTIVE );
+ if ( nStatus & QUEUE_STATUS_OUTPUT_BIN_FULL )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_OUTPUT_BIN_FULL );
+ if ( nStatus & QUEUE_STATUS_TONER_LOW )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_TONER_LOW );
+ if ( nStatus & QUEUE_STATUS_NO_TONER )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_NO_TONER );
+ if ( nStatus & QUEUE_STATUS_PAGE_PUNT )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_PAGE_PUNT );
+ if ( nStatus & QUEUE_STATUS_USER_INTERVENTION )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_USER_INTERVENTION );
+ if ( nStatus & QUEUE_STATUS_OUT_OF_MEMORY )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_OUT_OF_MEMORY );
+ if ( nStatus & QUEUE_STATUS_DOOR_OPEN )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_DOOR_OPEN );
+ if ( nStatus & QUEUE_STATUS_POWER_SAVE )
+ ImplPrnDlgAddResString( aStr, STR_SVT_PRNDLG_POWER_SAVE );
+
+ // Anzahl Jobs
+ ULONG nJobs = rInfo.GetJobs();
+ if ( nJobs && (nJobs != QUEUE_JOBS_DONTKNOW) )
+ {
+ XubString aJobStr( SvtResId( STR_SVT_PRNDLG_JOBCOUNT ) );
+ XubString aJobs( XubString::CreateFromInt32( nJobs ) );
+ aJobStr.SearchAndReplaceAscii( "%d", aJobs );
+ ImplPrnDlgAddString( aStr, aJobStr );
+ }
+
+ return aStr;
+}
+
+// =======================================================================
+
+PrinterSetupDialog::PrinterSetupDialog( Window* pWindow ) :
+ ModalDialog ( pWindow, SvtResId( DLG_SVT_PRNDLG_PRNSETUPDLG ) ),
+ maFlPrinter ( this, SvtResId( FL_PRINTER ) ),
+ maFtName ( this, SvtResId( FT_NAME ) ),
+ maLbName ( this, SvtResId( LB_NAMES ) ),
+ maBtnProperties ( this, SvtResId( BTN_PROPERTIES ) ),
+ maBtnOptions ( this, SvtResId( BTN_OPTIONS ) ),
+ maFtStatus ( this, SvtResId( FT_STATUS ) ),
+ maFiStatus ( this, SvtResId( FI_STATUS ) ),
+ maFtType ( this, SvtResId( FT_TYPE ) ),
+ maFiType ( this, SvtResId( FI_TYPE ) ),
+ maFtLocation ( this, SvtResId( FT_LOCATION ) ),
+ maFiLocation ( this, SvtResId( FI_LOCATION ) ),
+ maFtComment ( this, SvtResId( FT_COMMENT ) ),
+ maFiComment ( this, SvtResId( FI_COMMENT ) ),
+ maFlSepButton ( this, SvtResId( FL_SEPBUTTON ) ),
+ maBtnOK ( this, SvtResId( BTN_OK ) ),
+ maBtnCancel ( this, SvtResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, SvtResId( BTN_HELP ) )
+{
+ FreeResource();
+
+ // show options button only if link is set
+ maBtnOptions.Hide();
+
+ mpPrinter = NULL;
+ mpTempPrinter = NULL;
+
+ maStatusTimer.SetTimeout( IMPL_PRINTDLG_STATUS_UPDATE );
+ maStatusTimer.SetTimeoutHdl( LINK( this, PrinterSetupDialog, ImplStatusHdl ) );
+ maBtnProperties.SetClickHdl( LINK( this, PrinterSetupDialog, ImplPropertiesHdl ) );
+ maLbName.SetSelectHdl( LINK( this, PrinterSetupDialog, ImplChangePrinterHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+PrinterSetupDialog::~PrinterSetupDialog()
+{
+ ImplFreePrnDlgListBox( &maLbName, FALSE );
+ delete mpTempPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void PrinterSetupDialog::SetOptionsHdl( const Link& rLink )
+{
+ maBtnOptions.SetClickHdl( rLink );
+ maBtnOptions.Show( rLink.IsSet() );
+}
+
+const Link& PrinterSetupDialog::GetOptionsHdl() const
+{
+ return maBtnOptions.GetClickHdl();
+}
+
+void PrinterSetupDialog::ImplSetInfo()
+{
+ const QueueInfo* pInfo = Printer::GetQueueInfo(maLbName.GetSelectEntry(), true);
+ if ( pInfo )
+ {
+ maFiType.SetText( pInfo->GetDriver() );
+ maFiLocation.SetText( pInfo->GetLocation() );
+ maFiComment.SetText( pInfo->GetComment() );
+ maFiStatus.SetText( ImplPrnDlgGetStatusText( *pInfo ) );
+ }
+ else
+ {
+ XubString aTempStr;
+ maFiType.SetText( aTempStr );
+ maFiLocation.SetText( aTempStr );
+ maFiComment.SetText( aTempStr );
+ maFiStatus.SetText( aTempStr );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrinterSetupDialog, ImplStatusHdl, Timer*, EMPTYARG )
+{
+ QueueInfo aInfo;
+ ImplPrnDlgUpdateQueueInfo( &maLbName, aInfo );
+ maFiStatus.SetText( ImplPrnDlgGetStatusText( aInfo ) );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrinterSetupDialog, ImplPropertiesHdl, void*, EMPTYARG )
+{
+ if ( !mpTempPrinter )
+ mpTempPrinter = new Printer( mpPrinter->GetJobSetup() );
+ mpTempPrinter->Setup( this );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( PrinterSetupDialog, ImplChangePrinterHdl, void*, EMPTYARG )
+{
+ mpTempPrinter = ImplPrnDlgListBoxSelect( &maLbName, &maBtnProperties,
+ mpPrinter, mpTempPrinter );
+ ImplSetInfo();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long PrinterSetupDialog::Notify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_GETFOCUS) && IsReallyVisible() )
+ ImplStatusHdl( &maStatusTimer );
+
+ return ModalDialog::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PrinterSetupDialog::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_PRINTER )
+ {
+ mpTempPrinter = ImplPrnDlgUpdatePrinter( mpPrinter, mpTempPrinter );
+ Printer* pPrn;
+ if ( mpTempPrinter )
+ pPrn = mpTempPrinter;
+ else
+ pPrn = mpPrinter;
+ ImplFillPrnDlgListBox( pPrn, &maLbName, &maBtnProperties );
+ ImplSetInfo();
+ }
+
+ ModalDialog::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+short PrinterSetupDialog::Execute()
+{
+ if ( !mpPrinter || mpPrinter->IsPrinting() || mpPrinter->IsJobActive() )
+ {
+ DBG_ERRORFILE( "PrinterSetupDialog::Execute() - No Printer or printer is printing" );
+ return FALSE;
+ }
+
+ Printer::updatePrinters();
+
+ ImplFillPrnDlgListBox( mpPrinter, &maLbName, &maBtnProperties );
+ ImplSetInfo();
+ maStatusTimer.Start();
+
+ // Dialog starten
+ short nRet = ModalDialog::Execute();
+
+ // Wenn Dialog mit OK beendet wurde, dann die Daten updaten
+ if ( nRet == TRUE )
+ {
+ if ( mpTempPrinter )
+ mpPrinter->SetPrinterProps( mpTempPrinter );
+ }
+
+ maStatusTimer.Stop();
+
+ return nRet;
+}
diff --git a/svtools/source/dialogs/prnsetup.hrc b/svtools/source/dialogs/prnsetup.hrc
new file mode 100644
index 000000000000..4a06c3cf0e63
--- /dev/null
+++ b/svtools/source/dialogs/prnsetup.hrc
@@ -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.
+ *
+ ************************************************************************/
+#include <svtools/svtools.hrc>
+
+#define FL_PRINTER 1
+#define LB_NAMES 2
+#define BTN_PROPERTIES 3
+#define FT_NAME 4
+#define FT_STATUS 5
+#define FI_STATUS 6
+#define FT_TYPE 7
+#define FI_TYPE 8
+#define FT_LOCATION 9
+#define FI_LOCATION 10
+#define FT_COMMENT 11
+#define FI_COMMENT 12
+
+#define BTN_OK 13
+#define BTN_CANCEL 14
+#define BTN_HELP 15
+
+#define FL_SEPBUTTON 16
+
+#define BTN_OPTIONS 17
diff --git a/svtools/source/dialogs/prnsetup.src b/svtools/source/dialogs/prnsetup.src
new file mode 100644
index 000000000000..1443a35e0f39
--- /dev/null
+++ b/svtools/source/dialogs/prnsetup.src
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "prnsetup.hrc"
+
+String STR_SVT_PRNDLG_READY
+{
+ Text [ en-US ] = "Ready" ;
+};
+String STR_SVT_PRNDLG_PAUSED
+{
+ Text [ en-US ] = "Paused" ;
+};
+String STR_SVT_PRNDLG_PENDING
+{
+ Text [ en-US ] = "Pending deletion" ;
+};
+String STR_SVT_PRNDLG_BUSY
+{
+ Text [ en-US ] = "Busy" ;
+};
+String STR_SVT_PRNDLG_INITIALIZING
+{
+ Text [ en-US ] = "Initializing" ;
+};
+String STR_SVT_PRNDLG_WAITING
+{
+ Text [ en-US ] = "Waiting" ;
+};
+String STR_SVT_PRNDLG_WARMING_UP
+{
+ Text [ en-US ] = "Warming up" ;
+};
+String STR_SVT_PRNDLG_PROCESSING
+{
+ Text [ en-US ] = "Processing" ;
+};
+String STR_SVT_PRNDLG_PRINTING
+{
+ Text [ en-US ] = "Printing" ;
+};
+String STR_SVT_PRNDLG_OFFLINE
+{
+ Text [ en-US ] = "Offline" ;
+};
+String STR_SVT_PRNDLG_ERROR
+{
+ Text [ en-US ] = "Error" ;
+};
+String STR_SVT_PRNDLG_SERVER_UNKNOWN
+{
+ Text [ en-US ] = "Unknown Server" ;
+};
+String STR_SVT_PRNDLG_PAPER_JAM
+{
+ Text [ en-US ] = "Paper jam" ;
+};
+String STR_SVT_PRNDLG_PAPER_OUT
+{
+ Text [ en-US ] = "Not enough paper" ;
+};
+String STR_SVT_PRNDLG_MANUAL_FEED
+{
+ Text [ en-US ] = "Manual feed" ;
+};
+String STR_SVT_PRNDLG_PAPER_PROBLEM
+{
+ Text [ en-US ] = "Paper problem" ;
+};
+String STR_SVT_PRNDLG_IO_ACTIVE
+{
+ Text [ en-US ] = "I/O active" ;
+};
+String STR_SVT_PRNDLG_OUTPUT_BIN_FULL
+{
+ Text [ en-US ] = "Output bin full" ;
+};
+String STR_SVT_PRNDLG_TONER_LOW
+{
+ Text [ en-US ] = "Toner low" ;
+};
+String STR_SVT_PRNDLG_NO_TONER
+{
+ Text [ en-US ] = "No toner" ;
+};
+String STR_SVT_PRNDLG_PAGE_PUNT
+{
+ Text [ en-US ] = "Delete Page" ;
+};
+String STR_SVT_PRNDLG_USER_INTERVENTION
+{
+ Text [ en-US ] = "User intervention necessary" ;
+};
+String STR_SVT_PRNDLG_OUT_OF_MEMORY
+{
+ Text [ en-US ] = "Insufficient memory" ;
+};
+String STR_SVT_PRNDLG_DOOR_OPEN
+{
+ Text [ en-US ] = "Cover open" ;
+};
+String STR_SVT_PRNDLG_POWER_SAVE
+{
+ Text [ en-US ] = "Power save mode" ;
+};
+String STR_SVT_PRNDLG_DEFPRINTER
+{
+ Text [ en-US ] = "Default printer" ;
+};
+String STR_SVT_PRNDLG_JOBCOUNT
+{
+ Text [ en-US ] = "%d documents" ;
+};
+
+ModalDialog DLG_SVT_PRNDLG_PRNSETUPDLG
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Size = MAP_APPFONT ( 260 , 104 ) ;
+ Text [ en-US ] = "Printer Setup" ;
+ FixedLine FL_PRINTER
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Printer" ;
+ };
+ FixedText FT_NAME
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "~Name" ;
+ };
+ ListBox LB_NAMES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 12 ) ;
+ Size = MAP_APPFONT ( 125 , 80 ) ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ PushButton BTN_PROPERTIES
+ {
+ Pos = MAP_APPFONT ( 188 , 12 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ Text [ en-US ] = "Propert~ies..." ;
+ };
+ FixedText FT_STATUS
+ {
+ Pos = MAP_APPFONT ( 12 , 29 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "Status" ;
+ };
+ FixedText FI_STATUS
+ {
+ Pos = MAP_APPFONT ( 60 , 29 ) ;
+ Size = MAP_APPFONT ( 188 , 10 ) ;
+ };
+ FixedText FT_TYPE
+ {
+ Pos = MAP_APPFONT ( 12 , 40 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "Type" ;
+ };
+ FixedText FI_TYPE
+ {
+ Pos = MAP_APPFONT ( 60 , 40 ) ;
+ Size = MAP_APPFONT ( 188 , 10 ) ;
+ };
+ FixedText FT_LOCATION
+ {
+ Pos = MAP_APPFONT ( 12 , 51 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "Location" ;
+ };
+ FixedText FI_LOCATION
+ {
+ Pos = MAP_APPFONT ( 60 , 51 ) ;
+ Size = MAP_APPFONT ( 188 , 10 ) ;
+ };
+ FixedText FT_COMMENT
+ {
+ Pos = MAP_APPFONT ( 12 , 62 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "Comment" ;
+ };
+ FixedText FI_COMMENT
+ {
+ Pos = MAP_APPFONT ( 60 , 62 ) ;
+ Size = MAP_APPFONT ( 188 , 10 ) ;
+ };
+ FixedLine FL_SEPBUTTON
+ {
+ Pos = MAP_APPFONT ( 0, 78 );
+ Size = MAP_APPFONT ( 260, 2 );
+ };
+ PushButton BTN_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 5 , 84 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Options..." ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 95 , 84 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 148 , 84 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 204 , 84 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/dialogs/propctrl.cxx b/svtools/source/dialogs/propctrl.cxx
new file mode 100644
index 000000000000..675a93ca728b
--- /dev/null
+++ b/svtools/source/dialogs/propctrl.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_svtools.hxx"
+
+
+#ifndef _USR_INTROSP_HXX
+#include <usr/inspect.hxx>
+#endif
+#ifndef _USR_SERINFO_HXX
+#include <usr/serinfo.hxx>
+#endif
+#ifndef _USR_INTROSP_HXX
+#include <usr/introsp.hxx>
+#endif
+
+#include <propctrl.hxx>
+#include <property.hxx>
+
+
+// Controller-Implementation
+class PropertyEditorControler_Impl : public SvPropertyDataControl
+{
+ XIntrospectionAccessRef mxUnoAccess;
+ PropertySequence mPropSeq;
+ XPropertyEditorRef mxEditor;
+ SvPropertyBox* mpPropBox;
+ UsrAny maUnoObj;
+
+public:
+ // Provisorisch direkt Window mitgeben
+ PropertyEditorControler_Impl( SvPropertyBox* pPropBox_ );
+ //SimplePropertyEditor_Impl( void );
+
+ // Objekt zum Editieren setzen, dies loest das Eintragen
+ // der Properties in die PropertyBox aus
+ void setObject( XPropertyEditorRef xEditor_, const UsrAny& aToEditObj,
+ /* HACK fuer History-Interface*/String aPath, BOOL bBack=FALSE, BOOL bForward=FALSE );
+
+ /* SPAETER
+ SMART_UNO_DECLARATION(ImplIntrospection,UsrObject);
+
+ // Methoden von XInterface
+ XInterface * queryInterface( Uik aUik );
+ XIdlClassRef getIdlClass();
+ */
+
+ // Methoden von SvPropertyDataControl
+ virtual void Modified( const String& aName,
+ const String& aVal,
+ void* pData);
+
+ virtual void Clicked( const String& aName,
+ const String& aVal,
+ void* pData);
+
+ virtual void Commit( const String& aName,
+ const String& aVal,
+ void* pData);
+
+ virtual void Select( const String& aName,
+ void* pData);
+
+ virtual void LinkClicked(const String& aName,
+ void* pData);
+
+ // TODO: Das muss raus, sehr unglueckliche Schnittstelle
+ // PropertyBox erzwingt Zustand des Controllers
+ virtual String GetTheCorrectProperty() const;
+};
+
+// Methoden von XPropertyEditor
+PropertyEditorControler_Impl::PropertyEditorControler_Impl( SvPropertyBox* pPropBox_ )
+{
+ mpPropBox = pPropBox_;
+}
+
+void PropertyEditorControler_Impl::setObject( XPropertyEditorRef xEditor_, const UsrAny& aToEditObj,
+ /* HACK fuer History-Interface*/ String aPath, BOOL bBack, BOOL bForward )
+{
+ static XIntrospectionRef xIntrospection;
+
+ // Ohne Fenster laeuft gar nix
+ if( !mpPropBox )
+ return;
+
+ // Fenster aufraeumen
+ mpPropBox->ClearAll();
+
+ // Editor und Objekt übernehmen
+ mxEditor = xEditor_;
+ maUnoObj = aToEditObj;
+
+ if( !xIntrospection.is() )
+ {
+ // Introspection-Service holen
+ XServiceManagerRef xServiceManager = getGlobalServiceManager();
+ XServiceProviderRef xProv = xServiceManager->getServiceProvider
+ ( "com.sun.star.beans.Introspection", UikSequence(), UikSequence() );
+ xIntrospection = (XIntrospection *)xProv->newInstance()
+ ->queryInterface( XIntrospection::getSmartUik() );
+ }
+ if( !xIntrospection.is() )
+ return;
+
+ // und unspecten
+ mxUnoAccess = xIntrospection->inspect( maUnoObj );
+ if( !mxUnoAccess.Is() )
+ return;
+
+ // Uns als Controler anmelden
+ mpPropBox->SetController( this );
+
+ // Properties anlegen
+ mPropSeq = mxUnoAccess->getProperties();
+ UINT32 nPropCount = mPropSeq.getLen();
+ const Property* pProps = mPropSeq.getConstArray();
+
+ // 1. Seite anlegen
+ USHORT nPropPageId = mpPropBox->AppendPage("Properties");
+
+ // Beim Eintragen solls nicht flimmern
+ mpPropBox->DisableUpdate();
+
+ // Dummy-Properties fuer Path und Navigation
+ SvPropertyData aProperty;
+ if( aPath.Len() )
+ {
+ // Interface und Structs werden Hyperlinks
+ aProperty.bIsHyperLink = FALSE;
+ aProperty.bIsLocked = TRUE;
+ aProperty.bHasVisibleXButton = FALSE;
+ aProperty.eKind = KOC_EDIT;
+ aProperty.pControl = NULL;
+ aProperty.pDataPtr = NULL;
+ aProperty.aName = "Path";
+ aProperty.aValue = aPath;
+ mpPropBox->InsertEntry( aProperty );
+ }
+ if( bBack || bForward )
+ {
+ // Interface und Structs werden Hyperlinks
+ aProperty.bIsHyperLink = TRUE;
+ aProperty.bIsLocked = TRUE;
+ // HACK, solange Hyperlink nicht funktioniert
+ aProperty.bHasVisibleXButton = aProperty.bIsHyperLink;
+ aProperty.eKind = KOC_EDIT;
+ UINT32 iHandle;
+ aProperty.pControl = NULL;
+ if( bBack )
+ {
+ iHandle = 1000001;
+ aProperty.pDataPtr = (void*)iHandle;
+ aProperty.aName = "<-";
+ aProperty.aValue = "Back";
+ mpPropBox->InsertEntry( aProperty );
+ }
+ if( bForward )
+ {
+ iHandle = 1000000;
+ aProperty.pDataPtr = (void*)iHandle;
+ aProperty.aName = "->";
+ aProperty.aValue = "Forward";
+ mpPropBox->InsertEntry( aProperty );
+ }
+ }
+
+ // Properties eintragen
+ // TODO: Wo kommen die Strings her
+ UINT32 i;
+ for( i = 0 ; i < nPropCount ; i++ )
+ {
+ const Property& rProp = pProps[ i ];
+
+ // TypeClass des Property ermitteln
+ XIdlClassRef xPropClass = rProp.Type;
+ if( !xPropClass.is() )
+ {
+ DBG_ERROR( "PropertyEditorControler_Impl::Commit(), Property without type" )
+ return;
+ }
+ TypeClass eType = xPropClass->getTypeClass();
+
+ // Interface und Structs werden Hyperlinks
+ aProperty.bIsHyperLink = ( eType == TYPECLASS_INTERFACE || eType == TYPECLASS_STRUCT );
+ aProperty.bIsLocked = ((rProp.Attributes & PROPERTY_READONLY) != 0 );
+
+ // HACK, solange Hyperlink nicht funktioniert
+ aProperty.bHasVisibleXButton = aProperty.bIsHyperLink;
+
+ // Wert holen und in String wandeln
+ UsrAny aVal = mxUnoAccess->getPropertyValueByIndex( maUnoObj, i );
+ String aStrVal = AnyToString( aVal );
+
+ // Properties reinbraten
+ aProperty.eKind = KOC_EDIT;
+ aProperty.aName = rProp.Name;
+ aProperty.aValue = aStrVal;
+ aProperty.pDataPtr = (void*)i;
+ aProperty.pControl = NULL;
+ //aProperty.theValues.Insert(new String("1"),aProperty.theValues.Count());
+ //aProperty.theValues.Insert(new String("2"),aProperty.theValues.Count());
+ //aProperty.theValues.Insert(new String("3"),aProperty.theValues.Count());
+ //aProperty.theValues.Insert(new String("4"),aProperty.theValues.Count());
+ mpPropBox->InsertEntry( aProperty );
+ }
+
+ // 2. Seite fuer Listener
+ // TODO: Wo kommen die Eintraege her
+ USHORT nListenerPageId = mpPropBox->AppendPage("Listener");
+
+ XIdlClassSequence aSupportedListenerSeq = mxUnoAccess->getSupportedListeners();
+ const XIdlClassRef* pListenerArray = aSupportedListenerSeq.getConstArray();
+ UINT32 nIfaceCount = aSupportedListenerSeq.getLen();
+
+ // Property-Data vorfuellen
+ aProperty.eKind = KOC_EDIT;
+ //aProperty.eKind = KOC_UNDEFINED;
+ aProperty.aValue = "Listener-Value";
+ aProperty.bHasVisibleXButton = TRUE;
+ // TEST
+ //aProperty.bIsHyperLink = TRUE;
+ aProperty.bIsHyperLink = FALSE;
+ aProperty.bIsLocked = TRUE;
+ //aProperty.bIsLocked = FALSE;
+ aProperty.pDataPtr = NULL;
+ aProperty.pControl = NULL;
+
+ for( UINT32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const XIdlClassRef& rxIfaceClass = pListenerArray[j];
+ aProperty.aName = rxIfaceClass->getName();
+ mpPropBox->InsertEntry( aProperty );
+ }
+ mpPropBox->EnableUpdate();
+ mpPropBox->SetPage( nPropPageId );
+}
+
+void PropertyEditorControler_Impl::Modified
+( const String& aName, const String& aVal, void* pData)
+{
+}
+
+void PropertyEditorControler_Impl::Clicked
+( const String& aName, const String& aVal, void* pData)
+{
+ // HACK, solange LinkClicked nicht funktioniert
+ UINT32 iPos = (UINT32)pData;
+ UINT32 nPropCount = mPropSeq.getLen();
+ if( iPos >= nPropCount )
+ {
+ // Spezial-IDs fuer forward/back?
+ BOOL bForward = (iPos == 1000000);
+ BOOL bBack = (iPos == 1000001);
+ if( bForward || bBack )
+ {
+ // Unterstuetzt der PropertyEditor das?
+ XPropertyEditorNavigationRef xPropEdNav = (XPropertyEditorNavigation*)
+ mxEditor->queryInterface( XPropertyEditorNavigation::getSmartUik() );
+ if( xPropEdNav.is() )
+ {
+ if( bForward )
+ xPropEdNav->forward();
+ else
+ xPropEdNav->back();
+ }
+ }
+ return;
+ }
+
+ const Property* pProps = mPropSeq.getConstArray();
+ const Property& rProp = pProps[ iPos ];
+ XIdlClassRef xPropClass = rProp.Type;
+ if( !xPropClass.is() )
+ {
+ DBG_ERROR( "PropertyEditorControler_Impl::Commit(), Property without type" )
+ return;
+ }
+ TypeClass eType = xPropClass->getTypeClass();
+ if( eType == TYPECLASS_INTERFACE || eType == TYPECLASS_STRUCT )
+ LinkClicked( aName, pData );
+}
+
+void PropertyEditorControler_Impl::Commit
+( const String& aName, const String& aVal, void* pData)
+{
+ UINT32 iPos = (UINT32)pData;
+ UINT32 nPropCount = mPropSeq.getLen();
+ if( iPos >= nPropCount )
+ return;
+
+ // String in Property-Typ wandeln
+ const Property* pProps = mPropSeq.getConstArray();
+ const Property& rProp = pProps[ iPos ];
+ XIdlClassRef xPropClass = rProp.Type;
+ if( !xPropClass.is() )
+ {
+ DBG_ERROR( "PropertyEditorControler_Impl::Commit(), Property without type" )
+ return;
+ }
+ TypeClass eType = xPropClass->getTypeClass();
+ UsrAny aValue = StringToAny( aVal, eType );
+
+ // Wert setzen
+ mxUnoAccess->setPropertyValueByIndex( maUnoObj, iPos, aValue );
+
+ // Wert neu holen und ggf. neu setzen
+ UsrAny aNewVal = mxUnoAccess->getPropertyValueByIndex( maUnoObj, iPos );
+ String aNewStrVal = AnyToString( aNewVal );
+ if( aNewStrVal != aVal )
+ mpPropBox->SetPropertyValue( aName, aNewStrVal );
+}
+
+void PropertyEditorControler_Impl::Select
+( const String& aName, void* pData)
+{
+}
+
+void PropertyEditorControler_Impl::LinkClicked(const String& aName, void* pData)
+{
+ UINT32 iPos = (UINT32)pData;
+ UINT32 nPropCount = mPropSeq.getLen();
+ if( iPos >= nPropCount )
+ return;
+
+ // Wert holen und an Master-Controller zurueckgeben
+ UsrAny aNewObj = mxUnoAccess->getPropertyValueByIndex( maUnoObj, iPos );
+ mxEditor->setObject( aNewObj, aName );
+}
+
+
+// TODO: Das muss raus, sehr unglueckliche Schnittstelle
+// PropertyBox erzwingt Zustand des Controllers
+String PropertyEditorControler_Impl::GetTheCorrectProperty() const
+{
+ return String();
+}
+
+
+SMART_UNO_IMPLEMENTATION(SimplePropertyEditor_Impl,UsrObject);
+
+// Methoden von XInterface
+XInterface * SimplePropertyEditor_Impl::queryInterface( Uik aUik )
+{
+ if( aUik == XPropertyEditor::getSmartUik() )
+ return (XPropertyEditor *)this;
+ if( aUik == XPropertyEditorNavigation::getSmartUik() )
+ return (XPropertyEditorNavigation *)this;
+ return UsrObject::queryInterface( aUik );
+}
+
+XIdlClassRef SimplePropertyEditor_Impl::getIdlClass()
+{
+ // TODO: Unterstuetzen
+ return NULL;
+}
+
+
+// Methoden von SimplePropertyEditor_Impl
+SimplePropertyEditor_Impl::SimplePropertyEditor_Impl( Window *pParent )
+ : maHistorySeq( 10 ), maHistoryNames( 10 ), bSimpleHistory( FALSE )
+{
+ //XVCLComponent xC = pParent->getVCLComponent
+ //xC->addVCLComponentListener( MyListener )
+
+ pActiveControler = NULL;
+ mpPropBox = new SvPropertyBox( pParent );
+ mpPropBox->Show();
+
+ long cxOut = pParent->GetOutputSizePixel().Width();
+ long cyOut = pParent->GetOutputSizePixel().Height();
+ Size aSize( cxOut, cyOut );
+ mpPropBox->SetPosSizePixel( Point( 0, 0 ), aSize );
+
+ mnHistoryCount = 0;
+ mnActualHistoryLevel = -1;
+}
+
+SimplePropertyEditor_Impl::~SimplePropertyEditor_Impl()
+{
+ delete mpPropBox;
+ if( pActiveControler )
+ delete pActiveControler;
+}
+
+// Private Methode zum Anlegen/Aktivieren der Controller
+void SimplePropertyEditor_Impl::showObject( const UsrAny& aToShowObj )
+{
+ if( pActiveControler )
+ delete pActiveControler;
+
+ // Neuen Controller auf der Wiese anlegen (TODO: Controller cachen?)
+ pActiveControler = new PropertyEditorControler_Impl( mpPropBox );
+
+ XPropertyEditorRef xThis = (XPropertyEditor *)this;
+ pActiveControler->setObject( xThis, aToShowObj,
+ /*aPath*/bSimpleHistory ? getPath() : String(),
+ /*bBack*/bSimpleHistory && mnActualHistoryLevel > 0,
+ /*bForward*/bSimpleHistory && (INT32)mnHistoryCount > mnActualHistoryLevel );
+}
+
+String SimplePropertyEditor_Impl::getPath( void )
+{
+ String aRetStr;
+ const String* pStr = maHistoryNames.getConstArray();
+ for( INT32 i = 0 ; i <= mnActualHistoryLevel ; i++ )
+ {
+ String aName = pStr[i];
+
+ // Root speziell behandeln
+ if( i == 0 )
+ {
+ aRetStr += aName;
+ }
+ else
+ {
+ // Ist es ein Index?
+ long l = (long)aName;
+ String aNumStr( l );
+ if( aNumStr == aName )
+ {
+ aRetStr += '[';
+ aRetStr += aName;
+ aRetStr += ']';
+ }
+ else
+ {
+ aRetStr += '.';
+ aRetStr += aName;
+ }
+ }
+ }
+ return aRetStr;
+}
+
+// Methoden von XPropertyEditor
+void SimplePropertyEditor_Impl::setObject( const UsrAny& aToEditObj, const XubString& aObjName )
+{
+ // History pflegen
+ mnActualHistoryLevel++;
+ mnHistoryCount = (UINT32)mnActualHistoryLevel;
+ UINT32 iHistorySize = maHistorySeq.getLen();
+ if( mnHistoryCount > iHistorySize )
+ {
+ maHistorySeq.realloc( iHistorySize + 10 );
+ maHistoryNames.realloc( iHistorySize + 10 );
+ }
+
+ // Neues Object eintragen
+ maHistorySeq.getArray()[ mnHistoryCount ] = aToEditObj;
+ maHistoryNames.getArray()[ mnHistoryCount ] = aObjName;
+
+ // Object anzeigen
+ showObject( aToEditObj );
+}
+
+// Methoden von PropertyEditorNavigation
+void SimplePropertyEditor_Impl::forward(void)
+{
+ if( (INT32)mnHistoryCount > mnActualHistoryLevel )
+ {
+ // Naechstes Object darstellen
+ mnActualHistoryLevel++;
+ showObject( maHistorySeq.getConstArray()[mnActualHistoryLevel] );
+ }
+}
+
+void SimplePropertyEditor_Impl::back(void)
+{
+ if( mnActualHistoryLevel > 0 )
+ {
+ // Voriges Object darstellen
+ mnActualHistoryLevel--;
+ showObject( maHistorySeq.getConstArray()[mnActualHistoryLevel] );
+ }
+}
+
+
diff --git a/svtools/source/dialogs/propctrl.hxx b/svtools/source/dialogs/propctrl.hxx
new file mode 100644
index 000000000000..949873ceb1b7
--- /dev/null
+++ b/svtools/source/dialogs/propctrl.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/*
+#include <tools/stream.hxx>
+#include <vcl/sound.hxx>
+#include "sbx.hxx"
+#include "sbxbase.hxx"
+#include "sbxres.hxx"
+#include <svl/brdcst.hxx>
+ */
+
+
+#ifndef __PROPED_HXX__
+#include <proped.hxx>
+#endif
+#ifndef _UNO_HXX
+#include <usr/uno.hxx>
+#endif
+#ifndef _USR_SEQU_HXX
+#include <usr/sequ.hxx>
+#endif
+#ifndef __TOOLSIDL_HXX__
+#include <usr/toolsidl.hxx>
+#endif
+
+/*
+class XPropertyEditor
+ : public XInterface
+{
+public:
+
+ virtual void setObject(const UsrAny& aToInspectObj) = 0;
+
+ static Uik getSmartUik() { return(385); }
+};
+*/
+
+class PropertyEditorControler_Impl;
+class SvPropertyBox;
+class Window;
+
+class SimplePropertyEditor_Impl :
+ public XPropertyEditor,
+ public XPropertyEditorNavigation,
+ public UsrObject
+{
+ PropertyEditorControler_Impl* pActiveControler;
+ SvPropertyBox* mpPropBox;
+ UsrAny maStartUnoObj;
+ UsrAny maActiveUnoObj;
+
+ // History der Objekte speichern
+ AnySequence maHistorySeq;
+ WSStringSequence maHistoryNames;
+ UINT32 mnHistoryCount;
+ INT32 mnActualHistoryLevel;
+
+ // Einfache History via Dummy-Properties
+ BOOL bSimpleHistory;
+
+ // Methode zum Anlegen/Aktivieren der Controller
+ void showObject( const UsrAny& aToShowObj );
+ String getPath( void );
+
+public:
+ // Provisorischer Ctor mit Parent-Window
+ SimplePropertyEditor_Impl( Window *pParent );
+ ~SimplePropertyEditor_Impl();
+
+ // HACK fuer History-Test
+ void enableSimpleHistory( BOOL bHistory_ ) { bSimpleHistory = bHistory_; }
+
+ SMART_UNO_DECLARATION(ImplIntrospection,UsrObject);
+
+ // Methoden von XInterface
+ XInterface * queryInterface( Uik aUik );
+ XIdlClassRef getIdlClass();
+
+ // Methoden von XPropertyEditor
+ virtual void setObject(const UsrAny& aToInspectObj, const XubString& aObjName);
+
+ // Methoden von PropertyEditorNavigation
+ virtual void forward(void);
+ virtual void back(void);
+
+};
+
+
+
+
diff --git a/svtools/source/dialogs/property.cxx b/svtools/source/dialogs/property.cxx
new file mode 100644
index 000000000000..3b081ce2f520
--- /dev/null
+++ b/svtools/source/dialogs/property.cxx
@@ -0,0 +1,1560 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+
+#ifndef GCC
+#endif
+
+//------------------------------------------------------------------
+
+//#include "Svitems.hxx"
+
+#include "property.hxx"
+/*
+#include "property.hrc"
+#include "Scresid.hxx"
+*/
+#define FRAME_OFFSET 4
+
+
+SvXPropertyControl::SvXPropertyControl( Window* pParent, WinBits nWinStyle)
+ : Control(pParent,nWinStyle)
+{
+}
+
+SvXPropertyControl::SvXPropertyControl( Window* pParent, const ResId& rResId )
+ : Control(pParent,rResId )
+{
+}
+
+//------------------------------------------------------------------
+
+SvXPropertyEdit::SvXPropertyEdit( Window* pParent, WinBits nWinStyle)
+ : SvXPropertyControl(pParent,nWinStyle),
+ aEdit(this,WB_BORDER | WB_TABSTOP)
+{
+ pListener=NULL;
+ aEdit.SetModifyHdl(
+ LINK( this, SvXPropertyEdit, ModifiedHdl ));
+ aEdit.SetGetFocusHdl(
+ LINK( this, SvXPropertyEdit, GetFocusHdl));
+ aEdit.SetLoseFocusHdl(
+ LINK( this, SvXPropertyEdit, LoseFocusHdl));
+
+ aEdit.Show();
+}
+
+SvXPropertyEdit::SvXPropertyEdit( Window* pParent, const ResId& rResId)
+ : SvXPropertyControl(pParent,rResId),
+ aEdit(this,WB_BORDER | WB_TABSTOP)
+{
+ pListener=NULL;
+ aEdit.SetModifyHdl(
+ LINK( this, SvXPropertyEdit, ModifiedHdl ));
+ aEdit.SetGetFocusHdl(
+ LINK( this, SvXPropertyEdit, GetFocusHdl));
+ aEdit.SetLoseFocusHdl(
+ LINK( this, SvXPropertyEdit, LoseFocusHdl));
+
+ Size aSize=GetSizePixel();
+ SetCtrSize(aSize);
+ aEdit.Show();
+}
+
+void SvXPropertyEdit::SetSvXPropertyCtrListener(SvXPropertyCtrListener* pCtrListener)
+{
+ pListener=pCtrListener;
+}
+
+SvXPropertyCtrListener* SvXPropertyEdit::GetSvXPropertyCtrListener()
+{
+ return pListener;
+}
+
+
+void SvXPropertyEdit::SetCtrSize(const Size& rSize)
+{
+ SetSizePixel(rSize);
+ Size aSize=GetOutputSizePixel();
+ Point aPos(0,0);
+ aEdit.SetPosPixel(aPos);
+ aEdit.SetSizePixel(aSize);
+}
+
+void SvXPropertyEdit::SetLocked(BOOL bLocked)
+{
+ if(bLocked)
+ Disable();
+ else
+ Enable();
+}
+
+void SvXPropertyEdit::SetProperty(const String &rString)
+{
+ aEdit.SetText(rString);
+}
+
+String SvXPropertyEdit::GetProperty() const
+{
+ return aEdit.GetText();
+}
+
+BOOL SvXPropertyEdit::HasList()
+{
+ return FALSE;
+};
+
+
+void SvXPropertyEdit::ClearList()
+{
+ return;
+}
+void SvXPropertyEdit::InsertEntry( const String&,USHORT )
+{
+ return;
+}
+
+void SvXPropertyEdit::SetMyName(const String &rString)
+{
+ aName=rString;
+}
+
+String SvXPropertyEdit::GetMyName()const
+{
+ return aName;
+}
+
+void SvXPropertyEdit::SetMyData(void* pDat)
+{
+ pData=pDat;
+}
+
+void* SvXPropertyEdit::GetMyData()
+{
+ return pData;
+}
+
+
+IMPL_LINK( SvXPropertyEdit, ModifiedHdl, Edit*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->Modified(this);
+ return 0;
+}
+
+IMPL_LINK( SvXPropertyEdit, GetFocusHdl, Edit*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->GetFocus(this);
+ return 0;
+}
+
+IMPL_LINK( SvXPropertyEdit, LoseFocusHdl, Edit*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->LoseFocus(this);
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+SvXPropertyListBox::SvXPropertyListBox( Window* pParent, WinBits nWinStyle)
+ : SvXPropertyControl(pParent,nWinStyle),
+ aListBox(this,WB_BORDER | WB_DROPDOWN | WB_TABSTOP)
+{
+ pListener=NULL;
+ aListBox.SetSelectHdl(
+ LINK( this, SvXPropertyListBox, ModifiedHdl ));
+ aListBox.SetGetFocusHdl(
+ LINK( this, SvXPropertyListBox, GetFocusHdl));
+ aListBox.SetLoseFocusHdl(
+ LINK( this, SvXPropertyListBox, LoseFocusHdl));
+ aListBox.Show();
+}
+
+SvXPropertyListBox::SvXPropertyListBox( Window* pParent, const ResId& rResId)
+ : SvXPropertyControl(pParent,rResId),
+ aListBox(this,WB_BORDER | WB_DROPDOWN | WB_TABSTOP)
+{
+ pListener=NULL;
+ aListBox.SetSelectHdl(
+ LINK( this, SvXPropertyListBox, ModifiedHdl ));
+ aListBox.SetGetFocusHdl(
+ LINK( this, SvXPropertyListBox, GetFocusHdl));
+ aListBox.SetLoseFocusHdl(
+ LINK( this, SvXPropertyListBox, LoseFocusHdl));
+
+ Size aSize=GetSizePixel();
+ SetCtrSize(aSize);
+ aListBox.Show();
+}
+
+void SvXPropertyListBox::SetSvXPropertyCtrListener(SvXPropertyCtrListener* pCtrListener)
+{
+ pListener=pCtrListener;
+}
+
+SvXPropertyCtrListener* SvXPropertyListBox::GetSvXPropertyCtrListener()
+{
+ return pListener;
+}
+
+
+void SvXPropertyListBox::SetCtrSize(const Size& rSize)
+{
+ SetSizePixel(rSize);
+ Size aSize=GetOutputSizePixel();
+ Point aPos(0,0);
+ aListBox.SetPosPixel(aPos);
+ aListBox.SetSizePixel(aSize);
+}
+
+void SvXPropertyListBox::SetLocked(BOOL bLocked)
+{
+ if(bLocked)
+ Disable();
+ else
+ Enable();
+}
+
+void SvXPropertyListBox::SetProperty(const String &rString)
+{
+ aListBox.SelectEntry(rString);
+}
+
+String SvXPropertyListBox::GetProperty()const
+{
+ return aListBox.GetSelectEntry();
+}
+
+BOOL SvXPropertyListBox::HasList()
+{
+ return TRUE;
+}
+
+
+void SvXPropertyListBox::ClearList()
+{
+ aListBox.Clear();
+}
+
+void SvXPropertyListBox::InsertEntry( const String& rString,USHORT nPos)
+{
+ aListBox.InsertEntry(rString,nPos);
+}
+
+void SvXPropertyListBox::SetMyName(const String &rString)
+{
+ aName=rString;
+}
+
+String SvXPropertyListBox::GetMyName()const
+{
+ return aName;
+}
+
+void SvXPropertyListBox::SetMyData(void* pDat)
+{
+ pData=pDat;
+}
+
+void* SvXPropertyListBox::GetMyData()
+{
+ return pData;
+}
+
+IMPL_LINK( SvXPropertyListBox, ModifiedHdl, ListBox*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->Modified(this);
+ return 0;
+}
+
+IMPL_LINK( SvXPropertyListBox, GetFocusHdl, ListBox*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->GetFocus(this);
+ return 0;
+}
+
+IMPL_LINK( SvXPropertyListBox, LoseFocusHdl, ListBox*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->LoseFocus(this);
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+
+SvXPropertyComboBox::SvXPropertyComboBox( Window* pParent, WinBits nWinStyle)
+ : SvXPropertyControl(pParent,nWinStyle),
+ aComboBox(this,WB_BORDER | WB_DROPDOWN | WB_TABSTOP)
+{
+ pListener=NULL;
+ aComboBox.SetModifyHdl(
+ LINK( this, SvXPropertyComboBox, ModifiedHdl ));
+ aComboBox.SetGetFocusHdl(
+ LINK( this, SvXPropertyComboBox, GetFocusHdl));
+ aComboBox.SetLoseFocusHdl(
+ LINK( this, SvXPropertyComboBox, LoseFocusHdl));
+ aComboBox.Show();
+}
+
+SvXPropertyComboBox::SvXPropertyComboBox( Window* pParent, const ResId& rResId)
+ : SvXPropertyControl(pParent,rResId),
+ aComboBox(this,WB_BORDER | WB_DROPDOWN | WB_TABSTOP)
+{
+ pListener=NULL;
+ aComboBox.SetModifyHdl(
+ LINK( this, SvXPropertyComboBox, ModifiedHdl ));
+ aComboBox.SetGetFocusHdl(
+ LINK( this, SvXPropertyComboBox, GetFocusHdl));
+ aComboBox.SetLoseFocusHdl(
+ LINK( this, SvXPropertyComboBox, LoseFocusHdl));
+
+ Size aSize=GetSizePixel();
+ SetCtrSize(aSize);
+ aComboBox.Show();
+}
+
+void SvXPropertyComboBox::SetLocked(BOOL bLocked)
+{
+ if(bLocked)
+ Disable();
+ else
+ Enable();
+}
+
+void SvXPropertyComboBox::SetSvXPropertyCtrListener(SvXPropertyCtrListener* pCtrListener)
+{
+ pListener=pCtrListener;
+}
+
+SvXPropertyCtrListener* SvXPropertyComboBox::GetSvXPropertyCtrListener()
+{
+ return pListener;
+}
+
+
+void SvXPropertyComboBox::SetCtrSize(const Size& rSize)
+{
+ SetSizePixel(rSize);
+ Size aSize=GetOutputSizePixel();
+ Point aPos(0,0);
+ aComboBox.SetPosPixel(aPos);
+ aComboBox.SetSizePixel(aSize);
+}
+
+
+void SvXPropertyComboBox::SetProperty(const String &rString)
+{
+ aComboBox.SetText(rString);
+}
+
+String SvXPropertyComboBox::GetProperty() const
+{
+ return aComboBox.GetText();
+}
+
+BOOL SvXPropertyComboBox::HasList()
+{
+ return TRUE;
+}
+
+void SvXPropertyComboBox::ClearList()
+{
+ aComboBox.Clear();
+}
+
+void SvXPropertyComboBox::InsertEntry( const String& rString,USHORT nPos)
+{
+ aComboBox.InsertEntry(rString,nPos);
+}
+
+void SvXPropertyComboBox::SetMyName(const String &rString)
+{
+ aName=rString;
+}
+
+String SvXPropertyComboBox::GetMyName()const
+{
+ return aName;
+}
+
+void SvXPropertyComboBox::SetMyData(void* pDat)
+{
+ pData=pDat;
+}
+
+void* SvXPropertyComboBox::GetMyData()
+{
+ return pData;
+}
+
+IMPL_LINK( SvXPropertyComboBox, ModifiedHdl, ComboBox*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->Modified(this);
+ return 0;
+}
+
+IMPL_LINK( SvXPropertyComboBox, GetFocusHdl, ComboBox*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->GetFocus(this);
+ return 0;
+}
+
+IMPL_LINK( SvXPropertyComboBox, LoseFocusHdl, ComboBox*, EMPTYARG )
+{
+ if(pListener!=NULL)
+ pListener->LoseFocus(this);
+ return 0;
+}
+//------------------------------------------------------------------
+
+SvPropertyLine::SvPropertyLine( Window* pParent,WinBits nWinStyle)
+ : Control(pParent,nWinStyle),
+ aName(this,WB_BORDER),
+ pSvXPropertyControl(NULL),
+ aXButton(this,WB_BORDER),
+ bIsLocked(FALSE),
+ bIsHyperlink(FALSE)
+{
+ bNeedsRepaint = TRUE;
+ bHasXButton = FALSE;
+ aXButton.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "..." ) ) );
+ aName.Show();
+ aXButton.Show();
+ eKindOfCtr = KOC_UNDEFINED;
+ Wallpaper aWall = GetBackground();
+ aWall.SetColor( Color( COL_TRANSPARENT ) );
+ SetBackground( aWall );
+}
+
+SvPropertyLine::SvPropertyLine( Window* pParent,const ResId& rResId )
+ : Control(pParent,rResId),
+ aName (this,WB_BORDER),
+ pSvXPropertyControl(NULL),
+ aXButton (this,WB_BORDER),
+ bIsLocked(FALSE),
+ bIsHyperlink(FALSE)
+{
+ bNeedsRepaint = TRUE;
+ bHasXButton = FALSE;
+ eKindOfCtr = KOC_UNDEFINED;
+ aXButton.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "..." ) ) );
+ aName.Show();
+ aXButton.Show();
+ Wallpaper aWall = GetBackground();
+ aWall.SetColor( Color( COL_TRANSPARENT ) );
+ SetBackground( aWall );
+ Resize();
+}
+
+void SvPropertyLine::SetSvXPropertyControl(SvXPropertyControl* pXControl)
+{
+ pSvXPropertyControl=pXControl;
+ pSvXPropertyControl->Show();
+ Resize();
+}
+
+SvXPropertyControl* SvPropertyLine::GetSvXPropertyControl()
+{
+ return pSvXPropertyControl;
+}
+
+void SvPropertyLine::Resize()
+{
+ Size aSize=GetOutputSizePixel();
+ Size a2Size=aSize;
+
+ aSize.Width()=nNameWidth;
+ a2Size.Width()-=nNameWidth;
+
+ Point aPos(0,0);
+ aName.SetPosPixel(aPos);
+ aName.SetSizePixel(aSize);
+
+ USHORT nXButtonWidth=0;
+
+ if(bHasXButton)
+ {
+ nXButtonWidth=(USHORT)aSize.Height();
+ }
+ a2Size.Width()=a2Size.Width()-nXButtonWidth;
+
+ aPos.X()+=aSize.Width();
+
+ if(pSvXPropertyControl!=NULL)
+ {
+ pSvXPropertyControl->SetPosPixel(aPos);
+ pSvXPropertyControl->SetCtrSize(a2Size);
+ }
+
+ if(bHasXButton)
+ {
+ aPos.X()=GetOutputSizePixel().Width()
+ -nXButtonWidth;
+ aSize.Width()=nXButtonWidth;
+ aXButton .SetSizePixel(aSize);
+ aXButton .SetPosPixel(aPos);
+ }
+}
+
+void SvPropertyLine::SetNeedsRepaint(BOOL bFlag)
+{
+ bNeedsRepaint=bFlag;
+}
+
+BOOL SvPropertyLine::NeedsRepaint()
+{
+ return bNeedsRepaint;
+}
+
+void SvPropertyLine::SetName(const String& rString )
+{
+ aName.SetText(rString);
+ aName.Invalidate();
+}
+
+String SvPropertyLine::GetName() const
+{
+ return aName.GetText();
+}
+
+void SvPropertyLine::SetKindOfControl(eKindOfControl eKOC)
+{
+ eKindOfCtr=eKOC;
+}
+
+eKindOfControl SvPropertyLine::GetKindOfControl()
+{
+ return eKindOfCtr;
+}
+
+void SvPropertyLine::ShowXButton()
+{
+ bHasXButton=TRUE;
+ aXButton.Show();
+ Resize();
+}
+void SvPropertyLine::HideXButton()
+{
+ bHasXButton=FALSE;
+ aXButton.Hide();
+ Resize();
+}
+BOOL SvPropertyLine::IsVisibleXButton()
+{
+ return bHasXButton;
+}
+
+void SvPropertyLine::ShowAsHyperLink(BOOL nFlag)
+{
+ bIsHyperlink=nFlag;
+ if(nFlag)
+ {
+ Font aFont=GetFont();
+ aFont.SetUnderline(UNDERLINE_SINGLE);
+ aFont.SetColor(Color(COL_BLUE));
+ aName.SetFont(aFont);
+ }
+ else
+ {
+ Font aFont=GetFont();
+ aName.SetFont(aFont);
+ }
+}
+
+BOOL SvPropertyLine::IsShownAsHyperlink()
+{
+ return bIsHyperlink;
+}
+
+void SvPropertyLine::Locked(BOOL nFlag)
+{
+ bIsLocked=nFlag;
+ if(pSvXPropertyControl!=NULL)
+ pSvXPropertyControl->SetLocked(nFlag);
+}
+
+BOOL SvPropertyLine::IsLineLocked()
+{
+ return bIsLocked;
+}
+
+void SvPropertyLine::SetNameWidth(USHORT nWidth)
+{
+ nNameWidth=nWidth;
+ Resize();
+}
+
+void SvPropertyLine::SetClickHdl(const Link& rLink)
+{
+ aXButton.SetClickHdl(rLink );
+}
+
+//----------------------------------------------------------
+
+SvXPropEvListener::SvXPropEvListener()
+{
+ pTheActiveControl=NULL;
+}
+
+SvXPropEvListener::~SvXPropEvListener()
+{
+}
+
+void SvXPropEvListener::Modified (SvXPropertyControl *pSvXPCtr)
+{
+ pTheActiveControl=pSvXPCtr;
+ aModifyLink.Call(this);
+}
+
+void SvXPropEvListener::GetFocus (SvXPropertyControl *pSvXPCtr)
+{
+ pTheActiveControl=pSvXPCtr;
+ aGetFocusLink.Call(this);
+}
+
+void SvXPropEvListener::LoseFocus (SvXPropertyControl *pSvXPCtr)
+{
+ pTheActiveControl=pSvXPCtr;
+ aLoseFocusLink.Call(this);
+}
+
+void SvXPropEvListener::KeyInput (SvXPropertyControl *pSvXPCtr,const KeyCode& theKeyCode)
+{
+ pTheActiveControl=pSvXPCtr;
+ aKeyCode=theKeyCode;
+ aKeyInputLink.Call(this);
+}
+
+SvXPropertyControl * SvXPropEvListener::GetPropertyControl()
+{
+ return pTheActiveControl;
+}
+
+KeyCode SvXPropEvListener::GetKeyCode() const
+{
+ return aKeyCode;
+}
+
+//------------------------------------------------------------------
+
+SvListBoxForProperties::SvListBoxForProperties( Window* pParent, WinBits nWinStyle)
+ : Control(pParent,nWinStyle),
+ aPlayGround(this,WB_DIALOGCONTROL),
+ aVScroll(this,WB_VSCROLL|WB_REPEAT|WB_DRAG),
+ pPropDataControl(NULL)
+{
+
+ aListener.SetModifyHdl (LINK( this, SvListBoxForProperties, ModifyHdl));
+ aListener.SetGetFocusHdl (LINK( this, SvListBoxForProperties, GetFocusHdl));
+ aListener.SetLoseFocusHdl(LINK( this, SvListBoxForProperties,LoseFocusHdl));
+ aListener.SetKeyInputHdl (LINK( this, SvListBoxForProperties, KeyInputHdl));
+
+ nYOffset=0;
+ nTheNameSize=0;
+ ListBox aListBox(this,WB_DROPDOWN);
+ aListBox.SetPosSizePixel(Point(0,0),Size(100,100));
+ nRowHeight=(USHORT)aListBox.GetSizePixel().Height();
+ Wallpaper aWall = aPlayGround.GetBackground();
+ aWall.SetColor( Color( COL_TRANSPARENT ) );
+ aPlayGround.SetBackground( aWall );
+ aPlayGround.Show();
+ aVScroll.Hide();
+ aVScroll.SetScrollHdl(
+ LINK( this, SvListBoxForProperties, ScrollHdl ));
+
+}
+
+
+SvListBoxForProperties::SvListBoxForProperties( Window* pParent, const ResId& rResId )
+ : Control(pParent,rResId),
+ aPlayGround(this,0),
+ aVScroll(this,WB_VSCROLL|WB_REPEAT|WB_DRAG),
+ pPropDataControl(NULL)
+{
+ nTheNameSize=0;
+ nYOffset=0;
+ ListBox aListBox(this,WB_DROPDOWN);
+ aListBox.SetPosSizePixel(Point(0,0),Size(100,100));
+ nRowHeight=(USHORT)aListBox.GetSizePixel().Height();
+ Wallpaper aWall = aPlayGround.GetBackground();
+ aWall.SetColor( Color( COL_TRANSPARENT ) );
+ aPlayGround.SetBackground( aWall );
+ aPlayGround.Show();
+ aVScroll.Hide();
+ aVScroll.SetScrollHdl( LINK( this, SvListBoxForProperties, ScrollHdl ) );
+ UpdateVScroll();
+ Resize();
+}
+
+SvListBoxForProperties::~SvListBoxForProperties()
+{
+ Clear();
+}
+
+void SvListBoxForProperties::Clear()
+{
+ for(USHORT i=0;i<PLineArray.Count();i++)
+ {
+ SvPropertyLine* pPropLine=PLineArray[i];
+
+ switch(pPropLine->GetKindOfControl())
+ {
+ case KOC_LISTBOX:
+ case KOC_COMBOBOX:
+ case KOC_EDIT: delete pPropLine->GetSvXPropertyControl();
+ break;
+ default:
+ break;
+ }
+ delete pPropLine;
+ }
+ PLineArray.Remove(0,PLineArray.Count());
+}
+
+
+void SvListBoxForProperties::Resize()
+{
+ Size aSize=GetOutputSizePixel();
+ Size a2Size=aSize;
+ Size aVScrollSize;
+
+ if(aVScroll.IsVisible())
+ {
+ Point aPos(0,0);
+ aVScrollSize=aVScroll.GetSizePixel();
+ aVScrollSize.Height()=aSize.Height();
+ a2Size.Width()-=aVScrollSize.Width();
+ aPos.X()=a2Size.Width();
+ aVScroll.SetPosPixel(aPos);
+ aVScroll.SetSizePixel(aVScrollSize);
+ }
+
+ aPlayGround.SetPosPixel(Point(0,0));
+ aPlayGround.SetSizePixel(a2Size);
+ UpdatePosNSize();
+}
+
+void SvListBoxForProperties::SetController( SvPropertyDataControl *pPDC)
+{
+ pPropDataControl=pPDC;
+}
+
+USHORT SvListBoxForProperties::CalcVisibleLines()
+{
+ Size aSize=aPlayGround.GetOutputSizePixel();
+ USHORT nResult=0;
+ if(nRowHeight!=0)
+ nResult=(USHORT) aSize.Height()/nRowHeight;
+
+ return nResult;
+}
+
+void SvListBoxForProperties::UpdateVScroll()
+{
+ USHORT nLines=CalcVisibleLines();
+ aVScroll.SetPageSize(nLines-1);
+ aVScroll.SetVisibleSize(nLines-1);
+ aVScroll.SetRange(Range(0,PLineArray.Count()-1));
+ if(PLineArray.Count()<=nLines)
+ {
+ aVScroll.Hide();
+ }
+ else
+ {
+ BOOL bFlag=aVScroll.IsVisible();
+ aVScroll.Show();
+ if(!bFlag)Resize();
+ }
+
+
+}
+
+void SvListBoxForProperties::UpdatePosNSize()
+{
+ Point aPos(0,nYOffset);
+
+ for(USHORT i=0; i<PLineArray.Count();i++)
+ {
+ if((PLineArray[i])->NeedsRepaint())
+ {
+ (PLineArray[i])->SetPosPixel(aPos);
+ Size aSize=aPlayGround.GetOutputSizePixel();
+ aSize.Height()=nRowHeight;
+ (PLineArray[i])->SetSizePixel(aSize);
+ (PLineArray[i])->SetNameWidth(nTheNameSize+2*FRAME_OFFSET);
+ (PLineArray[i])->Invalidate();
+ (PLineArray[i])->Update();
+ (PLineArray[i])->Show();
+ (PLineArray[i])->SetNeedsRepaint(FALSE);
+ }
+ else
+ {
+ if((PLineArray[i])->IsVisible())
+ {
+ Size aSize=aPlayGround.GetOutputSizePixel();
+ aSize.Height()=nRowHeight;
+ (PLineArray[i])->SetSizePixel(aSize);
+ (PLineArray[i])->SetNameWidth(nTheNameSize+2*FRAME_OFFSET);
+ (PLineArray[i])->Invalidate();
+ }
+ }
+
+ aPos.Y()+=nRowHeight;
+ }
+ aPlayGround.Invalidate();
+ aPlayGround.Update();
+}
+
+void SvListBoxForProperties::UpdatePlayGround()
+{
+ Point aPos(0,0);
+ long nThumbPos=aVScroll.GetThumbPos();
+ long nLines=aVScroll.GetPageSize();
+ long nDelta=aVScroll.GetDelta();
+
+ USHORT nStart,nEnd;
+ Size aSize=aPlayGround.GetOutputSizePixel();
+ Point aPEnd;
+ aPEnd.X()=aSize.Width();
+
+ if(nDelta>0)
+ {
+ nStart=(USHORT)(nThumbPos+nLines+1-nDelta);
+ nEnd=(USHORT)(nThumbPos+nLines);
+ aPos.Y()=(nLines+1-nDelta)*nRowHeight;
+ }
+ else
+ {
+ nStart=(USHORT)nThumbPos;
+ nEnd=(USHORT)(nThumbPos-nDelta);
+ aPEnd.Y()=(nThumbPos-nDelta)*nRowHeight;;
+ }
+
+ aSize.Height()=nRowHeight;
+
+ nDelta=-nDelta*nRowHeight;
+
+ aPlayGround.Scroll(0,nDelta,SCROLL_CHILDREN);
+
+ for(USHORT i=nStart; i<=nEnd;i++)
+ {
+ (PLineArray[i])->SetPosSizePixel(aPos,aSize);
+ (PLineArray[i])->SetNameWidth(nTheNameSize+2*FRAME_OFFSET);
+ (PLineArray[i])->Show();
+ aPos.Y()+=nRowHeight;
+ }
+ aPlayGround.Update();
+}
+
+void SvListBoxForProperties::UpdateAll()
+{
+ UpdatePosNSize();
+ UpdatePlayGround();
+ //UpdateVScroll();
+}
+
+void SvListBoxForProperties::DisableUpdate()
+{
+ bUpdate=FALSE;
+}
+
+void SvListBoxForProperties::EnableUpdate()
+{
+ bUpdate=TRUE;
+ UpdateAll();
+}
+
+void SvListBoxForProperties::SetPropertyValue( const String & rEntryName, const String & rValue )
+{
+ USHORT i, iEnd = PLineArray.Count();
+ for( i = 0 ; i < iEnd ; i++ )
+ {
+ SvPropertyLine* pPropLine = PLineArray[ i ];
+ SvXPropertyControl* pSvXPCtr=pPropLine->GetSvXPropertyControl();
+ if( pSvXPCtr && pSvXPCtr->GetMyName() == rEntryName )
+ {
+ pSvXPCtr->SetProperty( rValue );
+ }
+ }
+}
+
+USHORT SvListBoxForProperties::AppendEntry( const SvPropertyData& aPropData)
+{
+ return InsertEntry(aPropData);
+}
+
+USHORT SvListBoxForProperties::InsertEntry( const SvPropertyData& aPropData, USHORT nPos)
+{
+ USHORT nInsPos=nPos;
+ SvPropertyLine* pPropLine=new SvPropertyLine(&aPlayGround,WB_TABSTOP | WB_DIALOGCONTROL);
+
+ if(nPos==LISTBOX_APPEND)
+ {
+ nInsPos=PLineArray.Count();
+ PLineArray.Insert(pPropLine,nInsPos);
+ }
+ else
+ {
+ PLineArray.Insert(pPropLine,nPos);
+ }
+ pPropLine->SetNameWidth(nTheNameSize);
+ UpdateVScroll();
+ UpdatePosNSize();
+ ChangeEntry(aPropData,nInsPos);
+ return nInsPos;
+}
+
+void SvListBoxForProperties::ChangeEntry( const SvPropertyData& aPropData, USHORT nPos)
+{
+ if(nPos<PLineArray.Count())
+ {
+ SvPropertyLine* pPropLine=PLineArray[nPos];
+
+ switch(pPropLine->GetKindOfControl())
+ {
+ case KOC_LISTBOX:
+ case KOC_COMBOBOX:
+ case KOC_EDIT: delete pPropLine->GetSvXPropertyControl();
+ break;
+ default:
+ break;
+ }
+
+ switch(aPropData.eKind)
+ {
+ case KOC_LISTBOX:
+ pPropLine->SetSvXPropertyControl(
+ new SvXPropertyComboBox(pPropLine,WB_TABSTOP));
+ pPropLine->SetKindOfControl(aPropData.eKind);
+ break;
+ case KOC_COMBOBOX:
+ pPropLine->SetSvXPropertyControl(
+ new SvXPropertyComboBox(pPropLine,WB_TABSTOP));
+ pPropLine->SetKindOfControl(aPropData.eKind);
+ break;
+ case KOC_EDIT:
+ pPropLine->SetSvXPropertyControl(
+ new SvXPropertyEdit(pPropLine,WB_TABSTOP));
+ pPropLine->SetKindOfControl(aPropData.eKind);
+ break;
+ case KOC_USERDEFINED:
+ pPropLine->SetSvXPropertyControl(aPropData.pControl);
+ aPropData.pControl->SetParent(pPropLine);
+ pPropLine->SetKindOfControl(aPropData.eKind);
+ break;
+ default:
+ pPropLine->SetSvXPropertyControl(NULL);
+ pPropLine->SetKindOfControl(KOC_UNDEFINED);
+ break;
+ }
+
+ SvXPropertyControl* pSvXPCtr=pPropLine->GetSvXPropertyControl();
+
+ if(pSvXPCtr!=NULL)
+ {
+ pSvXPCtr->SetSvXPropertyCtrListener(&aListener);
+ pSvXPCtr->SetProperty(aPropData.aValue);
+ pSvXPCtr->SetMyData(aPropData.pDataPtr);
+ pSvXPCtr->SetMyName(aPropData.aName);
+
+ if(pSvXPCtr->HasList())
+ {
+ for(USHORT i=0;i<aPropData.theValues.Count();i++)
+ {
+ pSvXPCtr->InsertEntry(*(aPropData.theValues[i]));
+ }
+ }
+ }
+
+ pPropLine->SetName(aPropData.aName);
+
+ USHORT nTextWidth=(USHORT)aPlayGround.GetTextWidth(aPropData.aName);
+
+ if ( nTheNameSize < nTextWidth )
+ nTheNameSize = nTextWidth;
+
+ if ( aPropData.bHasVisibleXButton )
+ {
+ pPropLine->SetClickHdl(LINK( this, SvListBoxForProperties, ClickHdl ) );
+ pPropLine->ShowXButton();
+ }
+ else
+ pPropLine->HideXButton();
+
+ pPropLine->Locked(aPropData.bIsLocked);
+
+ pPropLine->ShowAsHyperLink(aPropData.bIsHyperLink);
+ pPropLine->SetData(aPropData.pDataPtr);
+ }
+}
+
+USHORT SvListBoxForProperties::GetFirstVisibleEntry()
+{
+ return 0;
+}
+void SvListBoxForProperties::SetFirstVisibleEntry(USHORT)
+{
+ return;
+}
+
+void SvListBoxForProperties::SetSelectedEntry(USHORT)
+{
+ return;
+}
+
+USHORT SvListBoxForProperties::GetSelectedEntry()
+{
+ return 0;
+}
+
+IMPL_LINK( SvListBoxForProperties, ScrollHdl, ScrollBar*, pSB )
+{
+ if(pSB!=NULL)
+ {
+ long nDelta=aVScroll.GetDelta();
+ nYOffset=-aVScroll.GetThumbPos()*nRowHeight;
+ //aPlayGround.SetUpdateMode(FALSE);
+
+ long nThumbPos=aVScroll.GetThumbPos();
+ long nLines=aVScroll.GetPageSize();
+
+ UpdatePlayGround();
+
+ for(long i=nThumbPos-nDelta; i<nThumbPos+nLines-nDelta;i++)
+ {
+ if(i>=nThumbPos && i<=nThumbPos+nLines)
+ {
+ (PLineArray[sal::static_int_cast< USHORT >(i)])->
+ SetNeedsRepaint(TRUE);
+ }
+ else
+ {
+ (PLineArray[sal::static_int_cast< USHORT >(i)])->Hide();
+ (PLineArray[sal::static_int_cast< USHORT >(i)])->
+ SetNeedsRepaint(FALSE);
+ }
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( SvListBoxForProperties, ClickHdl, PushButton*,pPB)
+{
+ if(pPB!=NULL)
+ {
+ SvPropertyLine *pPropLine=(SvPropertyLine *)pPB->GetParent();
+ SvXPropertyControl* pSvXPCtr=pPropLine->GetSvXPropertyControl();
+ pPropDataControl->Clicked(pSvXPCtr->GetMyName(),
+ pSvXPCtr->GetProperty(),pSvXPCtr->GetMyData());
+ }
+ return 0;
+}
+
+IMPL_LINK( SvListBoxForProperties, ModifyHdl,SvXPropEvListener*, pSvXPEvL)
+{
+ if(pSvXPEvL!=NULL && pPropDataControl!=NULL)
+ {
+
+ SvXPropertyControl* pSvXPCtr=aListener.GetPropertyControl();
+
+ pPropDataControl->Modified(pSvXPCtr->GetMyName(),
+ pSvXPCtr->GetProperty(),pSvXPCtr->GetMyData());
+
+ }
+ return 0;
+}
+
+IMPL_LINK( SvListBoxForProperties, GetFocusHdl,SvXPropEvListener*, pSvXPEvL)
+{
+ if(pSvXPEvL!=NULL && pPropDataControl!=NULL)
+ {
+ SvXPropertyControl* pSvXPCtr=aListener.GetPropertyControl();
+
+ pPropDataControl->Select(pSvXPCtr->GetMyName(),pSvXPCtr->GetMyData());
+ }
+ return 0;
+}
+
+IMPL_LINK( SvListBoxForProperties, LoseFocusHdl,SvXPropEvListener*, pSvXPEvL)
+{
+ if(pSvXPEvL!=NULL && pPropDataControl!=NULL)
+ {
+ SvXPropertyControl* pSvXPCtr=aListener.GetPropertyControl();
+
+ pPropDataControl->Commit(pSvXPCtr->GetMyName(),
+ pSvXPCtr->GetProperty(),pSvXPCtr->GetMyData());
+ /*
+ {
+ pSvXPCtr->SetProperty(
+ pPropDataControl->GetTheCorrectProperty());
+ }
+ */
+ }
+ return 0;
+}
+
+IMPL_LINK( SvListBoxForProperties, KeyInputHdl,SvXPropEvListener*, pSvXPEvL)
+{
+ // FIXME - This code does not make a lot of sense.
+ if(pSvXPEvL!=NULL && pPropDataControl!=NULL)
+ {
+ /*SvXPropertyControl* pSvXPCtr=*/aListener.GetPropertyControl();
+ }
+ return 0;
+}
+
+
+
+
+SvTabPageForProperties::SvTabPageForProperties(Window* pParent,WinBits nWinStyle)
+ : TabPage(pParent,nWinStyle),
+ aLbProp(this)
+{
+ aLbProp.Show();
+}
+
+void SvTabPageForProperties::Resize()
+{
+ Point aPos(3,3);
+ Size aSize=GetOutputSizePixel();
+ aSize.Width()-=6;
+ aSize.Height()-=6;
+
+ aLbProp.SetPosSizePixel(aPos,aSize);
+}
+
+SvListBoxForProperties* SvTabPageForProperties::GetTheListBox()
+{
+ return &aLbProp;
+}
+
+
+SvPropertyBox::SvPropertyBox( Window* pParent, WinBits nWinStyle)
+ : Control(pParent,nWinStyle),
+ aTabControl(this)
+{
+ aTabControl.Show();
+}
+
+SvPropertyBox::SvPropertyBox( Window* pParent, const ResId& rResId )
+ : Control(pParent,rResId),
+ aTabControl(this)
+{
+ aTabControl.Show();
+ Resize();
+}
+
+SvPropertyBox::~SvPropertyBox()
+{
+ ClearAll();
+}
+
+
+void SvPropertyBox::ClearAll()
+{
+ USHORT nCount=aTabControl.GetPageCount();
+
+ for(USHORT i=nCount;i>=1;i--)
+ {
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(i);
+ aTabControl.RemovePage(i);
+ delete pPage;
+ }
+}
+
+
+void SvPropertyBox::Resize()
+{
+ Point aPos(3,3);
+ Size aSize=GetOutputSizePixel();
+ aSize.Width()-=6;
+ aSize.Height()-=6;
+
+ aTabControl.SetPosSizePixel(aPos,aSize);
+
+ USHORT nCount=aTabControl.GetPageCount();
+
+ aSize=aTabControl.GetTabPageSizePixel();
+ for(USHORT i=1;i<=nCount;i++)
+ {
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(i);
+ pPage->SetSizePixel(aSize);
+ }
+
+}
+
+
+USHORT SvPropertyBox::AppendPage( const String & rText )
+{
+ USHORT nId=aTabControl.GetPageCount()+1;
+ aTabControl.InsertPage( nId,rText);
+ SvTabPageForProperties* pPage=new SvTabPageForProperties(&aTabControl);
+ pPage->SetSizePixel(aTabControl.GetTabPageSizePixel());
+ pPage->GetTheListBox()->SetController(pThePropDataCtr);
+ aTabControl.SetTabPage( nId, pPage);
+ aTabControl.SetCurPageId(nId);
+ return nId;
+}
+
+void SvPropertyBox::SetPage( USHORT nId)
+{
+ aTabControl.SetCurPageId(nId);
+}
+
+USHORT SvPropertyBox::GetCurPage()
+{
+ return aTabControl.GetCurPageId();
+}
+
+USHORT SvPropertyBox::CalcVisibleLines()
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ return pPage->GetTheListBox()->CalcVisibleLines();
+}
+void SvPropertyBox::EnableUpdate()
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->EnableUpdate();
+}
+
+void SvPropertyBox::DisableUpdate()
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->DisableUpdate();
+}
+
+void SvPropertyBox::SetController(SvPropertyDataControl *pDataCtr)
+{
+ pThePropDataCtr=pDataCtr;
+ USHORT nCount=aTabControl.GetPageCount();
+
+ for(USHORT i=1;i<=nCount;i++)
+ {
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(i);
+
+ pPage->GetTheListBox()->SetController(pThePropDataCtr);
+ }
+
+}
+
+USHORT SvPropertyBox::InsertEntry( const SvPropertyData& rData, USHORT nPos)
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ return pPage->GetTheListBox()->InsertEntry(rData,nPos);
+}
+
+void SvPropertyBox::ChangeEntry( const SvPropertyData& rData, USHORT nPos)
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->ChangeEntry(rData,nPos);
+}
+
+USHORT SvPropertyBox::AppendEntry( const SvPropertyData& rData)
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ return pPage->GetTheListBox()->AppendEntry(rData);
+}
+
+void SvPropertyBox::SetPropertyValue( const String & rEntryName, const String & rValue )
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->SetPropertyValue( rEntryName, rValue );
+}
+
+void SvPropertyBox::SetFirstVisibleEntry(USHORT nPos)
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->SetFirstVisibleEntry(nPos);
+}
+USHORT SvPropertyBox::GetFirstVisibleEntry()
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ return pPage->GetTheListBox()->GetFirstVisibleEntry();
+}
+
+void SvPropertyBox::SetSelectedEntry(USHORT nPos)
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->SetSelectedEntry(nPos);
+}
+USHORT SvPropertyBox::GetSelectedEntry()
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ return pPage->GetTheListBox()->GetSelectedEntry();
+}
+
+void SvPropertyBox::ClearTable()
+{
+ SvTabPageForProperties* pPage=(SvTabPageForProperties*)
+ aTabControl.GetTabPage(aTabControl.GetCurPageId());
+ pPage->GetTheListBox()->Clear();
+}
+
+SvBasicPropertyDataControl::~SvBasicPropertyDataControl()
+{
+}
+
+void SvBasicPropertyDataControl::Modified(const String& aName,
+ const String& aVal,void* pData)
+{
+ aEntryName=aName;
+ aEntryProperty=aVal;
+ pTheData=pData;
+ aModifyLink.Call(this);
+}
+
+void SvBasicPropertyDataControl::Clicked( const String& aName,
+ const String& aVal,
+ void* pData) //Xtension-Button pressed
+{
+ aEntryName=aName;
+ aEntryProperty=aVal;
+ pTheData=pData;
+ aClickedLink.Call(this);
+}
+
+void SvBasicPropertyDataControl::Commit( const String& aName,
+ const String& aVal,
+ void* pData) //User accept changes
+{
+ aEntryName=aName;
+ aEntryProperty=aVal;
+ pTheData=pData;
+ aCommitLink.Call(this);
+}
+
+void SvBasicPropertyDataControl::Select( const String& aName,
+ void* pData) //User select new Row
+{
+ aEntryName=aName;
+ pTheData=pData;
+ aSelectLink.Call(this);
+}
+
+void SvBasicPropertyDataControl::LinkClicked(const String&, void*)
+{
+}
+
+
+String SvBasicPropertyDataControl::GetName() const //Tell's the name of the Property
+{
+ return aEntryName;
+}
+
+String SvBasicPropertyDataControl::GetProperty() const //Tell's the content of the Property
+{
+ return aEntryProperty;
+}
+
+void* SvBasicPropertyDataControl::GetData() //Tell's the storage
+{
+ return pTheData;
+}
+
+/*
+String SvBasicPropertyDataControl::GetTheCorrectProperty() const
+{
+ return aCorrectProperty;
+}
+*/
+
+void SvBasicPropertyDataControl::SetTheCorrectProperty(const String& aString)
+{
+ aCorrectProperty=aString;
+}
+
+void SvBasicPropertyDataControl::SetIsCorrect(BOOL nFlag)
+{
+ bCorrectness=nFlag;
+}
+
+
+
+//========================================================================
+// Property-Dialog:
+/* zum TESTEN im CALC*/
+//========================================================================
+/*
+ScPropertyDlg::ScPropertyDlg( Window* pParent) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_PROPERTIES) ),
+ aPropListBox ( this, ResId( CTR_PROPLINE) ),
+ aKindOfListBox (this,ResId( LB_KIND_OF_PROP)),
+ aModAnswer (this,ResId(FT_ANSMOD )),
+ aClickAnswer (this,ResId(FT_ANSCLICK )),
+ aCommitAnswer (this,ResId(FT_ANSCOMMIT)),
+ aSelectAnswer (this,ResId(FT_ANSSELECT)),
+ anOk(this,ResId( BTN_OK)),
+ aCancel(this,ResId( BTN_CANCEL))
+{
+ FreeResource();
+
+ aKindOfListBox.SelectEntryPos(0);
+ aKindOfListBox.SetSelectHdl(
+ LINK( this, ScPropertyDlg, ModifiedHdl ));
+ nCount=0;
+ nClickCount=0;
+
+ String aString("Don't know ");
+
+ aBaProDatCtr.SetModifyHdl (LINK( this, ScPropertyDlg, RowModifiedHdl ));
+ aBaProDatCtr.SetClickedHdl(LINK( this, ScPropertyDlg, ClickHdl ));
+ aBaProDatCtr.SetCommitHdl (LINK( this, ScPropertyDlg, SelectHdl ));
+ aBaProDatCtr.SetSelectHdl (LINK( this, ScPropertyDlg, CommitHdl ));
+
+ aPropListBox.SetController(&aBaProDatCtr);
+
+ USHORT nPageId=aPropListBox.AppendPage("YabbaDabbaDo");
+ aPropListBox.SetPage(nPageId);
+ aProperty.eKind=KOC_EDIT;
+ aProperty.aName=aString;
+ aProperty.aName+=String((USHORT)++nCount);
+ aProperty.aValue=sizeof ComboBox;
+ aProperty.bHasVisibleXButton=FALSE;
+ aProperty.bIsHyperLink=FALSE;
+ aProperty.bIsLocked=FALSE;
+ aProperty.pDataPtr=NULL;
+ aProperty.pControl=NULL;
+ aProperty.theValues.Insert(new String("1"),aProperty.theValues.Count());
+ aProperty.theValues.Insert(new String("2"),aProperty.theValues.Count());
+ aProperty.theValues.Insert(new String("3"),aProperty.theValues.Count());
+ aProperty.theValues.Insert(new String("4"),aProperty.theValues.Count());
+ aPropListBox.InsertEntry(aProperty);
+ aProperty.bHasVisibleXButton=TRUE;
+ aProperty.aName=aString;
+ aProperty.aName+=String((USHORT)++nCount);
+ aProperty.aValue="42";
+ aProperty.eKind=KOC_LISTBOX;
+ aPropListBox.InsertEntry(aProperty);
+ aProperty.aName=aString;
+ aProperty.aName+=String((USHORT)++nCount);
+ aProperty.eKind=KOC_COMBOBOX;
+ aProperty.bHasVisibleXButton=FALSE;
+ aPropListBox.InsertEntry(aProperty);
+}
+
+ScPropertyDlg::~ScPropertyDlg()
+{
+ delete aProperty.theValues[0];
+ delete aProperty.theValues[1];
+ delete aProperty.theValues[2];
+ delete aProperty.theValues[3];
+}
+
+IMPL_LINK( ScPropertyDlg, ModifiedHdl, ListBox*, pLB )
+{
+ if(pLB!=NULL)
+ {
+ String aString("Don't know ");
+ aProperty.aName=aString;
+ aProperty.aName+=String((USHORT)++nCount);
+ if(nCount>20)
+ {
+ String aStr("Yabba ");
+ aStr+=aPropListBox.GetCurPage();
+ USHORT nPageId=aPropListBox.AppendPage(aStr);
+ aPropListBox.SetPage(nPageId);
+ nCount=0;
+ }
+
+ aProperty.eKind=(eKindOfControl)(aKindOfListBox.GetSelectEntryPos()+1);
+ aProperty.bHasVisibleXButton=FALSE;
+ if((nCount % 5)==0) aProperty.bHasVisibleXButton=TRUE;
+ aPropListBox.InsertEntry(aProperty);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScPropertyDlg, RowModifiedHdl, SvBasicPropertyDataControl* ,pProCtr)
+{
+ if(pProCtr!=NULL)
+ {
+ aModAnswer.SetText(aBaProDatCtr.GetProperty());
+ aModAnswer.Invalidate();
+ aBaProDatCtr.SetIsCorrect(TRUE);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScPropertyDlg, CommitHdl, SvBasicPropertyDataControl*,pProCtr)
+{
+ if(pProCtr!=NULL)
+ {
+ aCommitAnswer.SetText(aBaProDatCtr.GetProperty());
+ aCommitAnswer.Invalidate();
+ aBaProDatCtr.SetIsCorrect(TRUE);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScPropertyDlg, ClickHdl, SvBasicPropertyDataControl*,pProCtr)
+{
+ if(pProCtr!=NULL)
+ {
+ aClickAnswer.SetText(aBaProDatCtr.GetName());
+ aClickAnswer.Invalidate();
+ aBaProDatCtr.SetIsCorrect(TRUE);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScPropertyDlg, SelectHdl, SvBasicPropertyDataControl*,pProCtr)
+{
+ if(pProCtr!=NULL)
+ {
+ aSelectAnswer.SetText(aBaProDatCtr.GetName());
+ aSelectAnswer.Invalidate();
+ aBaProDatCtr.SetIsCorrect(TRUE);
+ }
+ return 0;
+}
+*/
+
+
diff --git a/svtools/source/dialogs/roadmapwizard.cxx b/svtools/source/dialogs/roadmapwizard.cxx
new file mode 100644
index 000000000000..c28cfe1d4b18
--- /dev/null
+++ b/svtools/source/dialogs/roadmapwizard.cxx
@@ -0,0 +1,748 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/roadmapwizard.hxx>
+#include <svtools/svtools.hrc>
+#include <svtools/svtdata.hxx>
+#include "roadmap.hxx"
+#include <tools/debug.hxx>
+
+#include <stdarg.h>
+
+#include <vector>
+#include <map>
+#include <set>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ namespace
+ {
+ typedef ::std::set< WizardTypes::WizardState > StateSet;
+
+ typedef ::std::map<
+ RoadmapWizardTypes::PathId,
+ RoadmapWizardTypes::WizardPath
+ > Paths;
+
+ typedef ::std::map<
+ WizardTypes::WizardState,
+ ::std::pair<
+ String,
+ RoadmapWizardTypes::RoadmapPageFactory
+ >
+ > StateDescriptions;
+ }
+
+ struct RoadmapWizardImpl : public RoadmapWizardTypes
+ {
+ ORoadmap* pRoadmap;
+ Paths aPaths;
+ PathId nActivePath;
+ StateDescriptions aStateDescriptors;
+ StateSet aDisabledStates;
+ bool bActivePathIsDefinite;
+ FixedLine* pFixedLine;
+
+ RoadmapWizardImpl()
+ :pRoadmap( NULL )
+ ,nActivePath( -1 )
+ ,bActivePathIsDefinite( false )
+ ,pFixedLine(NULL)
+ {
+ }
+
+ ~RoadmapWizardImpl()
+ {
+ delete pRoadmap;
+ delete pFixedLine;
+ }
+
+ /// returns the index of the current state in given path, or -1
+ sal_Int32 getStateIndexInPath( WizardTypes::WizardState _nState, const WizardPath& _rPath );
+ /// returns the index of the current state in the path with the given id, or -1
+ sal_Int32 getStateIndexInPath( WizardTypes::WizardState _nState, PathId _nPathId );
+ /// returns the index of the first state in which the two given paths differ
+ sal_Int32 getFirstDifferentIndex( const WizardPath& _rLHS, const WizardPath& _rRHS );
+ };
+
+ //--------------------------------------------------------------------
+ sal_Int32 RoadmapWizardImpl::getStateIndexInPath( WizardTypes::WizardState _nState, const WizardPath& _rPath )
+ {
+ sal_Int32 nStateIndexInPath = 0;
+ WizardPath::const_iterator aPathLoop = _rPath.begin();
+ for ( ; aPathLoop != _rPath.end(); ++aPathLoop, ++nStateIndexInPath )
+ if ( *aPathLoop == _nState )
+ break;
+ if ( aPathLoop == _rPath.end() )
+ nStateIndexInPath = -1;
+ return nStateIndexInPath;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 RoadmapWizardImpl::getStateIndexInPath( WizardTypes::WizardState _nState, PathId _nPathId )
+ {
+ sal_Int32 nStateIndexInPath = -1;
+ Paths::const_iterator aPathPos = aPaths.find( _nPathId );
+ if ( aPathPos != aPaths.end( ) )
+ nStateIndexInPath = getStateIndexInPath( _nState, aPathPos->second );
+ return nStateIndexInPath;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 RoadmapWizardImpl::getFirstDifferentIndex( const WizardPath& _rLHS, const WizardPath& _rRHS )
+ {
+ sal_Int32 nMinLength = ::std::min( _rLHS.size(), _rRHS.size() );
+ for ( sal_Int32 nCheck = 0; nCheck < nMinLength; ++nCheck )
+ {
+ if ( _rLHS[ nCheck ] != _rRHS[ nCheck ] )
+ return nCheck;
+ }
+ return nMinLength;
+ }
+
+ //====================================================================
+ //= RoadmapWizard
+ //====================================================================
+ DBG_NAME( RoadmapWizard )
+ //--------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+ const char* CheckInvariants( const void* pVoid )
+ {
+ return static_cast< const RoadmapWizard* >( pVoid )->checkInvariants();
+ }
+
+ //--------------------------------------------------------------------
+ const sal_Char* RoadmapWizard::checkInvariants() const
+ {
+ // all paths have to start with the same state
+ WizardState nSharedFirstState = WZS_INVALID_STATE;
+ for ( Paths::const_iterator aPath = m_pImpl->aPaths.begin();
+ aPath != m_pImpl->aPaths.end();
+ ++aPath
+ )
+ {
+ if ( aPath->second.empty() )
+ return "RoadmapWizard::checkInvariants: paths should not be empty!";
+
+ if ( nSharedFirstState == WZS_INVALID_STATE )
+ // first path
+ nSharedFirstState = aPath->second[ 0 ];
+ else
+ if ( nSharedFirstState != aPath->second[ 0 ] )
+ return "RoadmapWizard::checkInvariants: alls paths must start with the same state!";
+ }
+
+ if ( !m_pImpl->aPaths.empty() )
+ {
+ Paths::const_iterator aCurrentPathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath );
+ if ( aCurrentPathPos == m_pImpl->aPaths.end() )
+ return "RoadmapWizard::checkInvariants: invalid active path!";
+
+ if ( -1 == m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath ) )
+ return "RoadmapWizard::checkInvariants: the current state is not part of the current path!";
+ }
+
+ return NULL;
+ }
+#endif
+
+ //--------------------------------------------------------------------
+ RoadmapWizard::RoadmapWizard( Window* _pParent, const ResId& _rRes, sal_uInt32 _nButtonFlags )
+ :OWizardMachine( _pParent, _rRes, _nButtonFlags )
+ ,m_pImpl( new RoadmapWizardImpl )
+ {
+ DBG_CTOR( RoadmapWizard, CheckInvariants );
+ impl_construct();
+ }
+
+ //--------------------------------------------------------------------
+ RoadmapWizard::RoadmapWizard( Window* _pParent, const WinBits i_nStyle, sal_uInt32 _nButtonFlags )
+ :OWizardMachine( _pParent, i_nStyle, _nButtonFlags )
+ ,m_pImpl( new RoadmapWizardImpl )
+ {
+ DBG_CTOR( RoadmapWizard, CheckInvariants );
+ impl_construct();
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::impl_construct()
+ {
+ SetLeftAlignedButtonCount( 1 );
+ SetEmptyViewMargin();
+
+ m_pImpl->pRoadmap = new ORoadmap( this, WB_TABSTOP );
+ m_pImpl->pRoadmap->SetText( SvtResId( STR_WIZDLG_ROADMAP_TITLE ) );
+ m_pImpl->pRoadmap->SetPosPixel( Point( 0, 0 ) );
+ m_pImpl->pRoadmap->SetItemSelectHdl( LINK( this, RoadmapWizard, OnRoadmapItemSelected ) );
+
+ Size aRoadmapSize =( LogicToPixel( Size( 85, 0 ), MAP_APPFONT ) );
+ aRoadmapSize.Height() = GetSizePixel().Height();
+ m_pImpl->pRoadmap->SetSizePixel( aRoadmapSize );
+
+ m_pImpl->pFixedLine = new FixedLine( this, WB_VERT );
+ m_pImpl->pFixedLine->Show();
+ m_pImpl->pFixedLine->SetPosPixel( Point( aRoadmapSize.Width() + 1, 0 ) );
+ m_pImpl->pFixedLine->SetSizePixel( Size( LogicToPixel( Size( 2, 0 ) ).Width(), aRoadmapSize.Height() ) );
+
+ SetViewWindow( m_pImpl->pRoadmap );
+ SetViewAlign( WINDOWALIGN_LEFT );
+ m_pImpl->pRoadmap->Show();
+ }
+
+ //--------------------------------------------------------------------
+ RoadmapWizard::~RoadmapWizard()
+ {
+ delete m_pImpl;
+ DBG_DTOR( RoadmapWizard, CheckInvariants );
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::SetRoadmapBitmap( const BitmapEx& _rBitmap )
+ {
+ m_pImpl->pRoadmap->SetRoadmapBitmap( _rBitmap );
+ }
+
+ //--------------------------------------------------------------------
+ const BitmapEx& RoadmapWizard::GetRoadmapBitmap( ) const
+ {
+ return m_pImpl->pRoadmap->GetRoadmapBitmap();
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::SetRoadmapSmartHelpId( const SmartId& _rId, SmartIdUpdateMode _aMode )
+ {
+ m_pImpl->pRoadmap->SetSmartHelpId( _rId, _aMode );
+ }
+
+ //--------------------------------------------------------------------
+ SmartId RoadmapWizard::GetRoadmapSmartHelpId() const
+ {
+ return m_pImpl->pRoadmap->GetSmartHelpId();
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::SetRoadmapInteractive( sal_Bool _bInteractive )
+ {
+ m_pImpl->pRoadmap->SetRoadmapInteractive( _bInteractive );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool RoadmapWizard::IsRoadmapInteractive()
+ {
+ return m_pImpl->pRoadmap->IsRoadmapInteractive();
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::declarePath( PathId _nPathId, const WizardPath& _lWizardStates)
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ m_pImpl->aPaths.insert( Paths::value_type( _nPathId, _lWizardStates ) );
+
+ if ( m_pImpl->aPaths.size() == 1 )
+ // the very first path -> activate it
+ activatePath( _nPathId, false );
+ else
+ implUpdateRoadmap( );
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::declarePath( PathId _nPathId, WizardState _nFirstState, ... )
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ DBG_ASSERT( _nFirstState != WZS_INVALID_STATE, "RoadmapWizard::declarePath: there should be at least one state in the path!" );
+ if ( _nFirstState == WZS_INVALID_STATE )
+ return;
+
+ WizardPath aNewPath;
+
+ // collect the elements of the path
+ va_list aStateList;
+ va_start( aStateList, _nFirstState );
+
+ WizardState nState = _nFirstState;
+ while ( nState != WZS_INVALID_STATE )
+ {
+ aNewPath.push_back( nState );
+ nState = sal::static_int_cast< WizardState >(
+ va_arg( aStateList, int ));
+ }
+ va_end( aStateList );
+
+ DBG_ASSERT( _nFirstState == 0, "RoadmapWizard::declarePath: first state must be NULL." );
+ // The WizardDialog (our very base class) always starts with a mnCurLevel == 0
+
+ declarePath( _nPathId, aNewPath );
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::describeState( WizardState _nState, const String& _rStateDisplayName, RoadmapPageFactory _pPageFactory )
+ {
+ OSL_ENSURE( m_pImpl->aStateDescriptors.find( _nState ) == m_pImpl->aStateDescriptors.end(),
+ "RoadmapWizard::describeState: there already is a descriptor for this state!" );
+ m_pImpl->aStateDescriptors[ _nState ] = StateDescriptions::mapped_type( _rStateDisplayName, _pPageFactory );
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::activatePath( PathId _nPathId, bool _bDecideForIt )
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ if ( ( _nPathId == m_pImpl->nActivePath ) && ( _bDecideForIt == m_pImpl->bActivePathIsDefinite ) )
+ // nothing to do
+ return;
+
+ // does the given path exist?
+ Paths::const_iterator aNewPathPos = m_pImpl->aPaths.find( _nPathId );
+ DBG_ASSERT( aNewPathPos != m_pImpl->aPaths.end(), "RoadmapWizard::activate: there is no such path!" );
+ if ( aNewPathPos == m_pImpl->aPaths.end() )
+ return;
+
+ // determine the index of the current state in the current path
+ sal_Int32 nCurrentStatePathIndex = -1;
+ if ( m_pImpl->nActivePath != -1 )
+ nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
+
+ DBG_ASSERT( (sal_Int32)aNewPathPos->second.size() > nCurrentStatePathIndex,
+ "RoadmapWizard::activate: you cannot activate a path which has less states than we've already advanced!" );
+ // If this asserts, this for instance means that we are already in state number, say, 5
+ // of our current path, and the caller tries to activate a path which has less than 5
+ // states
+ if ( (sal_Int32)aNewPathPos->second.size() <= nCurrentStatePathIndex )
+ return;
+
+ // assert that the current and the new path are equal, up to nCurrentStatePathIndex
+ Paths::const_iterator aActivePathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath );
+ if ( aActivePathPos != m_pImpl->aPaths.end() )
+ {
+ if ( m_pImpl->getFirstDifferentIndex( aActivePathPos->second, aNewPathPos->second ) <= nCurrentStatePathIndex )
+ {
+ OSL_ENSURE( false, "RoadmapWizard::activate: you cannot activate a path which conflicts with the current one *before* the current state!" );
+ return;
+ }
+ }
+
+ m_pImpl->nActivePath = _nPathId;
+ m_pImpl->bActivePathIsDefinite = _bDecideForIt;
+
+ implUpdateRoadmap( );
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::implUpdateRoadmap( )
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ DBG_ASSERT( m_pImpl->aPaths.find( m_pImpl->nActivePath ) != m_pImpl->aPaths.end(),
+ "RoadmapWizard::implUpdateRoadmap: there is no such path!" );
+ const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
+
+ sal_Int32 nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), rActivePath );
+
+ // determine up to which index (in the new path) we have to display the items
+ RoadmapTypes::ItemIndex nUpperStepBoundary = (RoadmapTypes::ItemIndex)rActivePath.size();
+ sal_Bool bIncompletePath = sal_False;
+ if ( !m_pImpl->bActivePathIsDefinite )
+ {
+ for ( Paths::const_iterator aPathPos = m_pImpl->aPaths.begin();
+ aPathPos != m_pImpl->aPaths.end();
+ ++aPathPos
+ )
+ {
+ if ( aPathPos->first == m_pImpl->nActivePath )
+ // it's the path we are just activating -> no need to check anything
+ continue;
+ // the index from which on both paths differ
+ sal_Int32 nDivergenceIndex = m_pImpl->getFirstDifferentIndex( rActivePath, aPathPos->second );
+ if ( nDivergenceIndex <= nCurrentStatePathIndex )
+ // they differ in an index which we have already left behind us
+ // -> this is no conflict anymore
+ continue;
+
+ // the path conflicts with our new path -> don't activate the
+ // *complete* new path, but only up to the step which is unambiguous
+ nUpperStepBoundary = nDivergenceIndex;
+ bIncompletePath = sal_True;
+ }
+ }
+
+ // can we advance from the current page?
+ bool bCurrentPageCanAdvance = true;
+ TabPage* pCurrentPage = GetPage( getCurrentState() );
+ if ( pCurrentPage )
+ {
+ const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
+ OSL_ENSURE( pController != NULL, "RoadmapWizard::implUpdateRoadmap: no controller for the current page!" );
+ bCurrentPageCanAdvance = !pController || pController->canAdvance();
+ }
+
+ // now, we have to remove all items after nCurrentStatePathIndex, and insert the items from the active
+ // path, up to (excluding) nUpperStepBoundary
+ RoadmapTypes::ItemIndex nLoopUntil = ::std::max( (RoadmapTypes::ItemIndex)nUpperStepBoundary, m_pImpl->pRoadmap->GetItemCount() );
+ for ( RoadmapTypes::ItemIndex nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex )
+ {
+ bool bExistentItem = ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() );
+ bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
+
+ bool bInsertItem = false;
+ if ( bExistentItem )
+ {
+ if ( !bNeedItem )
+ {
+ while ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() )
+ m_pImpl->pRoadmap->DeleteRoadmapItem( nItemIndex );
+ break;
+ }
+ else
+ {
+ // there is an item with this index in the roadmap - does it match what is requested by
+ // the respective state in the active path?
+ RoadmapTypes::ItemId nPresentItemId = m_pImpl->pRoadmap->GetItemID( nItemIndex );
+ WizardState nRequiredState = rActivePath[ nItemIndex ];
+ if ( nPresentItemId != nRequiredState )
+ {
+ m_pImpl->pRoadmap->DeleteRoadmapItem( nItemIndex );
+ bInsertItem = true;
+ }
+ }
+ }
+ else
+ {
+ DBG_ASSERT( bNeedItem, "RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
+ bInsertItem = bNeedItem;
+ }
+
+ WizardState nState( rActivePath[ nItemIndex ] );
+ if ( bInsertItem )
+ {
+ m_pImpl->pRoadmap->InsertRoadmapItem(
+ nItemIndex,
+ getStateDisplayName( nState ),
+ nState
+ );
+ }
+
+ // if the item is *after* the current state, but the current page does not
+ // allow advancing, the disable the state. This relieves derived classes
+ // from disabling all future states just because the current state does not
+ // (yet) allow advancing.
+ const bool nUnconditionedDisable = !bCurrentPageCanAdvance && ( nItemIndex > nCurrentStatePathIndex );
+ const bool bEnable = !nUnconditionedDisable && ( m_pImpl->aDisabledStates.find( nState ) == m_pImpl->aDisabledStates.end() );
+
+ m_pImpl->pRoadmap->EnableRoadmapItem( m_pImpl->pRoadmap->GetItemID( nItemIndex ), bEnable );
+ }
+
+ m_pImpl->pRoadmap->SetRoadmapComplete( !bIncompletePath );
+ }
+
+ //--------------------------------------------------------------------
+ WizardTypes::WizardState RoadmapWizard::determineNextState( WizardState _nCurrentState ) const
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ sal_Int32 nCurrentStatePathIndex = -1;
+
+ Paths::const_iterator aActivePathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath );
+ if ( aActivePathPos != m_pImpl->aPaths.end() )
+ nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( _nCurrentState, aActivePathPos->second );
+
+ DBG_ASSERT( nCurrentStatePathIndex != -1, "RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" );
+ if ( nCurrentStatePathIndex == -1 )
+ return WZS_INVALID_STATE;
+
+ sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1;
+
+ while ( ( nNextStateIndex < (sal_Int32)aActivePathPos->second.size() )
+ && ( m_pImpl->aDisabledStates.find( aActivePathPos->second[ nNextStateIndex ] ) != m_pImpl->aDisabledStates.end() )
+ )
+ {
+ ++nNextStateIndex;
+ }
+
+ if ( nNextStateIndex >= (sal_Int32)aActivePathPos->second.size() )
+ // there is no next state in the current path (at least none which is enabled)
+ return WZS_INVALID_STATE;
+
+ return aActivePathPos->second[ nNextStateIndex ];
+ }
+
+ //---------------------------------------------------------------------
+ bool RoadmapWizard::canAdvance() const
+ {
+ if ( !m_pImpl->bActivePathIsDefinite )
+ {
+ // check how many paths are still allowed
+ const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
+ sal_Int32 nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), rActivePath );
+
+ size_t nPossiblePaths(0);
+ for ( Paths::const_iterator aPathPos = m_pImpl->aPaths.begin();
+ aPathPos != m_pImpl->aPaths.end();
+ ++aPathPos
+ )
+ {
+ // the index from which on both paths differ
+ sal_Int32 nDivergenceIndex = m_pImpl->getFirstDifferentIndex( rActivePath, aPathPos->second );
+
+ if ( nDivergenceIndex > nCurrentStatePathIndex )
+ // this path is still a possible path
+ nPossiblePaths += 1;
+ }
+
+ // if we have more than one path which is still possible, then we assume
+ // to always have a next state. Though there might be scenarios where this
+ // is not true, but this is too sophisticated (means not really needed) right now.
+ if ( nPossiblePaths > 1 )
+ return true;
+ }
+
+ const WizardPath& rPath = m_pImpl->aPaths[ m_pImpl->nActivePath ];
+ if ( *rPath.rbegin() == getCurrentState() )
+ return false;
+
+ return true;
+ }
+
+ //---------------------------------------------------------------------
+ void RoadmapWizard::updateTravelUI()
+ {
+ OWizardMachine::updateTravelUI();
+
+ // disable the "Previous" button if all states in our history are disabled
+ ::std::vector< WizardState > aHistory;
+ getStateHistory( aHistory );
+ bool bHaveEnabledState = false;
+ for ( ::std::vector< WizardState >::const_iterator state = aHistory.begin();
+ state != aHistory.end() && !bHaveEnabledState;
+ ++state
+ )
+ {
+ if ( isStateEnabled( *state ) )
+ bHaveEnabledState = true;
+ }
+
+ enableButtons( WZB_PREVIOUS, bHaveEnabledState );
+
+ implUpdateRoadmap();
+ }
+
+ //--------------------------------------------------------------------
+ IMPL_LINK( RoadmapWizard, OnRoadmapItemSelected, void*, EMPTYARG )
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ RoadmapTypes::ItemId nCurItemId = m_pImpl->pRoadmap->GetCurrentRoadmapItemID();
+ if ( nCurItemId == getCurrentState() )
+ // nothing to do
+ return 1L;
+
+ if ( isTravelingSuspended() )
+ return 0;
+
+ WizardTravelSuspension aTravelGuard( *this );
+
+ sal_Int32 nCurrentIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
+ sal_Int32 nNewIndex = m_pImpl->getStateIndexInPath( nCurItemId, m_pImpl->nActivePath );
+
+ DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ),
+ "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" );
+ if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) )
+ {
+ return 0L;
+ }
+
+ sal_Bool bResult = sal_True;
+ if ( nNewIndex > nCurrentIndex )
+ {
+ bResult = skipUntil( (WizardState)nCurItemId );
+ WizardState nTemp = (WizardState)nCurItemId;
+ while( nTemp )
+ {
+ if( m_pImpl->aDisabledStates.find( --nTemp ) != m_pImpl->aDisabledStates.end() )
+ removePageFromHistory( nTemp );
+ }
+ }
+ else
+ bResult = skipBackwardUntil( (WizardState)nCurItemId );
+
+ if ( !bResult )
+ m_pImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() );
+
+ return 1L;
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::enterState( WizardState _nState )
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ OWizardMachine::enterState( _nState );
+
+ // synchronize the roadmap
+ implUpdateRoadmap( );
+ m_pImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() );
+ }
+
+ //--------------------------------------------------------------------
+ String RoadmapWizard::getStateDisplayName( WizardState _nState ) const
+ {
+ String sDisplayName;
+
+ StateDescriptions::const_iterator pos = m_pImpl->aStateDescriptors.find( _nState );
+ OSL_ENSURE( pos != m_pImpl->aStateDescriptors.end(),
+ "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" );
+ if ( pos != m_pImpl->aStateDescriptors.end() )
+ sDisplayName = pos->second.first;
+
+ return sDisplayName;
+ }
+
+ //--------------------------------------------------------------------
+ TabPage* RoadmapWizard::createPage( WizardState _nState )
+ {
+ TabPage* pPage( NULL );
+
+ StateDescriptions::const_iterator pos = m_pImpl->aStateDescriptors.find( _nState );
+ OSL_ENSURE( pos != m_pImpl->aStateDescriptors.end(),
+ "RoadmapWizard::createPage: no default implementation available for this state!" );
+ if ( pos != m_pImpl->aStateDescriptors.end() )
+ {
+ RoadmapPageFactory pFactory = pos->second.second;
+ pPage = (*pFactory)( *this );
+ }
+
+ return pPage;
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::enableState( WizardState _nState, bool _bEnable )
+ {
+ DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
+
+ // remember this (in case the state appears in the roadmap later on)
+ if ( _bEnable )
+ m_pImpl->aDisabledStates.erase( _nState );
+ else
+ {
+ m_pImpl->aDisabledStates.insert( _nState );
+ removePageFromHistory( _nState );
+ }
+
+ // if the state is currently in the roadmap, reflect it's new status
+ m_pImpl->pRoadmap->EnableRoadmapItem( (RoadmapTypes::ItemId)_nState, _bEnable );
+ }
+
+ //--------------------------------------------------------------------
+ bool RoadmapWizard::knowsState( WizardState i_nState ) const
+ {
+ for ( Paths::const_iterator path = m_pImpl->aPaths.begin();
+ path != m_pImpl->aPaths.end();
+ ++path
+ )
+ {
+ for ( WizardPath::const_iterator state = path->second.begin();
+ state != path->second.end();
+ ++state
+ )
+ {
+ if ( *state == i_nState )
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool RoadmapWizard::isStateEnabled( WizardState _nState ) const
+ {
+ return m_pImpl->aDisabledStates.find( _nState ) == m_pImpl->aDisabledStates.end();
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::Resize()
+ {
+ OWizardMachine::Resize();
+
+ if ( IsReallyShown() && !IsInInitShow() )
+ ResizeFixedLine();
+ }
+
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::StateChanged( StateChangedType nType )
+ {
+ WizardDialog::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ResizeFixedLine();
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::ResizeFixedLine()
+ {
+ Size aSize( m_pImpl->pRoadmap->GetSizePixel() );
+ aSize.Width() = m_pImpl->pFixedLine->GetSizePixel().Width();
+ m_pImpl->pFixedLine->SetSizePixel( aSize );
+ }
+
+ //--------------------------------------------------------------------
+ void RoadmapWizard::updateRoadmapItemLabel( WizardState _nState )
+ {
+ const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
+ RoadmapTypes::ItemIndex nUpperStepBoundary = (RoadmapTypes::ItemIndex)rActivePath.size();
+ RoadmapTypes::ItemIndex nLoopUntil = ::std::max( (RoadmapTypes::ItemIndex)nUpperStepBoundary, m_pImpl->pRoadmap->GetItemCount() );
+ sal_Int32 nCurrentStatePathIndex = -1;
+ if ( m_pImpl->nActivePath != -1 )
+ nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
+ for ( RoadmapTypes::ItemIndex nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex )
+ {
+ bool bExistentItem = ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() );
+ if ( bExistentItem )
+ {
+ // there is an item with this index in the roadmap - does it match what is requested by
+ // the respective state in the active path?
+ RoadmapTypes::ItemId nPresentItemId = m_pImpl->pRoadmap->GetItemID( nItemIndex );
+ WizardState nRequiredState = rActivePath[ nItemIndex ];
+ if ( _nState == nRequiredState )
+ {
+ m_pImpl->pRoadmap->ChangeRoadmapItemLabel( nPresentItemId, getStateDisplayName( nRequiredState ) );
+ break;
+ }
+ }
+ }
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/dialogs/so3res.src b/svtools/source/dialogs/so3res.src
new file mode 100644
index 000000000000..524b58e0a5df
--- /dev/null
+++ b/svtools/source/dialogs/so3res.src
@@ -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.
+ *
+ ************************************************************************/
+
+#include "sores.hxx"
+#define __RSC
+#include "soerr.hxx"
+#define S_MAX 0x7fff
+Resource RID_SO_ERROR_HANDLER
+{
+ String ERRCODE_SO_GENERALERROR&S_MAX
+ {
+ Text [ en-US ] = "General OLE error." ;
+ };
+ String ERRCODE_SO_CANT_BINDTOSOURCE&S_MAX
+ {
+ // ### ACHTUNG: Neuer Text in Resource? Die Verbindung zum Objekt kann nicht hergestellt werden : Die Verbindung zum Objekt kann nicht hergestellt werden.
+ Text [ en-US ] = "The connection to the object cannot be established." ;
+ };
+ String ERRCODE_SO_NOCACHE_UPDATED&S_MAX
+ {
+ Text [ en-US ] = "No cache files were updated." ;
+ };
+ String ERRCODE_SO_SOMECACHES_NOTUPDATED&S_MAX
+ {
+ Text [ en-US ] = "Some cache files were not updated." ;
+ };
+ String ERRCODE_SO_MK_UNAVAILABLE&S_MAX
+ {
+ Text [ en-US ] = "Status of object cannot be determined in a timely manner." ;
+ };
+ String ERRCODE_SO_E_CLASSDIFF&S_MAX
+ {
+ Text [ en-US ] = "Source of the OLE link has been converted." ;
+ };
+ String ERRCODE_SO_MK_NO_OBJECT&S_MAX
+ {
+ Text [ en-US ] = "The object could not be found." ;
+ };
+ String ERRCODE_SO_MK_EXCEEDED_DEADLINE&S_MAX
+ {
+ Text [ en-US ] = "The process could not be completed within the specified time period." ;
+ };
+ String ERRCODE_SO_MK_CONNECT_MANUALLY&S_MAX
+ {
+ Text [ en-US ] = "OLE could not connect to a network device (server)." ;
+ };
+ String ERRCODE_SO_MK_INTERMEDIATE_INTERFACE_NOT_SUPPORTED&S_MAX
+ {
+ Text [ en-US ] = "The object found does not support the interface required for the desired operation." ;
+ };
+ String ERRCODE_SO_NO_INTERFACE&S_MAX
+ {
+ Text [ en-US ] = "Interface not supported." ;
+ };
+ String ERRCODE_SO_OUT_OF_MEMORY&S_MAX
+ {
+ Text [ en-US ] = "Insufficient memory." ;
+ };
+ String ERRCODE_SO_MK_SYNTAX&S_MAX
+ {
+ Text [ en-US ] = "The connection name could not be processed." ;
+ };
+ String ERRCODE_SO_MK_REDUCED_TO_SELF&S_MAX
+ {
+ Text [ en-US ] = "The connection name could not be reduced further." ;
+ };
+ String ERRCODE_SO_MK_NO_INVERSE&S_MAX
+ {
+ Text [ en-US ] = "The connection name has no inverse." ;
+ };
+ String ERRCODE_SO_MK_NO_PREFIX&S_MAX
+ {
+ Text [ en-US ] = "No common prefix exists." ;
+ };
+ String ERRCODE_SO_MK_HIM&S_MAX
+ {
+ Text [ en-US ] = "The connection name is contained in the other one." ;
+ };
+ String ERRCODE_SO_MK_US&S_MAX
+ {
+ Text [ en-US ] = "The connection names (the receiver and the other moniker) are identical." ;
+ };
+ String ERRCODE_SO_MK_ME&S_MAX
+ {
+ Text [ en-US ] = "The connection name is contained in the other one." ;
+ };
+ String ERRCODE_SO_MK_NOT_BINDABLE&S_MAX
+ {
+ // ### ACHTUNG: Neuer Text in Resource? Der Verbindungsname kann nicht verbunden werden Es handelt sich um einen relativen Namen : Der Verbindungsname kann nicht verbunden werden. Es handelt sich um einen relativen Namen
+ Text [ en-US ] = "The connection name cannot be connected. This is a relative name." ;
+ };
+ String ERRCODE_SO_NOT_IMPLEMENTED&S_MAX
+ {
+ Text [ en-US ] = "Operation not implemented." ;
+ };
+ String ERRCODE_SO_MK_NO_STORAGE&S_MAX
+ {
+ Text [ en-US ] = "No storage." ;
+ };
+ String ERRCODE_SO_FALSE&S_MAX
+ {
+ Text [ en-US ] = "False." ;
+ };
+ String ERRCODE_SO_MK_NEED_GENERIC&S_MAX
+ {
+ Text [ en-US ] = "Monikers must be composed generically." ;
+ };
+ String ERRCODE_SO_PENDING&S_MAX
+ {
+ Text [ en-US ] = "Data not available at this time." ;
+ };
+ String ERRCODE_SO_NOT_INPLACEACTIVE & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Objekt wurde nicht InPlace aktiviert : Objetkt wurde nicht InPlace aktiviert */
+ Text [ en-US ] = "Object could not be activated InPlace." ;
+ };
+ String ERRCODE_SO_LINDEX & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ungültiger Index : Ung³ltiger Index */
+ Text [ en-US ] = "Invalid index." ;
+ };
+ String ERRCODE_SO_CANNOT_DOVERB_NOW & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Das Objekt kann die Aktion im momentanen Zustand nicht ausführen : Das Objekt kann die Aktion im momentanen Zustand nicht ausf³hren */
+ Text [ en-US ] = "The action cannot be executed in the object's current state." ;
+ };
+ String ERRCODE_SO_OLEOBJ_INVALIDHWND & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Bei der Aktivierung wurde ein ungültiges Fenster ist übergeben : Bei der Aktivierung wurde ein ung³ltiges Fenster ist ³bergeben */
+ Text [ en-US ] = "An invalid window was passed when activated." ;
+ };
+ String ERRCODE_SO_NOVERBS & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Das Objekt unterstützt keine Aktionen : Das Objekt unterst³tzt keine Aktionen */
+ Text [ en-US ] = "The object does not support any actions." ;
+ };
+ String ERRCODE_SO_INVALIDVERB & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Die Aktion ist nicht definiert. Es wird die Default Aktion ausgelöst : Die Aktion ist nicht definiert. Es wird die Default Aktion ausgel÷st */
+ Text [ en-US ] = "The action is not defined. The default action will be executed." ;
+ };
+ String ERRCODE_SO_MK_CONNECT & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Eine Verknüpfung auf das Netzwerk konnte nicht wieder hergestellt werden : Eine Verkn³pfung auf das Netzwerk, die nicht wieder hergestellt werden konnte */
+ Text [ en-US ] = "A link to the network could not be re-established." ;
+ };
+ String ERRCODE_SO_NOTIMPL & S_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Das Objekt unterstützt diese Aktion nicht : Das Objekt unterst³tzt diese Aktion nicht */
+ Text [ en-US ] = "Object does not support this action." ;
+ };
+ String ERRCODE_SO_MK_CANTOPENFILE & S_MAX
+ {
+ Text [ en-US ] = "The specified file could not be opened." ;
+ };
+ /*
+ String & S_MAX
+ {
+ Text = "";
+ };
+*/
+};
+Resource RID_SO_ERRCTX
+{
+ String ERRCTX_SO_DOVERB
+ {
+ Text [ en-US ] = "$(ERR) activating object" ;
+ };
+};
+String STR_INS_OBJECT
+{
+ Text [ en-US ] = "Inserts a new %1-Object into your document." ;
+};
+String STR_INS_OBJECT_ICON
+{
+ Text [ en-US ] = "Inserts a new %1-Object into your document as a symbol." ;
+};
+String STR_INS_FILE
+{
+ Text [ en-US ] = "Inserts the contents of the file into your document to enable later editing in the original application." ;
+};
+String STR_INS_PLUGIN
+{
+ Text [ en-US ] = "Inserts a plug-in object into your document with a reference to the plug-in data. When the object is activated, the plug-in is automatically executed." ;
+};
+String STR_INS_APPLET
+{
+ Text [ en-US ] = "Inserts an applet object into your document. When the object is activated, the applet is automatically executed." ;
+};
+String STR_INS_FILE_ICON
+{
+ Text [ en-US ] = "Inserts the contents of the file as an icon into your document." ;
+};
+String STR_INS_FILE_LINK
+{
+ Text [ en-US ] = "Inserts the contents of the file into your document and creates a link to the source file. Changes made to the source file will be reflected in your document." ;
+};
+String STR_INS_FILE_ICON_LINK
+{
+ Text [ en-US ] = "Inserts an icon into your document representing the file. Changes made to the source file will be reflected in your document." ;
+};
+String STR_PASTE
+{
+ Text [ en-US ] = "Pastes the contents of the clipboard as %1 in your document." ;
+};
+String STR_CONVERT_TO
+{
+ Text [ en-US ] = "Converts the selected %1object to the object type %2." ;
+};
+String STR_ACTIVATE_AS
+{
+ Text [ en-US ] = "All objects of type %1 are activated as %2, but not converted" ;
+};
+String STR_VERB_OPEN
+{
+ Text [ en-US ] = "~Open" ;
+};
+String STR_VERB_PROPS
+{
+ Text [ en-US ] = "~Properties" ;
+};
+String STR_PLUGIN_CANT_SHOW
+{
+ Text [ en-US ] = "Plug-in % cannot be displayed." ;
+};
+String STR_ERROR_DDE
+{
+ Text [ en-US ] = "DDE link to % for % area % are not available." ;
+};
+String STR_ERROR_OBJNOCREATE
+{
+ Text [ en-US ] = "Object % could not be inserted." ;
+};
+String STR_ERROR_OBJNOCREATE_FROM_FILE
+{
+ Text [ en-US ] = "Object from file % could not be inserted." ;
+};
+String STR_ERROR_OBJNOCREATE_PLUGIN
+{
+ Text [ en-US ] = "Plug-in from document % could not be inserted." ;
+};
+String STR_QUERYUPDATELINKS
+{
+ Text [ en-US ] = "Update all links?" ;
+};
+String STR_FURTHER_OBJECT
+{
+ Text [ en-US ] = "Further objects" ;
+};
+String STR_EDIT_APPLET
+{
+ Text [ en-US ] = "Edit Applet" ;
+};
+
+Bitmap BMP_PLUGIN
+{
+ File = "plugin.png" ;
+};
+Bitmap BMP_OLEOBJ
+{
+ File = "oleobj.png" ;
+};
+Menu MB_PLUGIN
+{
+ ItemList =
+ {
+ MenuItem MI_PLUGIN ;
+ };
+ ExtraData = { 1 ; 0 ; 0 ; }; //Um InPlace Menu zu bentzen
+};
+MenuItem MI_PLUGIN
+{
+ Identifier = MI_PLUGIN ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MI_PLUGIN_DEACTIVATE ;
+ Text [ en-US ] = "Deactivate" ;
+ };
+ };
+ };
+};
+String STR_UNKNOWN_SOURCE
+{
+ Text [ en-US ] = "Unknown source" ;
+};
+
+
diff --git a/svtools/source/dialogs/wizardmachine.cxx b/svtools/source/dialogs/wizardmachine.cxx
new file mode 100644
index 000000000000..2053da80019d
--- /dev/null
+++ b/svtools/source/dialogs/wizardmachine.cxx
@@ -0,0 +1,750 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/wizardmachine.hxx>
+#include <svtools/helpid.hrc>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/msgbox.hxx>
+#include <svtools/svtdata.hxx>
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ //=====================================================================
+ //= WizardPageImplData
+ //=====================================================================
+ struct WizardPageImplData
+ {
+ WizardPageImplData()
+ {
+ }
+ };
+
+ //=====================================================================
+ //= OWizardPage
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OWizardPage::OWizardPage( Window* _pParent, WinBits _nStyle )
+ :TabPage( _pParent, _nStyle )
+ ,m_pImpl( new WizardPageImplData )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ OWizardPage::OWizardPage( Window* _pParent, const ResId& _rResId )
+ :TabPage( _pParent, _rResId )
+ ,m_pImpl( new WizardPageImplData )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ OWizardPage::~OWizardPage()
+ {
+ delete m_pImpl;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardPage::initializePage()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardPage::ActivatePage()
+ {
+ TabPage::ActivatePage();
+ updateDialogTravelUI();
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardPage::updateDialogTravelUI()
+ {
+ OWizardMachine* pWizardMachine = dynamic_cast< OWizardMachine* >( GetParent() );
+ if ( pWizardMachine )
+ pWizardMachine->updateTravelUI();
+ }
+
+ //---------------------------------------------------------------------
+ bool OWizardPage::canAdvance() const
+ {
+ return true;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardPage::commitPage( WizardTypes::CommitPageReason )
+ {
+ return sal_True;
+ }
+
+ //=====================================================================
+ //= WizardMachineImplData
+ //=====================================================================
+ struct WizardMachineImplData : public WizardTypes
+ {
+ String sTitleBase; // the base for the title
+ ::std::stack< WizardState > aStateHistory; // the history of all states (used for implementing "Back")
+
+ WizardState nFirstUnknownPage;
+ // the WizardDialog does not allow non-linear transitions (e.g. it's
+ // not possible to add pages in a non-linear order), so we need some own maintainance data
+
+ sal_Bool m_bAutoNextButtonState;
+
+ bool m_bTravelingSuspended;
+
+ WizardMachineImplData()
+ :nFirstUnknownPage( 0 )
+ ,m_bAutoNextButtonState( sal_False )
+ ,m_bTravelingSuspended( false )
+ {
+ }
+ };
+
+ long OWizardMachine::calcRightHelpOffset(sal_uInt32 _nButtonFlags)
+ {
+ sal_Int32 nMask = 1;
+ sal_Int32 nRightAlignedButtonCount = -1;
+ for (unsigned int i = 0; i < 8*sizeof(_nButtonFlags); i++ )
+ {
+ if( ( _nButtonFlags & nMask ) != 0 )
+ nRightAlignedButtonCount++;
+ nMask <<= 1;
+ }
+ Size aSize = GetPageSizePixel();
+ sal_Int32 nTotButtonWidth = nRightAlignedButtonCount * LogicalCoordinateToPixel(50);
+ sal_Int32 nTotRightButtonSpaceOffset = (nRightAlignedButtonCount) * WIZARDDIALOG_BUTTON_STDOFFSET_X;
+ if ((_nButtonFlags & WZB_NEXT) && (_nButtonFlags & WZB_NEXT))
+ nTotRightButtonSpaceOffset = (nTotRightButtonSpaceOffset - WIZARDDIALOG_BUTTON_STDOFFSET_X) + WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X;
+ return aSize.Width() - nTotButtonWidth - nTotRightButtonSpaceOffset;
+ }
+
+ //=====================================================================
+ //= OWizardMachine
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OWizardMachine::OWizardMachine(Window* _pParent, const ResId& _rRes, sal_uInt32 _nButtonFlags )
+ :WizardDialog( _pParent, _rRes )
+ ,m_pFinish(NULL)
+ ,m_pCancel(NULL)
+ ,m_pNextPage(NULL)
+ ,m_pPrevPage(NULL)
+ ,m_pHelp(NULL)
+ ,m_pImpl( new WizardMachineImplData )
+ {
+ implConstruct( _nButtonFlags );
+ }
+
+ //---------------------------------------------------------------------
+ OWizardMachine::OWizardMachine(Window* _pParent, const WinBits i_nStyle, sal_uInt32 _nButtonFlags )
+ :WizardDialog( _pParent, i_nStyle )
+ ,m_pFinish(NULL)
+ ,m_pCancel(NULL)
+ ,m_pNextPage(NULL)
+ ,m_pPrevPage(NULL)
+ ,m_pHelp(NULL)
+ ,m_pImpl( new WizardMachineImplData )
+ {
+ implConstruct( _nButtonFlags );
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::implConstruct( const sal_uInt32 _nButtonFlags )
+ {
+ m_pImpl->sTitleBase = GetText();
+
+ // create the buttons according to the wizard button flags
+ // the help button
+ if (_nButtonFlags & WZB_HELP)
+ {
+ m_pHelp= new HelpButton(this, WB_TABSTOP);
+ m_pHelp->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
+ m_pHelp->Show();
+ AddButton( m_pHelp, WIZARDDIALOG_BUTTON_STDOFFSET_X);
+ }
+
+ // the previous button
+ if (_nButtonFlags & WZB_PREVIOUS)
+ {
+ m_pPrevPage = new PushButton(this, WB_TABSTOP);
+ m_pPrevPage->SetSmartHelpId( SmartId(HID_WIZARD_PREVIOUS) );
+ m_pPrevPage->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
+ m_pPrevPage->SetText(String(SvtResId(STR_WIZDLG_PREVIOUS)));
+ m_pPrevPage->Show();
+
+ if (_nButtonFlags & WZB_NEXT)
+ AddButton( m_pPrevPage, ( WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X) ); // half x-offset to the next button
+ else
+ AddButton( m_pPrevPage, WIZARDDIALOG_BUTTON_STDOFFSET_X );
+ SetPrevButton( m_pPrevPage );
+ m_pPrevPage->SetClickHdl( LINK( this, OWizardMachine, OnPrevPage ) );
+ }
+
+ // the next button
+ if (_nButtonFlags & WZB_NEXT)
+ {
+ m_pNextPage = new PushButton(this, WB_TABSTOP);
+ m_pNextPage->SetSmartHelpId( SmartId(HID_WIZARD_NEXT) );
+ m_pNextPage->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
+ m_pNextPage->SetText(String(SvtResId(STR_WIZDLG_NEXT)));
+ m_pNextPage->Show();
+
+ AddButton( m_pNextPage, WIZARDDIALOG_BUTTON_STDOFFSET_X );
+ SetNextButton( m_pNextPage );
+ m_pNextPage->SetClickHdl( LINK( this, OWizardMachine, OnNextPage ) );
+ }
+
+ // the finish button
+ if (_nButtonFlags & WZB_FINISH)
+ {
+ m_pFinish = new OKButton(this, WB_TABSTOP);
+ m_pFinish->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
+ m_pFinish->SetText(String(SvtResId(STR_WIZDLG_FINISH)));
+ m_pFinish->Show();
+
+ AddButton( m_pFinish, WIZARDDIALOG_BUTTON_STDOFFSET_X );
+ m_pFinish->SetClickHdl( LINK( this, OWizardMachine, OnFinish ) );
+ }
+
+ // the cancel button
+ if (_nButtonFlags & WZB_CANCEL)
+ {
+ m_pCancel = new CancelButton(this, WB_TABSTOP);
+ m_pCancel->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
+ m_pCancel->Show();
+
+ AddButton( m_pCancel, WIZARDDIALOG_BUTTON_STDOFFSET_X );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ OWizardMachine::~OWizardMachine()
+ {
+ delete m_pFinish;
+ delete m_pCancel;
+ delete m_pNextPage;
+ delete m_pPrevPage;
+ delete m_pHelp;
+
+ for (WizardState i=0; i<m_pImpl->nFirstUnknownPage; ++i)
+ delete GetPage(i);
+
+ delete m_pImpl;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::implUpdateTitle()
+ {
+ String sCompleteTitle(m_pImpl->sTitleBase);
+
+ // append the page title
+ TabPage* pCurrentPage = GetPage(getCurrentState());
+ if ( pCurrentPage && pCurrentPage->GetText().Len() )
+ {
+ sCompleteTitle += String::CreateFromAscii(" - ");
+ sCompleteTitle += pCurrentPage->GetText();
+ }
+
+ SetText(sCompleteTitle);
+ }
+
+ //---------------------------------------------------------------------
+ const String& OWizardMachine::getTitleBase() const
+ {
+ return m_pImpl->sTitleBase;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::setTitleBase(const String& _rTitleBase)
+ {
+ m_pImpl->sTitleBase = _rTitleBase;
+ implUpdateTitle();
+ }
+
+ //---------------------------------------------------------------------
+ TabPage* OWizardMachine::GetOrCreatePage( const WizardState i_nState )
+ {
+ if ( NULL == GetPage( i_nState ) )
+ {
+ TabPage* pNewPage = createPage( i_nState );
+ DBG_ASSERT( pNewPage, "OWizardMachine::GetOrCreatePage: invalid new page (NULL)!" );
+
+ // fill up the page sequence of our base class (with dummies)
+ while ( m_pImpl->nFirstUnknownPage < i_nState )
+ {
+ AddPage( NULL );
+ ++m_pImpl->nFirstUnknownPage;
+ }
+
+ if ( m_pImpl->nFirstUnknownPage == i_nState )
+ {
+ // encountered this page number the first time
+ AddPage( pNewPage );
+ ++m_pImpl->nFirstUnknownPage;
+ }
+ else
+ // already had this page - just change it
+ SetPage( i_nState, pNewPage );
+ }
+ return GetPage( i_nState );
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::ActivatePage()
+ {
+ WizardDialog::ActivatePage();
+
+ WizardState nCurrentLevel = GetCurLevel();
+ GetOrCreatePage( nCurrentLevel );
+
+ enterState( nCurrentLevel );
+ }
+
+ //---------------------------------------------------------------------
+ long OWizardMachine::DeactivatePage()
+ {
+ WizardState nCurrentState = getCurrentState();
+ if (!leaveState(nCurrentState) || !WizardDialog::DeactivatePage())
+ return sal_False;
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::defaultButton(sal_uInt32 _nWizardButtonFlags)
+ {
+ // the new default button
+ PushButton* pNewDefButton = NULL;
+ if (m_pFinish && (_nWizardButtonFlags & WZB_FINISH))
+ pNewDefButton = m_pFinish;
+ if (m_pNextPage && (_nWizardButtonFlags & WZB_NEXT))
+ pNewDefButton = m_pNextPage;
+ if (m_pPrevPage && (_nWizardButtonFlags & WZB_PREVIOUS))
+ pNewDefButton = m_pPrevPage;
+ if (m_pHelp && (_nWizardButtonFlags & WZB_HELP))
+ pNewDefButton = m_pHelp;
+ if (m_pCancel && (_nWizardButtonFlags & WZB_CANCEL))
+ pNewDefButton = m_pCancel;
+
+ if ( pNewDefButton )
+ defaultButton( pNewDefButton );
+ else
+ implResetDefault( this );
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::implResetDefault(Window* _pWindow)
+ {
+ Window* pChildLoop = _pWindow->GetWindow(WINDOW_FIRSTCHILD);
+ while (pChildLoop)
+ {
+ // does the window participate in the tabbing order?
+ if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
+ implResetDefault(pChildLoop);
+
+ // is it a button?
+ WindowType eType = pChildLoop->GetType();
+ if ( (WINDOW_BUTTON == eType)
+ || (WINDOW_PUSHBUTTON == eType)
+ || (WINDOW_OKBUTTON == eType)
+ || (WINDOW_CANCELBUTTON == eType)
+ || (WINDOW_HELPBUTTON == eType)
+ || (WINDOW_IMAGEBUTTON == eType)
+ || (WINDOW_MENUBUTTON == eType)
+ || (WINDOW_MOREBUTTON == eType)
+ )
+ {
+ pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
+ }
+
+ // the next one ...
+ pChildLoop = pChildLoop->GetWindow(WINDOW_NEXT);
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::defaultButton(PushButton* _pNewDefButton)
+ {
+ // loop through all (direct and indirect) descendants which participate in our tabbing order, and
+ // reset the WB_DEFBUTTON for every window which is a button
+ implResetDefault(this);
+
+ // set it's new style
+ if (_pNewDefButton)
+ _pNewDefButton->SetStyle(_pNewDefButton->GetStyle() | WB_DEFBUTTON);
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::enableButtons(sal_uInt32 _nWizardButtonFlags, sal_Bool _bEnable)
+ {
+ if (m_pFinish && (_nWizardButtonFlags & WZB_FINISH))
+ m_pFinish->Enable(_bEnable);
+ if (m_pNextPage && (_nWizardButtonFlags & WZB_NEXT))
+ m_pNextPage->Enable(_bEnable);
+ if (m_pPrevPage && (_nWizardButtonFlags & WZB_PREVIOUS))
+ m_pPrevPage->Enable(_bEnable);
+ if (m_pHelp && (_nWizardButtonFlags & WZB_HELP))
+ m_pHelp->Enable(_bEnable);
+ if (m_pCancel && (_nWizardButtonFlags & WZB_CANCEL))
+ m_pCancel->Enable(_bEnable);
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::enterState(WizardState _nState)
+ {
+ // tell the page
+ IWizardPageController* pController = getPageController( GetPage( _nState ) );
+ OSL_ENSURE( pController, "OWizardMachine::enterState: no controller for the given page!" );
+ if ( pController )
+ pController->initializePage();
+
+ if ( isAutomaticNextButtonStateEnabled() )
+ enableButtons( WZB_NEXT, canAdvance() );
+
+ enableButtons( WZB_PREVIOUS, !m_pImpl->aStateHistory.empty() );
+
+ // set the new title - it depends on the current page (i.e. state)
+ implUpdateTitle();
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::leaveState(WizardState)
+ {
+ // no need to ask the page here.
+ // If we reach this point, we already gave the current page the chance to commit it's data,
+ // and it was allowed to commit it's data
+
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::onFinish()
+ {
+ return Finnish( RET_OK );
+ }
+
+ //---------------------------------------------------------------------
+ IMPL_LINK(OWizardMachine, OnFinish, PushButton*, EMPTYARG)
+ {
+ if ( isTravelingSuspended() )
+ return 0;
+ WizardTravelSuspension aTravelGuard( *this );
+ if ( !prepareLeaveCurrentState( eFinish ) )
+ {
+ return 0L;
+ }
+ return onFinish() ? 1L : 0L;
+ }
+
+ //---------------------------------------------------------------------
+ OWizardMachine::WizardState OWizardMachine::determineNextState( WizardState _nCurrentState ) const
+ {
+ return _nCurrentState + 1;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::prepareLeaveCurrentState( CommitPageReason _eReason )
+ {
+ IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
+ ENSURE_OR_RETURN( pController != NULL, "OWizardMachine::prepareLeaveCurrentState: no controller for the current page!", sal_True );
+ return pController->commitPage( _eReason );
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::skipBackwardUntil( WizardState _nTargetState )
+ {
+ // alowed to leave the current page?
+ if ( !prepareLeaveCurrentState( eTravelBackward ) )
+ return sal_False;
+
+ // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong
+ ::std::stack< WizardState > aTravelVirtually = m_pImpl->aStateHistory;
+ ::std::stack< WizardState > aOldStateHistory = m_pImpl->aStateHistory;
+
+ WizardState nCurrentRollbackState = getCurrentState();
+ while ( nCurrentRollbackState != _nTargetState )
+ {
+ DBG_ASSERT( !aTravelVirtually.empty(), "OWizardMachine::skipBackwardUntil: this target state does not exist in the history!" );
+ nCurrentRollbackState = aTravelVirtually.top();
+ aTravelVirtually.pop();
+ }
+ m_pImpl->aStateHistory = aTravelVirtually;
+ if ( !ShowPage( _nTargetState ) )
+ {
+ m_pImpl->aStateHistory = aOldStateHistory;
+ return sal_False;
+ }
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::skipUntil( WizardState _nTargetState )
+ {
+ WizardState nCurrentState = getCurrentState();
+
+ // alowed to leave the current page?
+ if ( !prepareLeaveCurrentState( nCurrentState < _nTargetState ? eTravelForward : eTravelBackward ) )
+ return sal_False;
+
+ // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong
+ ::std::stack< WizardState > aTravelVirtually = m_pImpl->aStateHistory;
+ ::std::stack< WizardState > aOldStateHistory = m_pImpl->aStateHistory;
+ while ( nCurrentState != _nTargetState )
+ {
+ WizardState nNextState = determineNextState( nCurrentState );
+ if ( WZS_INVALID_STATE == nNextState )
+ {
+ DBG_ERROR( "OWizardMachine::skipUntil: the given target state does not exist!" );
+ return sal_False;
+ }
+
+ // remember the skipped state in the history
+ aTravelVirtually.push( nCurrentState );
+
+ // get the next state
+ nCurrentState = nNextState;
+ }
+ m_pImpl->aStateHistory = aTravelVirtually;
+ // show the target page
+ if ( !ShowPage( nCurrentState ) )
+ {
+ // argh! prepareLeaveCurrentPage succeeded, determineNextState succeeded,
+ // but ShowPage doesn't? Somebody behaves very strange here ....
+ DBG_ERROR( "OWizardMachine::skipUntil: very unpolite ...." );
+ m_pImpl->aStateHistory = aOldStateHistory;
+ return sal_False;
+ }
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::skip(sal_Int32 _nSteps)
+ {
+ DBG_ASSERT(_nSteps > 0, "OWizardMachine::skip: invalid number of steps!");
+ // alowed to leave the current page?
+ if ( !prepareLeaveCurrentState( eTravelForward ) )
+ return sal_False;
+
+ WizardState nCurrentState = getCurrentState();
+ WizardState nNextState = determineNextState(nCurrentState);
+ // loop _nSteps steps
+ while (_nSteps-- > 0)
+ {
+ if (WZS_INVALID_STATE == nNextState)
+ return sal_False;
+
+ // remember the skipped state in the history
+ m_pImpl->aStateHistory.push(nCurrentState);
+
+ // get the next state
+ nCurrentState = nNextState;
+ nNextState = determineNextState(nCurrentState);
+ }
+
+ // show the (n+1)th page
+ if (!ShowPage(nCurrentState))
+ {
+ // TODO: this leaves us in a state where we have no current page and an inconsistent state history.
+ // Perhaps we should rollback the skipping here ....
+ DBG_ERROR("OWizardMachine::skip: very unpolite ....");
+ // if somebody does a skip and then does not allow to leave ...
+ // (can't be a commit error, as we've already committed the current page. So if ShowPage fails here,
+ // somebody behaves really strange ...)
+ return sal_False;
+ }
+
+ // all fine
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::travelNext()
+ {
+ // allowed to leave the current page?
+ if ( !prepareLeaveCurrentState( eTravelForward ) )
+ return sal_False;
+
+ // determine the next state to travel to
+ WizardState nCurrentState = getCurrentState();
+ WizardState nNextState = determineNextState(nCurrentState);
+ if (WZS_INVALID_STATE == nNextState)
+ return sal_False;
+
+ // the state history is used by the enterState method
+ // all fine
+ m_pImpl->aStateHistory.push(nCurrentState);
+ if (!ShowPage(nNextState))
+ {
+ m_pImpl->aStateHistory.pop();
+ return sal_False;
+ }
+
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OWizardMachine::travelPrevious()
+ {
+ DBG_ASSERT(m_pImpl->aStateHistory.size() > 0, "OWizardMachine::travelPrevious: have no previous page!");
+
+ // alowed to leave the current page?
+ if ( !prepareLeaveCurrentState( eTravelBackward ) )
+ return sal_False;
+
+ // the next state to switch to
+ WizardState nPreviousState = m_pImpl->aStateHistory.top();
+
+ // the state history is used by the enterState method
+ m_pImpl->aStateHistory.pop();
+ // show this page
+ if (!ShowPage(nPreviousState))
+ {
+ m_pImpl->aStateHistory.push(nPreviousState);
+ return sal_False;
+ }
+
+ // all fine
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::removePageFromHistory( WizardState nToRemove )
+ {
+
+ ::std::stack< WizardState > aTemp;
+ while(!m_pImpl->aStateHistory.empty())
+ {
+ WizardState nPreviousState = m_pImpl->aStateHistory.top();
+ m_pImpl->aStateHistory.pop();
+ if(nPreviousState != nToRemove)
+ aTemp.push( nPreviousState );
+ else
+ break;
+ }
+ while(!aTemp.empty())
+ {
+ m_pImpl->aStateHistory.push( aTemp.top() );
+ aTemp.pop();
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::enableAutomaticNextButtonState( bool _bEnable )
+ {
+ m_pImpl->m_bAutoNextButtonState = _bEnable;
+ }
+
+ //---------------------------------------------------------------------
+ bool OWizardMachine::isAutomaticNextButtonStateEnabled() const
+ {
+ return m_pImpl->m_bAutoNextButtonState;
+ }
+
+ //---------------------------------------------------------------------
+ IMPL_LINK(OWizardMachine, OnPrevPage, PushButton*, EMPTYARG)
+ {
+ if ( isTravelingSuspended() )
+ return 0;
+ WizardTravelSuspension aTravelGuard( *this );
+ sal_Int32 nRet = travelPrevious();
+ return nRet;
+ }
+
+ //---------------------------------------------------------------------
+ IMPL_LINK(OWizardMachine, OnNextPage, PushButton*, EMPTYARG)
+ {
+ if ( isTravelingSuspended() )
+ return 0;
+ WizardTravelSuspension aTravelGuard( *this );
+ sal_Int32 nRet = travelNext();
+ return nRet;
+ }
+
+ //---------------------------------------------------------------------
+ IWizardPageController* OWizardMachine::getPageController( TabPage* _pCurrentPage ) const
+ {
+ IWizardPageController* pController = dynamic_cast< IWizardPageController* >( _pCurrentPage );
+ return pController;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::getStateHistory( ::std::vector< WizardState >& _out_rHistory )
+ {
+ ::std::stack< WizardState > aHistoryCopy( m_pImpl->aStateHistory );
+ while ( !aHistoryCopy.empty() )
+ {
+ _out_rHistory.push_back( aHistoryCopy.top() );
+ aHistoryCopy.pop();
+ }
+ }
+
+ //---------------------------------------------------------------------
+ bool OWizardMachine::canAdvance() const
+ {
+ return WZS_INVALID_STATE != determineNextState( getCurrentState() );
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::updateTravelUI()
+ {
+ const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
+ OSL_ENSURE( pController != NULL, "RoadmapWizard::updateTravelUI: no controller for the current page!" );
+
+ bool bCanAdvance =
+ ( !pController || pController->canAdvance() ) // the current page allows to advance
+ && canAdvance(); // the dialog as a whole allows to advance
+ enableButtons( WZB_NEXT, bCanAdvance );
+ }
+
+ //---------------------------------------------------------------------
+ bool OWizardMachine::isTravelingSuspended() const
+ {
+ return m_pImpl->m_bTravelingSuspended;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::suspendTraveling( AccessGuard )
+ {
+ DBG_ASSERT( !m_pImpl->m_bTravelingSuspended, "OWizardMachine::suspendTraveling: already suspended!" );
+ m_pImpl->m_bTravelingSuspended = true;
+ }
+
+ //---------------------------------------------------------------------
+ void OWizardMachine::resumeTraveling( AccessGuard )
+ {
+ DBG_ASSERT( m_pImpl->m_bTravelingSuspended, "OWizardMachine::resumeTraveling: nothing to resume!" );
+ m_pImpl->m_bTravelingSuspended = false;
+ }
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
diff --git a/svtools/source/dialogs/wizardmachine.src b/svtools/source/dialogs/wizardmachine.src
new file mode 100644
index 000000000000..9c82ea30071f
--- /dev/null
+++ b/svtools/source/dialogs/wizardmachine.src
@@ -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 _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+String STR_WIZDLG_FINISH
+{
+ Text [ en-US ] = "~Finish" ;
+};
+
+String STR_WIZDLG_NEXT
+{
+ Text [ en-US ] = "~Next >>";
+};
+
+String STR_WIZDLG_PREVIOUS
+{
+ Text [ en-US ] = "<< Bac~k";
+};
+
+String STR_WIZDLG_ROADMAP_TITLE
+{
+ Text [ en-US ] = "Steps";
+};
diff --git a/svtools/source/dialogs/wizdlg.cxx b/svtools/source/dialogs/wizdlg.cxx
new file mode 100644
index 000000000000..f06b4f53ce7c
--- /dev/null
+++ b/svtools/source/dialogs/wizdlg.cxx
@@ -0,0 +1,707 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SVT_WIZDLG_CXX
+#include <tools/debug.hxx>
+#ifndef _VCL_FIXED_HXX
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _VCL_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#ifndef _VCL_TABPAGE_HXX
+#include <vcl/tabpage.hxx>
+#endif
+#include <svtools/wizdlg.hxx>
+
+// =======================================================================
+
+#define WIZARDDIALOG_BUTTON_OFFSET_Y 6
+#define WIZARDDIALOG_BUTTON_DLGOFFSET_X 6
+#define WIZARDDIALOG_VIEW_DLGOFFSET_X 6
+#define WIZARDDIALOG_VIEW_DLGOFFSET_Y 6
+
+// =======================================================================
+
+struct ImplWizPageData
+{
+ ImplWizPageData* mpNext;
+ TabPage* mpPage;
+};
+
+// -----------------------------------------------------------------------
+
+struct ImplWizButtonData
+{
+ ImplWizButtonData* mpNext;
+ Button* mpButton;
+ long mnOffset;
+};
+
+// =======================================================================
+
+void WizardDialog::ImplInitData()
+{
+ mpFirstPage = NULL;
+ mpFirstBtn = NULL;
+ mpFixedLine = NULL;
+ mpCurTabPage = NULL;
+ mpPrevBtn = NULL;
+ mpNextBtn = NULL;
+ mpViewWindow = NULL;
+ mnCurLevel = 0;
+ meViewAlign = WINDOWALIGN_LEFT;
+ mbEmptyViewMargin = false;
+ mnLeftAlignCount = 0;
+}
+
+// -----------------------------------------------------------------------
+void WizardDialog::SetLeftAlignedButtonCount( sal_Int16 _nCount )
+{
+ mnLeftAlignCount = _nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::SetEmptyViewMargin()
+{
+ mbEmptyViewMargin = true;
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::ImplCalcSize( Size& rSize )
+{
+ // ButtonBar-Hoehe berechnen
+ long nMaxHeight = 0;
+ ImplWizButtonData* pBtnData = mpFirstBtn;
+ while ( pBtnData )
+ {
+ long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
+ if ( nBtnHeight > nMaxHeight )
+ nMaxHeight = nBtnHeight;
+ pBtnData = pBtnData->mpNext;
+ }
+ if ( nMaxHeight )
+ nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
+ if ( mpFixedLine && mpFixedLine->IsVisible() )
+ nMaxHeight += mpFixedLine->GetSizePixel().Height();
+ rSize.Height() += nMaxHeight;
+
+ // View-Window-Groesse dazurechnen
+ if ( mpViewWindow && mpViewWindow->IsVisible() )
+ {
+ Size aViewSize = mpViewWindow->GetSizePixel();
+ if ( meViewAlign == WINDOWALIGN_TOP )
+ rSize.Height() += aViewSize.Height();
+ else if ( meViewAlign == WINDOWALIGN_LEFT )
+ rSize.Width() += aViewSize.Width();
+ else if ( meViewAlign == WINDOWALIGN_BOTTOM )
+ rSize.Height() += aViewSize.Height();
+ else if ( meViewAlign == WINDOWALIGN_RIGHT )
+ rSize.Width() += aViewSize.Width();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::ImplPosCtrls()
+{
+ Size aDlgSize = GetOutputSizePixel();
+ long nBtnWidth = 0;
+ long nMaxHeight = 0;
+ long nOffY = aDlgSize.Height();
+
+ ImplWizButtonData* pBtnData = mpFirstBtn;
+ int j = 0;
+ while ( pBtnData )
+ {
+ if (j >= mnLeftAlignCount)
+ {
+ Size aBtnSize = pBtnData->mpButton->GetSizePixel();
+ long nBtnHeight = aBtnSize.Height();
+ if ( nBtnHeight > nMaxHeight )
+ nMaxHeight = nBtnHeight;
+ nBtnWidth += aBtnSize.Width();
+ nBtnWidth += pBtnData->mnOffset;
+ }
+ pBtnData = pBtnData->mpNext;
+ j++;
+ }
+
+ if ( nMaxHeight )
+ {
+ long nOffX = aDlgSize.Width()-nBtnWidth-WIZARDDIALOG_BUTTON_DLGOFFSET_X;
+ long nOffLeftAlignX = LogicalCoordinateToPixel(6);
+ nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y+nMaxHeight;
+
+ pBtnData = mpFirstBtn;
+ int i = 0;
+ while ( pBtnData )
+ {
+ Size aBtnSize = pBtnData->mpButton->GetSizePixel();
+ if (i >= mnLeftAlignCount)
+ {
+ Point aPos( nOffX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
+ pBtnData->mpButton->SetPosPixel( aPos );
+ nOffX += aBtnSize.Width();
+ nOffX += pBtnData->mnOffset;
+ }
+ else
+ {
+ Point aPos( nOffLeftAlignX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
+ pBtnData->mpButton->SetPosPixel( aPos );
+ nOffLeftAlignX += aBtnSize.Width();
+ nOffLeftAlignX += pBtnData->mnOffset;
+ }
+
+ pBtnData = pBtnData->mpNext;
+ i++;
+ }
+
+ nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y;
+ }
+
+ if ( mpFixedLine && mpFixedLine->IsVisible() )
+ {
+ nOffY -= mpFixedLine->GetSizePixel().Height();
+ mpFixedLine->SetPosSizePixel( 0, nOffY, aDlgSize.Width(), 0,
+ WINDOW_POSSIZE_POS | WINDOW_POSSIZE_WIDTH );
+ }
+
+ if ( mpViewWindow && mpViewWindow->IsVisible() )
+ {
+ long nViewOffX = 0;
+ long nViewOffY = 0;
+ long nViewWidth = 0;
+ long nViewHeight = 0;
+ long nDlgHeight = nOffY;
+ USHORT nViewPosFlags = WINDOW_POSSIZE_POS;
+ if ( meViewAlign == WINDOWALIGN_TOP )
+ {
+ nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
+ nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ nViewWidth = aDlgSize.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X*2);
+ nViewPosFlags |= WINDOW_POSSIZE_WIDTH;
+ }
+ else if ( meViewAlign == WINDOWALIGN_LEFT )
+ {
+ if ( mbEmptyViewMargin )
+ {
+ nViewOffX = 0;
+ nViewOffY = 0;
+ nViewHeight = nDlgHeight;
+ }
+ else
+ {
+ nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
+ nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
+ }
+ nViewPosFlags |= WINDOW_POSSIZE_HEIGHT;
+ }
+ else if ( meViewAlign == WINDOWALIGN_BOTTOM )
+ {
+ nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
+ nViewOffY = nDlgHeight-mpViewWindow->GetSizePixel().Height()-WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ nViewWidth = aDlgSize.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X*2);
+ nViewPosFlags |= WINDOW_POSSIZE_WIDTH;
+ }
+ else if ( meViewAlign == WINDOWALIGN_RIGHT )
+ {
+ nViewOffX = aDlgSize.Width()-mpViewWindow->GetSizePixel().Width()-WIZARDDIALOG_VIEW_DLGOFFSET_X;
+ nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
+ nViewPosFlags |= WINDOW_POSSIZE_HEIGHT;
+ }
+ mpViewWindow->SetPosSizePixel( nViewOffX, nViewOffY,
+ nViewWidth, nViewHeight,
+ nViewPosFlags );
+ }
+}
+
+
+long WizardDialog::LogicalCoordinateToPixel(int iCoordinate){
+ Size aLocSize = LogicToPixel(Size( iCoordinate, 0 ), MAP_APPFONT );
+ int iPixelCoordinate = aLocSize.Width();
+ return iPixelCoordinate;
+}
+
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::ImplPosTabPage()
+{
+ if ( !mpCurTabPage )
+ return;
+
+ if ( !IsInInitShow() )
+ {
+ // #100199# - On Unix initial size is equal to screen size, on Windows
+ // it's 0,0. One cannot calculate the size unless dialog is visible.
+ if ( !IsReallyVisible() )
+ return;
+ }
+
+ // ButtonBar-Hoehe berechnen
+ long nMaxHeight = 0;
+ ImplWizButtonData* pBtnData = mpFirstBtn;
+ while ( pBtnData )
+ {
+ long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
+ if ( nBtnHeight > nMaxHeight )
+ nMaxHeight = nBtnHeight;
+ pBtnData = pBtnData->mpNext;
+ }
+ if ( nMaxHeight )
+ nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
+ if ( mpFixedLine && mpFixedLine->IsVisible() )
+ nMaxHeight += mpFixedLine->GetSizePixel().Height();
+
+ // TabPage positionieren
+ Size aDlgSize = GetOutputSizePixel();
+ aDlgSize.Height() -= nMaxHeight;
+ long nOffX = 0;
+ long nOffY = 0;
+ if ( mpViewWindow && mpViewWindow->IsVisible() )
+ {
+ Size aViewSize = mpViewWindow->GetSizePixel();
+ if ( meViewAlign == WINDOWALIGN_TOP )
+ {
+ nOffY += aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ aDlgSize.Height() -= aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ }
+ else if ( meViewAlign == WINDOWALIGN_LEFT )
+ {
+ long nViewOffset = mbEmptyViewMargin ? 0 : WIZARDDIALOG_VIEW_DLGOFFSET_X;
+ nOffX += aViewSize.Width() + nViewOffset;
+ aDlgSize.Width() -= nOffX;
+ }
+ else if ( meViewAlign == WINDOWALIGN_BOTTOM )
+ aDlgSize.Height() -= aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
+ else if ( meViewAlign == WINDOWALIGN_RIGHT )
+ aDlgSize.Width() -= aViewSize.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X;
+ }
+ Point aPos( nOffX, nOffY );
+ mpCurTabPage->SetPosSizePixel( aPos, aDlgSize );
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::ImplShowTabPage( TabPage* pTabPage )
+{
+ if ( mpCurTabPage == pTabPage )
+ return;
+
+ TabPage* pOldTabPage = mpCurTabPage;
+ if ( pOldTabPage )
+ pOldTabPage->DeactivatePage();
+
+ mpCurTabPage = pTabPage;
+ if ( pTabPage )
+ {
+ ImplPosTabPage();
+ pTabPage->ActivatePage();
+ pTabPage->Show();
+ }
+
+ if ( pOldTabPage )
+ pOldTabPage->Hide();
+}
+
+// -----------------------------------------------------------------------
+
+TabPage* WizardDialog::ImplGetPage( USHORT nLevel ) const
+{
+ USHORT nTempLevel = 0;
+ ImplWizPageData* pPageData = mpFirstPage;
+ while ( pPageData )
+ {
+ if ( (nTempLevel == nLevel) || !pPageData->mpNext )
+ break;
+
+ nTempLevel++;
+ pPageData = pPageData->mpNext;
+ }
+
+ if ( pPageData )
+ return pPageData->mpPage;
+ return NULL;
+}
+
+// =======================================================================
+
+WizardDialog::WizardDialog( Window* pParent, WinBits nStyle ) :
+ ModalDialog( pParent, nStyle )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+WizardDialog::WizardDialog( Window* pParent, const ResId& rResId ) :
+ ModalDialog( pParent, rResId )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+WizardDialog::~WizardDialog()
+{
+ if ( mpFixedLine )
+ delete mpFixedLine;
+
+ // Remove all buttons
+ while ( mpFirstBtn )
+ RemoveButton( mpFirstBtn->mpButton );
+
+ // Remove all pages
+ while ( mpFirstPage )
+ RemovePage( mpFirstPage->mpPage );
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::Resize()
+{
+ if ( IsReallyShown() && !IsInInitShow() )
+ {
+ ImplPosCtrls();
+ ImplPosTabPage();
+ }
+
+ Dialog::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( IsDefaultSize() )
+ {
+ Size aDlgSize = GetPageSizePixel();
+ if ( !aDlgSize.Width() || !aDlgSize.Height() )
+ {
+ ImplWizPageData* pPageData = mpFirstPage;
+ while ( pPageData )
+ {
+ if ( pPageData->mpPage )
+ {
+ Size aPageSize = pPageData->mpPage->GetSizePixel();
+ if ( aPageSize.Width() > aDlgSize.Width() )
+ aDlgSize.Width() = aPageSize.Width();
+ if ( aPageSize.Height() > aDlgSize.Height() )
+ aDlgSize.Height() = aPageSize.Height();
+ }
+
+ pPageData = pPageData->mpNext;
+ }
+ }
+ ImplCalcSize( aDlgSize );
+ SetOutputSizePixel( aDlgSize );
+ }
+
+ ImplPosCtrls();
+ ImplPosTabPage();
+ ImplShowTabPage( ImplGetPage( mnCurLevel ) );
+ }
+
+ Dialog::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+long WizardDialog::Notify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && mpPrevBtn && mpNextBtn )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( aKeyCode.IsMod1() )
+ {
+ if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
+ {
+ if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
+ {
+ if ( mpPrevBtn->IsVisible() &&
+ mpPrevBtn->IsEnabled() && mpPrevBtn->IsInputEnabled() )
+ {
+ mpPrevBtn->SetPressed( TRUE );
+ mpPrevBtn->SetPressed( FALSE );
+ mpPrevBtn->Click();
+ }
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
+ {
+ if ( mpNextBtn->IsVisible() &&
+ mpNextBtn->IsEnabled() && mpNextBtn->IsInputEnabled() )
+ {
+ mpNextBtn->SetPressed( TRUE );
+ mpNextBtn->SetPressed( FALSE );
+ mpNextBtn->Click();
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return Dialog::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::ActivatePage()
+{
+ maActivateHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+long WizardDialog::DeactivatePage()
+{
+ if ( maDeactivateHdl.IsSet() )
+ return maDeactivateHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL WizardDialog::ShowNextPage()
+{
+ return ShowPage( mnCurLevel+1 );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL WizardDialog::ShowPrevPage()
+{
+ if ( !mnCurLevel )
+ return FALSE;
+ return ShowPage( mnCurLevel-1 );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL WizardDialog::ShowPage( USHORT nLevel )
+{
+ if ( DeactivatePage() )
+ {
+ mnCurLevel = nLevel;
+ ActivatePage();
+ ImplShowTabPage( ImplGetPage( mnCurLevel ) );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL WizardDialog::Finnish( long nResult )
+{
+ if ( DeactivatePage() )
+ {
+ if ( mpCurTabPage )
+ mpCurTabPage->DeactivatePage();
+
+ if ( IsInExecute() )
+ EndDialog( nResult );
+ else if ( GetStyle() & WB_CLOSEABLE )
+ Close();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::AddPage( TabPage* pPage )
+{
+ ImplWizPageData* pNewPageData = new ImplWizPageData;
+ pNewPageData->mpNext = NULL;
+ pNewPageData->mpPage = pPage;
+
+ if ( !mpFirstPage )
+ mpFirstPage = pNewPageData;
+ else
+ {
+ ImplWizPageData* pPageData = mpFirstPage;
+ while ( pPageData->mpNext )
+ pPageData = pPageData->mpNext;
+ pPageData->mpNext = pNewPageData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::RemovePage( TabPage* pPage )
+{
+ ImplWizPageData* pPrevPageData = NULL;
+ ImplWizPageData* pPageData = mpFirstPage;
+ while ( pPageData )
+ {
+ if ( pPageData->mpPage == pPage )
+ {
+ if ( pPrevPageData )
+ pPrevPageData->mpNext = pPageData->mpNext;
+ else
+ mpFirstPage = pPageData->mpNext;
+ if ( pPage == mpCurTabPage )
+ mpCurTabPage = NULL;
+ delete pPageData;
+ return;
+ }
+
+ pPrevPageData = pPageData;
+ pPageData = pPageData->mpNext;
+ }
+
+ DBG_ERROR( "WizardDialog::RemovePage() - Page not in list" );
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::SetPage( USHORT nLevel, TabPage* pPage )
+{
+ USHORT nTempLevel = 0;
+ ImplWizPageData* pPageData = mpFirstPage;
+ while ( pPageData )
+ {
+ if ( (nTempLevel == nLevel) || !pPageData->mpNext )
+ break;
+
+ nTempLevel++;
+ pPageData = pPageData->mpNext;
+ }
+
+ if ( pPageData )
+ {
+ if ( pPageData->mpPage == mpCurTabPage )
+ mpCurTabPage = NULL;
+ pPageData->mpPage = pPage;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TabPage* WizardDialog::GetPage( USHORT nLevel ) const
+{
+ USHORT nTempLevel = 0;
+ ImplWizPageData* pPageData = mpFirstPage;
+ while ( pPageData )
+ {
+ if ( nTempLevel == nLevel )
+ return pPageData->mpPage;
+
+ nTempLevel++;
+ pPageData = pPageData->mpNext;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::AddButton( Button* pButton, long nOffset )
+{
+ ImplWizButtonData* pNewBtnData = new ImplWizButtonData;
+ pNewBtnData->mpNext = NULL;
+ pNewBtnData->mpButton = pButton;
+ pNewBtnData->mnOffset = nOffset;
+
+ if ( !mpFirstBtn )
+ mpFirstBtn = pNewBtnData;
+ else
+ {
+ ImplWizButtonData* pBtnData = mpFirstBtn;
+ while ( pBtnData->mpNext )
+ pBtnData = pBtnData->mpNext;
+ pBtnData->mpNext = pNewBtnData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::RemoveButton( Button* pButton )
+{
+ ImplWizButtonData* pPrevBtnData = NULL;
+ ImplWizButtonData* pBtnData = mpFirstBtn;
+ while ( pBtnData )
+ {
+ if ( pBtnData->mpButton == pButton )
+ {
+ if ( pPrevBtnData )
+ pPrevBtnData->mpNext = pBtnData->mpNext;
+ else
+ mpFirstBtn = pBtnData->mpNext;
+ delete pBtnData;
+ return;
+ }
+
+ pPrevBtnData = pBtnData;
+ pBtnData = pBtnData->mpNext;
+ }
+
+ DBG_ERROR( "WizardDialog::RemoveButton() - Button not in list" );
+}
+
+// -----------------------------------------------------------------------
+
+void WizardDialog::ShowButtonFixedLine( BOOL bVisible )
+{
+ if ( !mpFixedLine )
+ {
+ if ( !bVisible )
+ return;
+
+ mpFixedLine = new FixedLine( this );
+ }
+
+ mpFixedLine->Show( bVisible );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL WizardDialog::IsButtonFixedLineVisible()
+{
+ return (mpFixedLine && mpFixedLine->IsVisible());
+}
diff --git a/svtools/source/edit/editsyntaxhighlighter.cxx b/svtools/source/edit/editsyntaxhighlighter.cxx
new file mode 100644
index 000000000000..01bb7ad41682
--- /dev/null
+++ b/svtools/source/edit/editsyntaxhighlighter.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_svtools.hxx"
+
+#include <svtools/svmedit.hxx>
+#include <svtools/xtextedt.hxx>
+#include <svtools/editsyntaxhighlighter.hxx>
+#include "../../inc/txtattr.hxx"
+
+
+MultiLineEditSyntaxHighlight::MultiLineEditSyntaxHighlight( Window* pParent, WinBits nWinStyle,
+ HighlighterLanguage aLanguage): MultiLineEdit(pParent,nWinStyle), mbDoBracketHilight(true)
+{
+ EnableUpdateData(300);
+ aHighlighter.initialize( aLanguage );
+}
+
+MultiLineEditSyntaxHighlight::MultiLineEditSyntaxHighlight( Window* pParent, const ResId& rResId ,
+ HighlighterLanguage aLanguage): MultiLineEdit(pParent,rResId), mbDoBracketHilight(true)
+{
+ EnableUpdateData(300);
+ aHighlighter.initialize( aLanguage );
+}
+
+MultiLineEditSyntaxHighlight::~MultiLineEditSyntaxHighlight()
+{
+}
+
+void MultiLineEditSyntaxHighlight::EnableBracketHilight(bool aHilight)
+{
+ mbDoBracketHilight = aHilight;
+}
+
+bool MultiLineEditSyntaxHighlight::IsBracketHilight()
+{
+ return mbDoBracketHilight;
+}
+
+void MultiLineEditSyntaxHighlight::SetText(const String& rNewText)
+{
+ MultiLineEdit::SetText(rNewText);
+ UpdateData();
+}
+
+void MultiLineEditSyntaxHighlight::DoBracketHilight(USHORT aKey)
+{
+ TextSelection aCurrentPos = GetTextView()->GetSelection();
+ xub_StrLen aStartPos = aCurrentPos.GetStart().GetIndex();
+ ULONG nStartPara = aCurrentPos.GetStart().GetPara();
+ USHORT aCount = 0;
+ int aChar = -1;
+
+ switch (aKey)
+ {
+ case '\'': // no break
+ case '"':
+ {
+ aChar = aKey;
+ break;
+ }
+ case '}' :
+ {
+ aChar = '{';
+ break;
+ }
+ case ')':
+ {
+ aChar = '(';
+ break;
+ }
+ case ']':
+ {
+ aChar = '[';
+ break;
+ }
+ }
+
+ if (aChar != -1)
+ {
+ for (long aPara =nStartPara; aPara>=0;--aPara)
+ {
+ if ( aStartPos == 0 )
+ continue;
+
+ String aLine( GetTextEngine()->GetText( aPara ) );
+ for (USHORT i = ((unsigned long)aPara==nStartPara) ? aStartPos-1 : (USHORT)(aLine.Len()-1); i>0; --i)
+ {
+ if (aLine.GetChar(i)==aChar)
+ {
+ if (!aCount)
+ {
+ GetTextEngine()->SetAttrib( TextAttribFontWeight( WEIGHT_ULTRABOLD ), aPara, i, i+1, TRUE );
+ GetTextEngine()->SetAttrib( TextAttribFontColor( Color(0,0,0) ), aPara, i, i+1, TRUE );
+ GetTextEngine()->SetAttrib( TextAttribFontWeight( WEIGHT_ULTRABOLD ), nStartPara, aStartPos, aStartPos, TRUE );
+ GetTextEngine()->SetAttrib( TextAttribFontColor( Color(0,0,0) ), nStartPara, aStartPos, aStartPos, TRUE );
+ return;
+ }
+ else
+ aCount--;
+ }
+ if (aLine.GetChar(i)==aKey)
+ aCount++;
+ }
+ }
+ }
+}
+
+long MultiLineEditSyntaxHighlight::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( mbDoBracketHilight && (rNEvt.GetType() == EVENT_KEYINPUT) )
+ DoBracketHilight(rNEvt.GetKeyEvent()->GetCharCode());
+
+ return MultiLineEdit::PreNotify(rNEvt);
+}
+
+Color MultiLineEditSyntaxHighlight::GetColorValue(TokenTypes aToken)
+{
+ Color aColor;
+ switch (aHighlighter.GetLanguage())
+ {
+ case HIGHLIGHT_SQL:
+ {
+ switch (aToken)
+ {
+ case TT_IDENTIFIER: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLIDENTIFIER).nColor; break;
+ case TT_NUMBER: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLNUMBER).nColor; break;
+ case TT_STRING: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLSTRING).nColor; break;
+ case TT_OPERATOR: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLOPERATOR).nColor; break;
+ case TT_KEYWORDS: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLKEYWORD).nColor; break;
+ case TT_PARAMETER: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLPARAMETER).nColor; break;
+ case TT_COMMENT: aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLCOMMENT).nColor; break;
+ default: aColor = Color(0,0,0);
+ }
+ break;
+ }
+ case HIGHLIGHT_BASIC:
+ {
+ switch (aToken)
+ {
+ case TT_IDENTIFIER: aColor = Color(255,0,0); break;
+ case TT_COMMENT: aColor = Color(0,0,45); break;
+ case TT_NUMBER: aColor = Color(204,102,204); break;
+ case TT_STRING: aColor = Color(0,255,45); break;
+ case TT_OPERATOR: aColor = Color(0,0,100); break;
+ case TT_KEYWORDS: aColor = Color(0,0,255); break;
+ case TT_ERROR : aColor = Color(0,255,255); break;
+ default: aColor = Color(0,0,0);
+ }
+ break;
+ }
+ default: aColor = Color(0,0,0);
+
+ }
+ return aColor;
+}
+
+void MultiLineEditSyntaxHighlight::UpdateData()
+{
+ // syntax highlighting
+ // this must be possible improved by using notifychange correctly
+ BOOL bTempModified = GetTextEngine()->IsModified();
+ for (unsigned int nLine=0; nLine < GetTextEngine()->GetParagraphCount(); nLine++)
+ {
+ String aLine( GetTextEngine()->GetText( nLine ) );
+ Range aChanges = aHighlighter.notifyChange( nLine, 0, &aLine, 1 );
+
+ GetTextEngine()->RemoveAttribs( nLine, TRUE );
+ HighlightPortions aPortions;
+ aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
+ for ( USHORT i = 0; i < aPortions.Count(); i++ )
+ {
+ HighlightPortion& r = aPortions[i];
+ GetTextEngine()->SetAttrib( TextAttribFontColor( GetColorValue(r.tokenType) ), nLine, r.nBegin, r.nEnd, TRUE );
+ }
+ }
+ GetTextView()->ShowCursor( false, true );
+ GetTextEngine()->SetModified(bTempModified);
+}
diff --git a/svtools/source/edit/makefile.mk b/svtools/source/edit/makefile.mk
new file mode 100644
index 000000000000..58a63be58f78
--- /dev/null
+++ b/svtools/source/edit/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=svtools
+TARGET=edit
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/textdata.obj \
+ $(SLO)$/textdoc.obj \
+ $(SLO)$/texteng.obj \
+ $(SLO)$/textundo.obj \
+ $(SLO)$/textview.obj \
+ $(SLO)$/txtattr.obj \
+ $(SLO)$/xtextedt.obj \
+ $(SLO)$/sychconv.obj \
+ $(SLO)$/svmedit.obj \
+ $(SLO)$/svmedit2.obj \
+ $(SLO)$/textwindowpeer.obj \
+ $(SLO)$/syntaxhighlight.obj \
+ $(SLO)$/editsyntaxhighlighter.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/textview.obj \
+ $(SLO)$/textdoc.obj \
+ $(SLO)$/texteng.obj \
+ $(SLO)$/textwindowpeer.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/edit/svmedit.cxx b/svtools/source/edit/svmedit.cxx
new file mode 100644
index 000000000000..daaff472d1cc
--- /dev/null
+++ b/svtools/source/edit/svmedit.cxx
@@ -0,0 +1,1656 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+
+#include <memory>
+
+#include "unoiface.hxx"
+
+#include <tools/rc.h>
+
+#include <vcl/decoview.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svtools/svmedit.hxx>
+#include <svtools/xtextedt.hxx>
+#include <svl/brdcst.hxx>
+#include <svl/undo.hxx>
+#include <svtools/textwindowpeer.hxx>
+#include <svl/lstner.hxx>
+#include <svl/smplhint.hxx>
+
+
+// IDs erstmal aus VCL geklaut, muss mal richtig delivert werden...
+#define SV_MENU_EDIT_UNDO 1
+#define SV_MENU_EDIT_CUT 2
+#define SV_MENU_EDIT_COPY 3
+#define SV_MENU_EDIT_PASTE 4
+#define SV_MENU_EDIT_DELETE 5
+#define SV_MENU_EDIT_SELECTALL 6
+#define SV_MENU_EDIT_INSERTSYMBOL 7
+#include <vcl/scrbar.hxx>
+
+namespace css = ::com::sun::star;
+
+class TextWindow : public Window
+{
+private:
+ ExtTextEngine* mpExtTextEngine;
+ ExtTextView* mpExtTextView;
+
+ BOOL mbInMBDown;
+ BOOL mbFocusSelectionHide;
+ BOOL mbIgnoreTab;
+ BOOL mbActivePopup;
+ BOOL mbSelectOnTab;
+
+public:
+ TextWindow( Window* pParent );
+ ~TextWindow();
+
+ ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; }
+ ExtTextView* GetTextView() const { return mpExtTextView; }
+
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void KeyInput( const KeyEvent& rKEvent );
+
+ virtual void Command( const CommandEvent& rCEvt );
+
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Resize();
+
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ BOOL IsAutoFocusHide() const { return mbFocusSelectionHide; }
+ void SetAutoFocusHide( BOOL bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
+
+ BOOL IsIgnoreTab() const { return mbIgnoreTab; }
+ void SetIgnoreTab( BOOL bIgnore ) { mbIgnoreTab = bIgnore; }
+
+ void DisableSelectionOnFocus() {mbSelectOnTab = sal_False;}
+
+ virtual
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
+ GetComponentInterface(BOOL bCreate = TRUE);
+};
+
+
+class ImpSvMEdit : public SfxListener
+{
+private:
+ MultiLineEdit* pSvMultiLineEdit;
+
+ TextWindow* mpTextWindow;
+ ScrollBar* mpHScrollBar;
+ ScrollBar* mpVScrollBar;
+ ScrollBarBox* mpScrollBox;
+
+ Point maTextWindowOffset;
+ xub_StrLen mnTextWidth;
+ mutable Selection maSelection;
+
+protected:
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+ void ImpUpdateSrollBarVis( WinBits nWinStyle );
+ void ImpInitScrollBars();
+ void ImpSetScrollBarRanges();
+ void ImpSetHScrollBarThumbPos();
+ DECL_LINK( ScrollHdl, ScrollBar* );
+
+public:
+ ImpSvMEdit( MultiLineEdit* pSvMultiLineEdit, WinBits nWinStyle );
+ ~ImpSvMEdit();
+
+ void SetModified( BOOL bMod );
+ BOOL IsModified() const;
+
+ void SetReadOnly( BOOL bRdOnly );
+ BOOL IsReadOnly() const;
+
+ void SetMaxTextLen( xub_StrLen nLen );
+ xub_StrLen GetMaxTextLen() const;
+
+ void SetInsertMode( BOOL bInsert );
+ BOOL IsInsertMode() const;
+
+ void InsertText( const String& rStr );
+ String GetSelected() const;
+ String GetSelected( LineEnd aSeparator ) const;
+
+ void SetSelection( const Selection& rSelection );
+ const Selection& GetSelection() const;
+
+ void Cut();
+ void Copy();
+ void Paste();
+
+ void SetText( const String& rStr );
+ String GetText() const;
+ String GetText( LineEnd aSeparator ) const;
+ String GetTextLines() const;
+ String GetTextLines( LineEnd aSeparator ) const;
+
+ void Resize();
+ void GetFocus();
+
+ BOOL HandleCommand( const CommandEvent& rCEvt );
+
+ void Enable( BOOL bEnable );
+
+ Size CalcMinimumSize() const;
+ Size CalcSize( USHORT nColumns, USHORT nLines ) const;
+ void GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const;
+
+ void SetAlign( WinBits nWinStyle );
+
+ void InitFromStyle( WinBits nWinStyle );
+
+ TextWindow* GetTextWindow() { return mpTextWindow; }
+ ScrollBar* GetHScrollBar() { return mpHScrollBar; }
+ ScrollBar* GetVScrollBar() { return mpVScrollBar; }
+
+ void SetTextWindowOffset( const Point& rOffset );
+};
+
+ImpSvMEdit::ImpSvMEdit( MultiLineEdit* pEdt, WinBits nWinStyle )
+ :mpHScrollBar(NULL)
+ ,mpVScrollBar(NULL)
+ ,mpScrollBox(NULL)
+{
+ pSvMultiLineEdit = pEdt;
+ mnTextWidth = 0;
+ mpTextWindow = new TextWindow( pEdt );
+ mpTextWindow->Show();
+ InitFromStyle( nWinStyle );
+ StartListening( *mpTextWindow->GetTextEngine() );
+}
+
+void ImpSvMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
+{
+ const BOOL bHaveVScroll = (NULL != mpVScrollBar);
+ const BOOL bHaveHScroll = (NULL != mpHScrollBar);
+ const BOOL bHaveScrollBox = (NULL != mpScrollBox);
+
+ BOOL bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
+ const BOOL bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
+
+ const BOOL bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
+ if ( !bNeedVScroll && bAutoVScroll )
+ {
+ TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
+ ULONG nOverallTextHeight(0);
+ for ( ULONG i=0; i<rEngine.GetParagraphCount(); ++i )
+ nOverallTextHeight += rEngine.GetTextHeight( i );
+ if ( nOverallTextHeight > (ULONG)mpTextWindow->GetOutputSizePixel().Height() )
+ bNeedVScroll = true;
+ }
+
+ const BOOL bNeedScrollBox = bNeedVScroll && bNeedHScroll;
+
+ BOOL bScrollbarsChanged = false;
+ if ( bHaveVScroll != bNeedVScroll )
+ {
+ delete mpVScrollBar;
+ mpVScrollBar = bNeedVScroll ? new ScrollBar( pSvMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL;
+
+ if ( bNeedVScroll )
+ {
+ mpVScrollBar->Show();
+ mpVScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
+ }
+
+ bScrollbarsChanged = sal_True;
+ }
+
+ if ( bHaveHScroll != bNeedHScroll )
+ {
+ delete mpHScrollBar;
+ mpHScrollBar = bNeedHScroll ? new ScrollBar( pSvMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL;
+
+ if ( bNeedHScroll )
+ {
+ mpHScrollBar->Show();
+ mpHScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
+ }
+
+ bScrollbarsChanged = sal_True;
+ }
+
+ if ( bHaveScrollBox != bNeedScrollBox )
+ {
+ delete mpScrollBox;
+ mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pSvMultiLineEdit, WB_SIZEABLE ) : NULL;
+
+ if ( bNeedScrollBox )
+ mpScrollBox->Show();
+ }
+
+ if ( bScrollbarsChanged )
+ {
+ ImpInitScrollBars();
+ Resize();
+ }
+}
+
+void ImpSvMEdit::InitFromStyle( WinBits nWinStyle )
+{
+ ImpUpdateSrollBarVis( nWinStyle );
+ SetAlign( nWinStyle );
+
+ if ( nWinStyle & WB_NOHIDESELECTION )
+ mpTextWindow->SetAutoFocusHide( FALSE );
+ else
+ mpTextWindow->SetAutoFocusHide( TRUE );
+
+ if ( nWinStyle & WB_READONLY )
+ mpTextWindow->GetTextView()->SetReadOnly( TRUE );
+ else
+ mpTextWindow->GetTextView()->SetReadOnly( FALSE );
+
+ if ( nWinStyle & WB_IGNORETAB )
+ {
+ mpTextWindow->SetIgnoreTab( TRUE );
+ }
+ else
+ {
+ mpTextWindow->SetIgnoreTab( FALSE );
+ // #103667# MultiLineEdit has the flag, but focusable window also needs this flag
+ WinBits nStyle = mpTextWindow->GetStyle();
+ nStyle |= WINDOW_DLGCTRL_MOD1TAB;
+ mpTextWindow->SetStyle( nStyle );
+ }
+}
+
+ImpSvMEdit::~ImpSvMEdit()
+{
+ EndListening( *mpTextWindow->GetTextEngine() );
+ delete mpTextWindow;
+ delete mpHScrollBar;
+ delete mpVScrollBar;
+ delete mpScrollBox;
+}
+
+void ImpSvMEdit::ImpSetScrollBarRanges()
+{
+ if ( mpVScrollBar )
+ {
+ ULONG nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
+ mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) );
+ }
+ if ( mpHScrollBar )
+ {
+// ULONG nTextWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
+ // Es gibt kein Notify bei Breiten-Aenderung...
+// ULONG nW = Max( (ULONG)mpTextWindow->GetOutputSizePixel().Width()*5, (ULONG)nTextWidth );
+// mpHScrollBar->SetRange( Range( 0, (long)nW ) );
+ mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
+ }
+}
+
+void ImpSvMEdit::ImpInitScrollBars()
+{
+ static const sal_Unicode sampleText[] = { 'x', '\0' };
+ if ( mpHScrollBar || mpVScrollBar )
+ {
+ ImpSetScrollBarRanges();
+ Size aCharBox;
+ aCharBox.Width() = mpTextWindow->GetTextWidth( sampleText );
+ aCharBox.Height() = mpTextWindow->GetTextHeight();
+ Size aOutSz = mpTextWindow->GetOutputSizePixel();
+ if ( mpHScrollBar )
+ {
+ mpHScrollBar->SetVisibleSize( aOutSz.Width() );
+ mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
+ mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
+ ImpSetHScrollBarThumbPos();
+ }
+ if ( mpVScrollBar )
+ {
+ mpVScrollBar->SetVisibleSize( aOutSz.Height() );
+ mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
+ mpVScrollBar->SetLineSize( aCharBox.Height() );
+ mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
+ }
+ }
+}
+
+void ImpSvMEdit::ImpSetHScrollBarThumbPos()
+{
+ long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
+ if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
+ mpHScrollBar->SetThumbPos( nX );
+ else
+ mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
+
+}
+
+IMPL_LINK( ImpSvMEdit, ScrollHdl, ScrollBar*, pCurScrollBar )
+{
+ long nDiffX = 0, nDiffY = 0;
+
+ if ( pCurScrollBar == mpVScrollBar )
+ nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
+ else if ( pCurScrollBar == mpHScrollBar )
+ nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
+
+ mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
+ // mpTextWindow->GetTextView()->ShowCursor( FALSE, TRUE );
+
+ return 0;
+}
+
+
+// void ImpSvMEdit::ImpModified()
+// {
+// // Wann wird das gerufen ?????????????????????
+// pSvMultiLineEdit->Modify();
+// }
+
+void ImpSvMEdit::SetAlign( WinBits nWinStyle )
+{
+ BOOL bRTL = Application::GetSettings().GetLayoutRTL();
+ mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
+
+ if ( nWinStyle & WB_CENTER )
+ mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER );
+ else if ( nWinStyle & WB_RIGHT )
+ mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT );
+ else if ( nWinStyle & WB_LEFT )
+ mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT );
+}
+
+void ImpSvMEdit::SetTextWindowOffset( const Point& rOffset )
+{
+ maTextWindowOffset = rOffset;
+ Resize();
+}
+
+void ImpSvMEdit::SetModified( BOOL bMod )
+{
+ mpTextWindow->GetTextEngine()->SetModified( bMod );
+}
+
+BOOL ImpSvMEdit::IsModified() const
+{
+ return mpTextWindow->GetTextEngine()->IsModified();
+}
+
+void ImpSvMEdit::SetInsertMode( BOOL bInsert )
+{
+ mpTextWindow->GetTextView()->SetInsertMode( bInsert );
+}
+
+void ImpSvMEdit::SetReadOnly( BOOL bRdOnly )
+{
+ mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
+ // Farbe anpassen ???????????????????????????
+}
+
+BOOL ImpSvMEdit::IsReadOnly() const
+{
+ return mpTextWindow->GetTextView()->IsReadOnly();
+}
+
+void ImpSvMEdit::SetMaxTextLen( xub_StrLen nLen )
+{
+ mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
+}
+
+xub_StrLen ImpSvMEdit::GetMaxTextLen() const
+{
+ return sal::static_int_cast< xub_StrLen >(
+ mpTextWindow->GetTextEngine()->GetMaxTextLen());
+}
+
+void ImpSvMEdit::InsertText( const String& rStr )
+{
+ mpTextWindow->GetTextView()->InsertText( rStr );
+}
+
+String ImpSvMEdit::GetSelected() const
+{
+ return mpTextWindow->GetTextView()->GetSelected();
+}
+
+String ImpSvMEdit::GetSelected( LineEnd aSeparator ) const
+{
+ return mpTextWindow->GetTextView()->GetSelected( aSeparator );
+}
+
+void ImpSvMEdit::Resize()
+{
+ size_t nIteration = 1;
+ do
+ {
+ WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
+ if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
+ ImpUpdateSrollBarVis( nWinStyle );
+
+ Size aSz = pSvMultiLineEdit->GetOutputSizePixel();
+ Size aEditSize = aSz;
+ long nSBWidth = pSvMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
+ nSBWidth = pSvMultiLineEdit->CalcZoom( nSBWidth );
+
+ if ( mpHScrollBar )
+ aSz.Height() -= nSBWidth+1;
+ if ( mpVScrollBar )
+ aSz.Width() -= nSBWidth+1;
+
+ if ( !mpHScrollBar )
+ mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
+ else
+ mpHScrollBar->SetPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
+
+ Point aTextWindowPos( maTextWindowOffset );
+ if ( mpVScrollBar )
+ {
+ if( Application::GetSettings().GetLayoutRTL() )
+ {
+ mpVScrollBar->SetPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
+ aTextWindowPos.X() += nSBWidth;
+ }
+ else
+ mpVScrollBar->SetPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
+ }
+
+ if ( mpScrollBox )
+ mpScrollBox->SetPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
+
+ Size aTextWindowSize( aSz );
+ aTextWindowSize.Width() -= maTextWindowOffset.X();
+ aTextWindowSize.Height() -= maTextWindowOffset.Y();
+ if ( aTextWindowSize.Width() < 0 )
+ aTextWindowSize.Width() = 0;
+ if ( aTextWindowSize.Height() < 0 )
+ aTextWindowSize.Height() = 0;
+
+ Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
+ mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
+ if ( aOldTextWindowSize == aTextWindowSize )
+ break;
+
+ // Changing the text window size might effectively have changed the need for
+ // scrollbars, so do another iteration.
+ ++nIteration;
+ OSL_ENSURE( nIteration < 3, "ImpSvMEdit::Resize: isn't this expected to terminate with the second iteration?" );
+
+ } while ( nIteration <= 3 ); // artificial break after four iterations
+
+ ImpInitScrollBars();
+}
+
+void ImpSvMEdit::GetFocus()
+{
+ mpTextWindow->GrabFocus();
+}
+
+void ImpSvMEdit::Cut()
+{
+ if ( !mpTextWindow->GetTextView()->IsReadOnly() )
+ mpTextWindow->GetTextView()->Cut();
+}
+
+void ImpSvMEdit::Copy()
+{
+ mpTextWindow->GetTextView()->Copy();
+}
+
+void ImpSvMEdit::Paste()
+{
+ if ( !mpTextWindow->GetTextView()->IsReadOnly() )
+ mpTextWindow->GetTextView()->Paste();
+}
+
+void ImpSvMEdit::SetText( const String& rStr )
+{
+ BOOL bWasModified = mpTextWindow->GetTextEngine()->IsModified();
+ mpTextWindow->GetTextEngine()->SetText( rStr );
+ if ( !bWasModified )
+ mpTextWindow->GetTextEngine()->SetModified( FALSE );
+
+ mpTextWindow->GetTextView()->SetSelection( TextSelection() );
+
+ WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
+ if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
+ ImpUpdateSrollBarVis( nWinStyle );
+}
+
+String ImpSvMEdit::GetText() const
+{
+ return mpTextWindow->GetTextEngine()->GetText();
+}
+
+String ImpSvMEdit::GetText( LineEnd aSeparator ) const
+{
+ return mpTextWindow->GetTextEngine()->GetText( aSeparator );
+}
+
+String ImpSvMEdit::GetTextLines() const
+{
+ return mpTextWindow->GetTextEngine()->GetTextLines();
+}
+
+String ImpSvMEdit::GetTextLines( LineEnd aSeparator ) const
+{
+ return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
+}
+
+void ImpSvMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( TextHint ) )
+ {
+ const TextHint& rTextHint = (const TextHint&)rHint;
+ if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
+ {
+ if ( mpHScrollBar )
+ ImpSetHScrollBarThumbPos();
+ if ( mpVScrollBar )
+ mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
+ {
+ if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
+ {
+ long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
+ long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
+ if ( nTextHeight < nOutHeight )
+ mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
+ }
+
+ ImpSetScrollBarRanges();
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
+ {
+ if ( mpHScrollBar )
+ {
+ ULONG nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
+ if ( nWidth != mnTextWidth )
+ {
+ mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth);
+ mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
+ ImpSetHScrollBarThumbPos();
+ }
+ }
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
+ {
+ pSvMultiLineEdit->Modify();
+ }
+ }
+}
+
+void ImpSvMEdit::SetSelection( const Selection& rSelection )
+{
+ String aText = mpTextWindow->GetTextEngine()->GetText();
+
+ Selection aNewSelection( rSelection );
+ if ( aNewSelection.Min() < 0 )
+ aNewSelection.Min() = 0;
+ else if ( aNewSelection.Min() > aText.Len() )
+ aNewSelection.Min() = aText.Len();
+ if ( aNewSelection.Max() < 0 )
+ aNewSelection.Max() = 0;
+ else if ( aNewSelection.Max() > aText.Len() )
+ aNewSelection.Max() = aText.Len();
+
+ long nEnd = Max( aNewSelection.Min(), aNewSelection.Max() );
+ TextSelection aTextSel;
+ ULONG nPara = 0;
+ USHORT nChar = 0;
+ USHORT x = 0;
+ while ( x <= nEnd )
+ {
+ if ( x == aNewSelection.Min() )
+ aTextSel.GetStart() = TextPaM( nPara, nChar );
+ if ( x == aNewSelection.Max() )
+ aTextSel.GetEnd() = TextPaM( nPara, nChar );
+
+ if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) )
+ {
+ nPara++;
+ nChar = 0;
+ }
+ else
+ nChar++;
+ x++;
+ }
+ mpTextWindow->GetTextView()->SetSelection( aTextSel );
+}
+
+const Selection& ImpSvMEdit::GetSelection() const
+{
+ maSelection = Selection();
+ TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
+ aTextSel.Justify();
+ // Selektion flachklopfen => jeder Umbruch ein Zeichen...
+
+ ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
+ // Absaetze davor:
+ ULONG n;
+ for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ )
+ {
+ maSelection.Min() += pExtTextEngine->GetTextLen( n );
+ maSelection.Min()++;
+ }
+
+ // Erster Absatz mit Selektion:
+ maSelection.Max() = maSelection.Min();
+ maSelection.Min() += aTextSel.GetStart().GetIndex();
+
+ for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ )
+ {
+ maSelection.Max() += pExtTextEngine->GetTextLen( n );
+ maSelection.Max()++;
+ }
+
+ maSelection.Max() += aTextSel.GetEnd().GetIndex();
+
+ return maSelection;
+}
+
+Size ImpSvMEdit::CalcMinimumSize() const
+{
+ Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
+ mpTextWindow->GetTextEngine()->GetTextHeight() );
+
+ if ( mpHScrollBar )
+ aSz.Height() += mpHScrollBar->GetSizePixel().Height();
+ if ( mpVScrollBar )
+ aSz.Width() += mpVScrollBar->GetSizePixel().Width();
+
+ return aSz;
+}
+
+Size ImpSvMEdit::CalcSize( USHORT nColumns, USHORT nLines ) const
+{
+ static const sal_Unicode sampleText[] = { 'X', '\0' };
+
+ Size aSz;
+ Size aCharSz;
+ aCharSz.Width() = mpTextWindow->GetTextWidth( sampleText );
+ aCharSz.Height() = mpTextWindow->GetTextHeight();
+
+ if ( nLines )
+ aSz.Height() = nLines*aCharSz.Height();
+ else
+ aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight();
+
+ if ( nColumns )
+ aSz.Width() = nColumns*aCharSz.Width();
+ else
+ aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth();
+
+ if ( mpHScrollBar )
+ aSz.Height() += mpHScrollBar->GetSizePixel().Height();
+ if ( mpVScrollBar )
+ aSz.Width() += mpVScrollBar->GetSizePixel().Width();
+
+ return aSz;
+}
+
+void ImpSvMEdit::GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const
+{
+ static const sal_Unicode sampleText[] = { 'x', '\0' };
+ Size aOutSz = mpTextWindow->GetOutputSizePixel();
+ Size aCharSz( mpTextWindow->GetTextWidth( sampleText ), mpTextWindow->GetTextHeight() );
+ rnCols = (USHORT) (aOutSz.Width()/aCharSz.Width());
+ rnLines = (USHORT) (aOutSz.Height()/aCharSz.Height());
+}
+
+void ImpSvMEdit::Enable( BOOL bEnable )
+{
+ mpTextWindow->Enable( bEnable );
+ if ( mpHScrollBar )
+ mpHScrollBar->Enable( bEnable );
+ if ( mpVScrollBar )
+ mpVScrollBar->Enable( bEnable );
+}
+
+BOOL ImpSvMEdit::HandleCommand( const CommandEvent& rCEvt )
+{
+ BOOL bDone = FALSE;
+ if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
+ ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
+ ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
+ {
+ mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
+ bDone = TRUE;
+ }
+ return bDone;
+}
+
+
+TextWindow::TextWindow( Window* pParent ) : Window( pParent )
+{
+ mbInMBDown = FALSE;
+ mbSelectOnTab = TRUE;
+ mbFocusSelectionHide = FALSE;
+ mbIgnoreTab = FALSE;
+ mbActivePopup = FALSE;
+ mbSelectOnTab = TRUE;
+
+ SetPointer( Pointer( POINTER_TEXT ) );
+
+ mpExtTextEngine = new ExtTextEngine;
+ mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN );
+ if( pParent->GetStyle() & WB_BORDER )
+ mpExtTextEngine->SetLeftMargin( 2 );
+ mpExtTextEngine->SetLocale( GetSettings().GetLocale() );
+ mpExtTextView = new ExtTextView( mpExtTextEngine, this );
+ mpExtTextEngine->InsertView( mpExtTextView );
+ mpExtTextEngine->EnableUndo( TRUE );
+ mpExtTextView->ShowCursor();
+
+ Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
+ SetBackground( aBackgroundColor );
+ pParent->SetBackground( aBackgroundColor );
+}
+
+TextWindow::~TextWindow()
+{
+ delete mpExtTextView;
+ delete mpExtTextEngine;
+}
+
+void TextWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ mpExtTextView->MouseMove( rMEvt );
+ Window::MouseMove( rMEvt );
+}
+
+void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ mbInMBDown = TRUE; // Dann im GetFocus nicht alles selektieren wird
+ mpExtTextView->MouseButtonDown( rMEvt );
+ Window::MouseButtonDown( rMEvt );
+ GrabFocus();
+ mbInMBDown = FALSE;
+}
+
+void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ mpExtTextView->MouseButtonUp( rMEvt );
+ Window::MouseButtonUp( rMEvt );
+}
+
+void TextWindow::KeyInput( const KeyEvent& rKEvent )
+{
+ BOOL bDone = FALSE;
+ USHORT nCode = rKEvent.GetKeyCode().GetCode();
+ if ( nCode == com::sun::star::awt::Key::SELECT_ALL ||
+ ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
+ )
+ {
+ mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
+ bDone = TRUE;
+ }
+ else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
+ {
+ if ( Edit::GetGetSpecialCharsFunction() )
+ {
+ // Damit die Selektion erhalten bleibt
+ mbActivePopup = TRUE;
+ XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
+ if ( aChars.Len() )
+ {
+ mpExtTextView->InsertText( aChars );
+ mpExtTextView->GetTextEngine()->SetModified( TRUE );
+ }
+ mbActivePopup = FALSE;
+ bDone = TRUE;
+ }
+ }
+ else if ( nCode == KEY_TAB )
+ {
+ if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
+ bDone = mpExtTextView->KeyInput( rKEvent );
+ }
+ else
+ {
+ bDone = mpExtTextView->KeyInput( rKEvent );
+ }
+
+ if ( !bDone )
+ Window::KeyInput( rKEvent );
+}
+
+void TextWindow::Paint( const Rectangle& rRect )
+{
+ mpExtTextView->Paint( rRect );
+}
+
+void TextWindow::Resize()
+{
+}
+
+void TextWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ PopupMenu* pPopup = Edit::CreatePopupMenu();
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_HIDEDISABLED )
+ pPopup->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES );
+ if ( !mpExtTextView->HasSelection() )
+ {
+ pPopup->EnableItem( SV_MENU_EDIT_CUT, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_COPY, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_DELETE, FALSE );
+ }
+ if ( mpExtTextView->IsReadOnly() )
+ {
+ pPopup->EnableItem( SV_MENU_EDIT_CUT, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_PASTE, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_DELETE, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, FALSE );
+ }
+ if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
+ {
+ pPopup->EnableItem( SV_MENU_EDIT_UNDO, FALSE );
+ }
+// if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
+// {
+// pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, FALSE );
+// }
+ if ( !Edit::GetGetSpecialCharsFunction() )
+ {
+ USHORT nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
+ pPopup->RemoveItem( nPos );
+ pPopup->RemoveItem( nPos-1 );
+ }
+
+ mbActivePopup = TRUE;
+ Point aPos = rCEvt.GetMousePosPixel();
+ if ( !rCEvt.IsMouseEvent() )
+ {
+ // !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!!
+ Size aSize = GetOutputSizePixel();
+ aPos = Point( aSize.Width()/2, aSize.Height()/2 );
+ }
+// pPopup->RemoveDisabledEntries();
+ USHORT n = pPopup->Execute( this, aPos );
+ Edit::DeletePopupMenu( pPopup );
+ switch ( n )
+ {
+ case SV_MENU_EDIT_UNDO: mpExtTextView->Undo();
+ mpExtTextEngine->SetModified( TRUE );
+ mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ break;
+ case SV_MENU_EDIT_CUT: mpExtTextView->Cut();
+ mpExtTextEngine->SetModified( TRUE );
+ mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ break;
+ case SV_MENU_EDIT_COPY: mpExtTextView->Copy();
+ break;
+ case SV_MENU_EDIT_PASTE: mpExtTextView->Paste();
+ mpExtTextEngine->SetModified( TRUE );
+ mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ break;
+ case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected();
+ mpExtTextEngine->SetModified( TRUE );
+ mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ break;
+ case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
+ break;
+ case SV_MENU_EDIT_INSERTSYMBOL:
+ {
+ XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
+ if ( aChars.Len() )
+ {
+ mpExtTextView->InsertText( aChars );
+ mpExtTextEngine->SetModified( TRUE );
+ mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ }
+ }
+ break;
+ }
+ mbActivePopup = FALSE;
+ }
+ else
+ {
+ mpExtTextView->Command( rCEvt );
+ }
+ Window::Command( rCEvt );
+}
+
+void TextWindow::GetFocus()
+{
+ Window::GetFocus();
+ if ( !mbActivePopup )
+ {
+ BOOL bGotoCursor = !mpExtTextView->IsReadOnly();
+ if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly()
+ && ( mbSelectOnTab &&
+ (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) )) )
+ {
+ // Alles selektieren, aber nicht scrollen
+ BOOL bAutoScroll = mpExtTextView->IsAutoScroll();
+ mpExtTextView->SetAutoScroll( FALSE );
+ mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
+ mpExtTextView->SetAutoScroll( bAutoScroll );
+ bGotoCursor = FALSE;
+ }
+ mpExtTextView->SetPaintSelection( TRUE );
+ mpExtTextView->ShowCursor( bGotoCursor );
+ }
+}
+
+void TextWindow::LoseFocus()
+{
+ Window::LoseFocus();
+
+ if ( mbFocusSelectionHide && !mbActivePopup )
+ mpExtTextView->SetPaintSelection( FALSE );
+}
+
+// virtual
+::css::uno::Reference< ::css::awt::XWindowPeer >
+TextWindow::GetComponentInterface(BOOL bCreate)
+{
+ ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
+ Window::GetComponentInterface(false));
+ if (!xPeer.is() && bCreate)
+ {
+ xPeer = new ::svt::TextWindowPeer(*GetTextView(), true);
+ SetComponentInterface(xPeer);
+ }
+ return xPeer;
+}
+
+MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle )
+ : Edit( pParent, nWinStyle )
+{
+ SetType( WINDOW_MULTILINEEDIT );
+ pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ pUpdateDataTimer = 0;
+
+ SetCompoundControl( TRUE );
+ SetStyle( ImplInitStyle( nWinStyle ) );
+}
+
+MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId )
+ : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
+{
+ SetType( WINDOW_MULTILINEEDIT );
+ WinBits nWinStyle = rResId.GetWinBits();
+ pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ pUpdateDataTimer = 0;
+
+ USHORT nMaxLen = Edit::GetMaxTextLen();
+ if ( nMaxLen )
+ SetMaxTextLen( nMaxLen );
+
+ SetText( Edit::GetText() );
+
+ if ( IsVisible() )
+ pImpSvMEdit->Resize();
+
+ SetCompoundControl( TRUE );
+ SetStyle( ImplInitStyle( nWinStyle ) );
+
+ // Base Edit ctor could call Show already, but that would cause problems
+ // with accessibility, as Show might (indirectly) trigger a call to virtual
+ // GetComponentInterface, which is the Edit's base version instead of the
+ // MultiLineEdit's version while in the base Edit ctor:
+ if ((GetStyle() & WB_HIDE) == 0)
+ Show();
+}
+
+MultiLineEdit::~MultiLineEdit()
+{
+ {
+ ::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit );
+ pImpSvMEdit = NULL;
+ }
+ delete pUpdateDataTimer;
+}
+
+WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+
+ if ( !(nStyle & WB_IGNORETAB ))
+ nStyle |= WINDOW_DLGCTRL_MOD1TAB;
+
+ return nStyle;
+}
+
+
+void MultiLineEdit::ImplInitSettings( BOOL /*bFont*/, BOOL /*bForeground*/, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Der Font muss immer mit manipuliert werden, weil die TextEngine
+ // sich nicht um TextColor/Background kuemmert
+
+ Color aTextColor = rStyleSettings.GetFieldTextColor();
+ if ( IsControlForeground() )
+ aTextColor = GetControlForeground();
+ if ( !IsEnabled() )
+ aTextColor = rStyleSettings.GetDisableColor();
+
+ Font aFont = rStyleSettings.GetFieldFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ aFont.SetTransparent( IsPaintTransparent() );
+ SetZoomedPointFont( aFont );
+ Font TheFont = GetFont();
+ TheFont.SetColor( aTextColor );
+ if( IsPaintTransparent() )
+ TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
+ else
+ TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
+ pImpSvMEdit->GetTextWindow()->SetFont( TheFont );
+ pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
+ pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor );
+
+ if ( bBackground )
+ {
+ if( IsPaintTransparent() )
+ {
+ pImpSvMEdit->GetTextWindow()->SetPaintTransparent( TRUE );
+ pImpSvMEdit->GetTextWindow()->SetBackground();
+ pImpSvMEdit->GetTextWindow()->SetControlBackground();
+ SetBackground();
+ SetControlBackground();
+ }
+ else
+ {
+ if( IsControlBackground() )
+ pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
+ else
+ pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
+ // Auch am MultiLineEdit einstellen, weil die TextComponent
+ // ggf. die Scrollbars hidet.
+ SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() );
+ }
+ }
+}
+
+void MultiLineEdit::Modify()
+{
+ aModifyHdlLink.Call( this );
+
+ CallEventListeners( VCLEVENT_EDIT_MODIFY );
+
+ if ( pUpdateDataTimer )
+ pUpdateDataTimer->Start();
+}
+
+IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG )
+{
+ UpdateData();
+ return 0;
+}
+
+void MultiLineEdit::UpdateData()
+{
+ aUpdateDataHdlLink.Call( this );
+}
+
+void MultiLineEdit::SetModifyFlag()
+{
+ pImpSvMEdit->SetModified( TRUE );
+}
+
+void MultiLineEdit::ClearModifyFlag()
+{
+ pImpSvMEdit->SetModified( FALSE );
+}
+
+BOOL MultiLineEdit::IsModified() const
+{
+ return pImpSvMEdit->IsModified();
+}
+
+void MultiLineEdit::EnableUpdateData( ULONG nTimeout )
+{
+ if ( !nTimeout )
+ DisableUpdateData();
+ else
+ {
+ if ( !pUpdateDataTimer )
+ {
+ pUpdateDataTimer = new Timer;
+ pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) );
+ }
+ pUpdateDataTimer->SetTimeout( nTimeout );
+ }
+}
+
+void MultiLineEdit::SetReadOnly( BOOL bReadOnly )
+{
+ pImpSvMEdit->SetReadOnly( bReadOnly );
+ Edit::SetReadOnly( bReadOnly );
+
+ // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
+ WinBits nStyle = GetStyle();
+ if ( bReadOnly )
+ nStyle |= WB_READONLY;
+ else
+ nStyle &= ~WB_READONLY;
+ SetStyle( nStyle );
+}
+
+BOOL MultiLineEdit::IsReadOnly() const
+{
+ return pImpSvMEdit->IsReadOnly();
+}
+
+void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
+{
+ pImpSvMEdit->SetMaxTextLen( nMaxLen );
+}
+
+xub_StrLen MultiLineEdit::GetMaxTextLen() const
+{
+ return pImpSvMEdit->GetMaxTextLen();
+}
+
+void MultiLineEdit::ReplaceSelected( const String& rStr )
+{
+ pImpSvMEdit->InsertText( rStr );
+}
+
+void MultiLineEdit::DeleteSelected()
+{
+ pImpSvMEdit->InsertText( String() );
+}
+
+String MultiLineEdit::GetSelected() const
+{
+ return pImpSvMEdit->GetSelected();
+}
+
+String MultiLineEdit::GetSelected( LineEnd aSeparator ) const
+{
+ return pImpSvMEdit->GetSelected( aSeparator );
+}
+
+void MultiLineEdit::Cut()
+{
+ pImpSvMEdit->Cut();
+}
+
+void MultiLineEdit::Copy()
+{
+ pImpSvMEdit->Copy();
+}
+
+void MultiLineEdit::Paste()
+{
+ pImpSvMEdit->Paste();
+}
+
+void MultiLineEdit::SetText( const String& rStr )
+{
+ pImpSvMEdit->SetText( rStr );
+}
+
+String MultiLineEdit::GetText() const
+{
+ return pImpSvMEdit->GetText();
+}
+
+String MultiLineEdit::GetText( LineEnd aSeparator ) const
+{
+ return pImpSvMEdit->GetText( aSeparator );
+}
+
+String MultiLineEdit::GetTextLines() const
+{
+ return pImpSvMEdit->GetTextLines();
+}
+
+String MultiLineEdit::GetTextLines( LineEnd aSeparator ) const
+{
+ return pImpSvMEdit->GetTextLines( aSeparator );
+}
+
+void MultiLineEdit::Resize()
+{
+ pImpSvMEdit->Resize();
+}
+
+void MultiLineEdit::GetFocus()
+{
+ if ( !pImpSvMEdit ) // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state
+ return;
+
+ Edit::GetFocus();
+ pImpSvMEdit->GetFocus();
+}
+
+void MultiLineEdit::SetSelection( const Selection& rSelection )
+{
+ pImpSvMEdit->SetSelection( rSelection );
+}
+
+const Selection& MultiLineEdit::GetSelection() const
+{
+ return pImpSvMEdit->GetSelection();
+}
+
+Size MultiLineEdit::CalcMinimumSize() const
+{
+ Size aSz = pImpSvMEdit->CalcMinimumSize();
+
+ sal_Int32 nLeft, nTop, nRight, nBottom;
+ ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
+ aSz.Width() += nLeft+nRight;
+ aSz.Height() += nTop+nBottom;
+
+ return aSz;
+}
+
+Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
+{
+ Size aSz = rPrefSize;
+ sal_Int32 nLeft, nTop, nRight, nBottom;
+ ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
+
+ // In der Hoehe auf ganze Zeilen justieren
+
+ long nHeight = aSz.Height() - nTop - nBottom;
+ long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height();
+ long nLines = nHeight / nLineHeight;
+ if ( nLines < 1 )
+ nLines = 1;
+
+ aSz.Height() = nLines * nLineHeight;
+ aSz.Height() += nTop+nBottom;
+
+ return aSz;
+}
+
+Size MultiLineEdit::CalcSize( USHORT nColumns, USHORT nLines ) const
+{
+ Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines );
+
+ sal_Int32 nLeft, nTop, nRight, nBottom;
+ ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
+ aSz.Width() += nLeft+nRight;
+ aSz.Height() += nTop+nBottom;
+ return aSz;
+}
+
+void MultiLineEdit::GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const
+{
+ pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
+}
+
+void MultiLineEdit::StateChanged( StateChangedType nType )
+{
+ if( nType == STATE_CHANGE_ENABLE )
+ {
+ pImpSvMEdit->Enable( IsEnabled() );
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ }
+ else if( nType == STATE_CHANGE_READONLY )
+ {
+ pImpSvMEdit->SetReadOnly( IsReadOnly() );
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() );
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Resize();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Resize();
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ pImpSvMEdit->InitFromStyle( GetStyle() );
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ }
+ else if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if( IsPaintTransparent() )
+ {
+ pImpSvMEdit->GetTextWindow()->SetPaintTransparent( TRUE );
+ pImpSvMEdit->GetTextWindow()->SetBackground();
+ pImpSvMEdit->GetTextWindow()->SetControlBackground();
+ SetBackground();
+ SetControlBackground();
+ }
+ }
+
+ Control::StateChanged( nType );
+}
+
+void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Resize();
+ Invalidate();
+ }
+ else
+ Control::DataChanged( rDCEvt );
+}
+
+void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ ImplInitSettings( TRUE, TRUE, TRUE );
+
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
+ aFont.SetTransparent( TRUE );
+ OutDevType eOutDevType = pDev->GetOutDevType();
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ pDev->SetTextFillColor();
+
+ // Border/Background
+ pDev->SetLineColor();
+ pDev->SetFillColor();
+ BOOL bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
+ BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
+ if ( bBorder || bBackground )
+ {
+ Rectangle aRect( aPos, aSize );
+ if ( bBorder )
+ {
+ DecorationView aDecoView( pDev );
+ aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ if ( bBackground )
+ {
+ pDev->SetFillColor( GetControlBackground() );
+ pDev->DrawRect( aRect );
+ }
+ }
+
+ // Inhalt
+ if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ {
+ if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ pDev->SetTextColor( rStyleSettings.GetDisableColor() );
+ }
+ else
+ {
+ pDev->SetTextColor( GetTextColor() );
+ }
+ }
+
+ XubString aText = GetText();
+ Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
+ ULONG nLines = (ULONG) (aSize.Height() / aTextSz.Height());
+ if ( !nLines )
+ nLines = 1;
+ aTextSz.Height() = nLines*aTextSz.Height();
+ long nOnePixel = GetDrawPixel( pDev, 1 );
+ long nOffX = 3*nOnePixel;
+ long nOffY = 2*nOnePixel;
+
+ // Clipping?
+ if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
+ {
+ Rectangle aClip( aPos, aSize );
+ if ( aTextSz.Height() > aSize.Height() )
+ aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // Damit HP-Drucker nicht 'weg-optimieren'
+ pDev->IntersectClipRegion( aClip );
+ }
+
+ TextEngine aTE;
+ aTE.SetText( GetText() );
+ aTE.SetMaxTextWidth( aSize.Width() );
+ aTE.SetFont( aFont );
+ aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
+ aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
+
+ pDev->Pop();
+}
+
+long MultiLineEdit::Notify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
+ }
+ return nDone ? nDone : Edit::Notify( rNEvt );
+}
+
+long MultiLineEdit::PreNotify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+
+#if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
+ if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
+ {
+ SetRightToLeft( !IsRightToLeft() );
+ }
+ }
+#endif
+
+ if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
+ {
+ const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
+ if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
+ {
+ nDone = 1;
+ TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection();
+ if ( aSel.HasRange() )
+ {
+ aSel.GetStart() = aSel.GetEnd();
+ pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
+ }
+ else
+ {
+ switch ( rKEvent.GetKeyCode().GetCode() )
+ {
+ case KEY_UP:
+ {
+ if ( pImpSvMEdit->GetVScrollBar() )
+ pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
+ }
+ break;
+ case KEY_DOWN:
+ {
+ if ( pImpSvMEdit->GetVScrollBar() )
+ pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
+ }
+ break;
+ case KEY_PAGEUP :
+ {
+ if ( pImpSvMEdit->GetVScrollBar() )
+ pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
+ }
+ break;
+ case KEY_PAGEDOWN:
+ {
+ if ( pImpSvMEdit->GetVScrollBar() )
+ pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
+ }
+ break;
+ case KEY_LEFT:
+ {
+ if ( pImpSvMEdit->GetHScrollBar() )
+ pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
+ }
+ break;
+ case KEY_RIGHT:
+ {
+ if ( pImpSvMEdit->GetHScrollBar() )
+ pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
+ }
+ break;
+ case KEY_HOME:
+ {
+ if ( rKEvent.GetKeyCode().IsMod1() )
+ pImpSvMEdit->GetTextWindow()->GetTextView()->
+ SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
+ }
+ break;
+ case KEY_END:
+ {
+ if ( rKEvent.GetKeyCode().IsMod1() )
+ pImpSvMEdit->GetTextWindow()->GetTextView()->
+ SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
+ }
+ break;
+ default:
+ {
+ nDone = 0;
+ }
+ }
+ }
+ }
+ }
+
+ return nDone ? nDone : Edit::PreNotify( rNEvt );
+}
+
+//
+// Internas fuer abgeleitete Klassen, z.B. TextComponent
+
+ExtTextEngine* MultiLineEdit::GetTextEngine() const
+{
+ return pImpSvMEdit->GetTextWindow()->GetTextEngine();
+}
+
+ExtTextView* MultiLineEdit::GetTextView() const
+{
+ return pImpSvMEdit->GetTextWindow()->GetTextView();
+}
+
+ScrollBar* MultiLineEdit::GetHScrollBar() const
+{
+ return pImpSvMEdit->GetHScrollBar();
+}
+
+
+ScrollBar* MultiLineEdit::GetVScrollBar() const
+{
+ return pImpSvMEdit->GetVScrollBar();
+}
+
+void MultiLineEdit::EnableFocusSelectionHide( BOOL bHide )
+{
+ pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
+}
+
+BOOL MultiLineEdit::IsFocusSelectionHideEnabled() const
+{
+ return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide();
+}
+
+
+void MultiLineEdit::SetLeftMargin( USHORT n )
+{
+ if ( GetTextEngine() )
+ GetTextEngine()->SetLeftMargin( n );
+}
+
+USHORT MultiLineEdit::GetLeftMargin() const
+{
+ if ( GetTextEngine() )
+ return GetTextEngine()->GetLeftMargin();
+ else
+ return 0;
+}
+
+void MultiLineEdit::SetRightToLeft( BOOL bRightToLeft )
+{
+ if ( GetTextEngine() )
+ {
+ GetTextEngine()->SetRightToLeft( bRightToLeft );
+ GetTextView()->ShowCursor();
+ }
+}
+
+BOOL MultiLineEdit::IsRightToLeft() const
+{
+ BOOL bRightToLeft = FALSE;
+
+ if ( GetTextEngine() )
+ bRightToLeft = GetTextEngine()->IsRightToLeft();
+
+ return bRightToLeft;
+}
+
+// virtual
+::css::uno::Reference< ::css::awt::XWindowPeer >
+MultiLineEdit::GetComponentInterface(BOOL bCreate)
+{
+ ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
+ Edit::GetComponentInterface(false));
+ if (!xPeer.is() && bCreate)
+ {
+ ::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit());
+ xEdit->SetWindow(this);
+ xPeer = xEdit.release();
+ SetComponentInterface(xPeer);
+ }
+ return xPeer;
+}
+/*-- 11.08.2004 11:29:23---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void MultiLineEdit::DisableSelectionOnFocus()
+{
+ pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus();
+}
diff --git a/svtools/source/edit/svmedit2.cxx b/svtools/source/edit/svmedit2.cxx
new file mode 100644
index 000000000000..19eba618a828
--- /dev/null
+++ b/svtools/source/edit/svmedit2.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_svtools.hxx"
+
+#include <svtools/svmedit2.hxx>
+#include <svtools/xtextedt.hxx>
+
+ExtMultiLineEdit::ExtMultiLineEdit( Window* pParent, WinBits nWinStyle ) :
+
+ MultiLineEdit( pParent, nWinStyle )
+
+{
+}
+
+ExtMultiLineEdit::ExtMultiLineEdit( Window* pParent, const ResId& rResId ) :
+
+ MultiLineEdit( pParent, rResId )
+
+{
+}
+
+ExtMultiLineEdit::~ExtMultiLineEdit()
+{
+}
+
+void ExtMultiLineEdit::InsertText( const String& rNew, BOOL )
+{
+ GetTextView()->InsertText( rNew, FALSE );
+}
+
+void ExtMultiLineEdit::SetAutoScroll( BOOL bAutoScroll )
+{
+ GetTextView()->SetAutoScroll( bAutoScroll );
+}
+
+void ExtMultiLineEdit::EnableCursor( BOOL bEnable )
+{
+ GetTextView()->EnableCursor( bEnable );
+}
+
+void ExtMultiLineEdit::SetAttrib( const TextAttrib& rAttr, ULONG nPara, USHORT nStart, USHORT nEnd )
+{
+ GetTextEngine()->SetAttrib( rAttr, nPara, nStart, nEnd );
+}
+
+void ExtMultiLineEdit::SetLeftMargin( USHORT nLeftMargin )
+{
+ GetTextEngine()->SetLeftMargin( nLeftMargin );
+}
+
+ULONG ExtMultiLineEdit::GetParagraphCount() const
+{
+ return GetTextEngine()->GetParagraphCount();
+}
+
diff --git a/svtools/source/edit/sychconv.cxx b/svtools/source/edit/sychconv.cxx
new file mode 100644
index 000000000000..3efa510bfc5a
--- /dev/null
+++ b/svtools/source/edit/sychconv.cxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "sychconv.hxx"
+#include <vcl/outdev.hxx>
+
+BOOL SymCharConverter::Convert( Font& rFont, UniString& rString, OutputDevice* pDev )
+{
+ // hibyte 0 = exact matching
+ // 1 = little differences,
+ // 2 = the converted character does not look like the original but got the same meaning
+ // 3 = the destination does not match looking and meaning of the original
+
+ static USHORT __READONLY_DATA aWingdingsToStarBatsTable[ 256 - 32 ] =
+ {
+ 0x0020, 0x0238, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0174, 0x02BA, 0x017B, 0x017C, 0x037C, 0x037C, 0x037C, 0x037C,
+ 0x0000, 0x0000, 0x0372, 0x0272, 0x0372, 0x0000, 0x0000, 0x0374, 0x0279, 0x0000, 0x027A, 0x0000, 0x0178, 0x0278, 0x0000, 0x0137,
+ 0x027E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017D, 0x0000, 0x0000, 0x0000, 0x0021, 0x03AC, 0x00AD, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x01C0, 0x0000, 0x0000, 0x0286, 0x0286, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0022, 0x0023, 0x0024, 0x0025,
+ 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x0133, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0194, 0x0000,
+ 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060,
+ 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01A5, 0x0095,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x002E, 0x0024, 0x0125, 0x0000, 0x0000, 0x0000, 0x014B, 0x024D, 0x014E, 0x014A,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x002F, 0x0000, 0x0000, 0x0000, 0x0035, 0x0000, 0x0000, 0x0000,
+ 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0031, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01B1,
+ 0x01AF, 0x01B2, 0x01B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0150, 0x0032, 0x0033, 0x0034, 0x01C8
+ };
+
+ static USHORT __READONLY_DATA aMonotypeSortsToStarBatsTable[ 256 - 32 ]=
+ {
+ 0x0020, 0x00cb, 0x00cb, 0x00cb, 0x00cb, 0x0074, 0x00ba, 0x0021, 0x00cc, 0x007b, 0x0036, 0x007d, 0x007e, 0x0037, 0x0038, 0x0038,
+ 0x0039, 0x0038, 0x0038, 0x0039, 0x003a, 0x004f, 0x0050, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0086, 0x0086, 0x0086,
+ 0x0052, 0x00cd, 0x0044, 0x0045, 0x0046, 0x0047, 0x0041, 0x0041, 0x0058, 0x0057, 0x0075, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x004b, 0x004b, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004e, 0x004b, 0x004b, 0x00ce, 0x00ce, 0x00ce,
+ 0x00ce, 0x00ce, 0x00ce, 0x00ce, 0x00cf, 0x00cf, 0x00cf, 0x00cf, 0x00cf, 0x00cf, 0x00b9, 0x00b9, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x003e, 0x0040, 0x00c5, 0x00c4, 0x002b, 0x002c, 0x00d0, 0x00d1, 0x00d1, 0x00d1, 0x0091, 0x0092, 0x0093, 0x0094, 0x0000,
+ 0x00d2, 0x00d3, 0x00d2, 0x00d3, 0x00d2, 0x00d3, 0x00d2, 0x00d3, 0x00d2, 0x00d3, 0x00d2, 0x00d3, 0x00d2, 0x00d3, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x00d4, 0x00d4, 0x00d4, 0x00d6, 0x00d6, 0x00d4, 0x00d4, 0x00d5, 0x002a, 0x00d6, 0x00d7, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066,
+ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0030, 0x0031, 0x00d8, 0x00d9, 0x00da, 0x00bc, 0x00db, 0x00bc, 0x00bc, 0x00bc, 0x00bc, 0x0031,
+ 0x0031, 0x0031, 0x002f, 0x002f, 0x002f, 0x00be, 0x00be, 0x0031, 0x0031, 0x00af, 0x00af, 0x00af, 0x00af, 0x00af, 0x00af, 0x00af,
+ 0x0000, 0x00af, 0x0035, 0x00dc, 0x00da, 0x00dc, 0x00db, 0x00da, 0x00dc, 0x00db, 0x00dc, 0x00dc, 0x00dc, 0x00dc, 0x00af, 0x0000
+ };
+
+ const USHORT* pTransTable = NULL;
+
+ BOOL bIsAvailable = ( pDev ) ? pDev->IsFontAvailable( rFont.GetName() ) : FALSE;
+ if ( !bIsAvailable )
+ {
+ if ( rFont.GetName().CompareToAscii( RTL_CONSTASCII_STRINGPARAM( "Wingdings" ) ) == COMPARE_EQUAL )
+ pTransTable = &aWingdingsToStarBatsTable[ 0 ];
+ else if ( rFont.GetName().CompareToAscii( RTL_CONSTASCII_STRINGPARAM( "Monotype Sorts" ) ) == COMPARE_EQUAL )
+ pTransTable = &aMonotypeSortsToStarBatsTable[ 0 ];
+ }
+ if ( pTransTable )
+ {
+ sal_Unicode c;
+ for ( UINT16 i = rString.Len(); i--; )
+ {
+ c = rString.GetChar( i );
+ c -= 32;
+ c = ( ((UINT16)c) >= 224 ) ? 0 : (sal_Unicode) pTransTable[ c ];
+ if ( !c ) // if character is out of range or not matching
+ c = 0xA5; // we will default a StarBats-Bullet
+ rString.SetChar( i, c );
+ }
+ rFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ rFont.SetName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "StarBats" ) ) );
+ return TRUE;
+ }
+ else return FALSE;
+};
diff --git a/svtools/source/edit/syntaxhighlight.cxx b/svtools/source/edit/syntaxhighlight.cxx
new file mode 100644
index 000000000000..5729eb712bfe
--- /dev/null
+++ b/svtools/source/edit/syntaxhighlight.cxx
@@ -0,0 +1,909 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/syntaxhighlight.hxx>
+
+#include <unotools/charclass.hxx>
+#include <tools/debug.hxx>
+
+
+SV_IMPL_VARARR(HighlightPortions, HighlightPortion)
+
+
+// ##########################################################################
+// ATTENTION: all these words needs to be in small caps
+// ##########################################################################
+static const char* strListBasicKeyWords[] = {
+ "access",
+ "alias",
+ "and",
+ "any",
+ "append",
+ "as",
+ "base",
+ "binary",
+ "boolean",
+ "byref",
+ "byte",
+ "byval",
+ "call",
+ "case",
+ "cdecl",
+ "classmodule",
+ "close",
+ "compare",
+ "compatible",
+ "const",
+ "currency",
+ "date",
+ "declare",
+ "defbool",
+ "defcur",
+ "defdate",
+ "defdbl",
+ "deferr",
+ "defint",
+ "deflng",
+ "defobj",
+ "defsng",
+ "defstr",
+ "defvar",
+ "dim",
+ "do",
+ "double",
+ "each",
+ "else",
+ "elseif",
+ "end",
+ "end enum",
+ "end function",
+ "end if",
+ "end select",
+ "end sub",
+ "end type",
+ "endif",
+ "enum",
+ "eqv",
+ "erase",
+ "error",
+ "exit",
+ "explicit",
+ "for",
+ "function",
+ "get",
+ "global",
+ "gosub",
+ "goto",
+ "if",
+ "imp",
+ "implements",
+ "in",
+ "input",
+ "integer",
+ "is",
+ "let",
+ "lib",
+ "like",
+ "line",
+ "line input",
+ "local",
+ "lock",
+ "long",
+ "loop",
+ "lprint",
+ "lset",
+ "mod",
+ "name",
+ "new",
+ "next",
+ "not",
+ "object",
+ "on",
+ "open",
+ "option",
+ "optional",
+ "or",
+ "output",
+ "preserve",
+ "print",
+ "private",
+ "property",
+ "public",
+ "random",
+ "read",
+ "redim",
+ "rem",
+ "resume",
+ "return",
+ "rset",
+ "select",
+ "set",
+ "shared",
+ "single",
+ "static",
+ "step",
+ "stop",
+ "string",
+ "sub",
+ "system",
+ "text",
+ "then",
+ "to",
+ "type",
+ "typeof",
+ "until",
+ "variant",
+ "wend",
+ "while",
+ "with",
+ "write",
+ "xor"
+};
+
+
+static const char* strListSqlKeyWords[] = {
+ "all",
+ "and",
+ "any",
+ "as",
+ "asc",
+ "avg",
+ "between",
+ "by",
+ "cast",
+ "corresponding",
+ "count",
+ "create",
+ "cross",
+ "delete",
+ "desc",
+ "distinct",
+ "drop",
+ "escape",
+ "except",
+ "exists",
+ "false",
+ "from",
+ "full",
+ "global",
+ "group",
+ "having",
+ "in",
+ "inner",
+ "insert",
+ "intersect",
+ "into",
+ "is",
+ "join",
+ "left",
+ "like",
+ "local",
+ "match",
+ "max",
+ "min",
+ "natural",
+ "not",
+ "null",
+ "on",
+ "or",
+ "order",
+ "outer",
+ "right",
+ "select",
+ "set",
+ "some",
+ "sum",
+ "table",
+ "temporary",
+ "true",
+ "union",
+ "unique",
+ "unknown",
+ "update",
+ "using",
+ "values",
+ "where"
+};
+
+
+extern "C" int CDECL compare_strings( const void *arg1, const void *arg2 )
+{
+ return strcmp( (char *)arg1, *(char **)arg2 );
+}
+
+
+class LetterTable
+{
+ bool IsLetterTab[256];
+
+public:
+ LetterTable( void );
+
+ inline bool isLetter( sal_Unicode c )
+ {
+ bool bRet = (c < 256) ? IsLetterTab[c] : isLetterUnicode( c );
+ return bRet;
+ }
+ bool isLetterUnicode( sal_Unicode c );
+};
+
+class BasicSimpleCharClass
+{
+ static LetterTable aLetterTable;
+
+public:
+ static BOOL isAlpha( sal_Unicode c, bool bCompatible )
+ {
+ BOOL bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+ || (bCompatible && aLetterTable.isLetter( c ));
+ return bRet;
+ }
+
+ static BOOL isDigit( sal_Unicode c )
+ {
+ BOOL bRet = (c >= '0' && c <= '9');
+ return bRet;
+ }
+
+ static BOOL isAlphaNumeric( sal_Unicode c, bool bCompatible )
+ {
+ BOOL bRet = isDigit( c ) || isAlpha( c, bCompatible );
+ return bRet;
+ }
+};
+
+LetterTable BasicSimpleCharClass::aLetterTable;
+
+LetterTable::LetterTable( void )
+{
+ for( int i = 0 ; i < 256 ; ++i )
+ IsLetterTab[i] = false;
+
+ IsLetterTab[0xC0] = true; // À , CAPITAL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xC1] = true; // Á , CAPITAL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xC2] = true; // Â , CAPITAL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xC3] = true; // Ã , CAPITAL LETTER A WITH TILDE
+ IsLetterTab[0xC4] = true; // Ä , CAPITAL LETTER A WITH DIAERESIS
+ IsLetterTab[0xC5] = true; // Å , CAPITAL LETTER A WITH RING ABOVE
+ IsLetterTab[0xC6] = true; // Æ , CAPITAL LIGATURE AE
+ IsLetterTab[0xC7] = true; // Ç , CAPITAL LETTER C WITH CEDILLA
+ IsLetterTab[0xC8] = true; // È , CAPITAL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xC9] = true; // É , CAPITAL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xCA] = true; // Ê , CAPITAL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCB] = true; // Ë , CAPITAL LETTER E WITH DIAERESIS
+ IsLetterTab[0xCC] = true; // Ì , CAPITAL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xCD] = true; // Í , CAPITAL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xCE] = true; // Î , CAPITAL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCF] = true; // Ï , CAPITAL LETTER I WITH DIAERESIS
+ IsLetterTab[0xD0] = true; // Ð , CAPITAL LETTER ETH
+ IsLetterTab[0xD1] = true; // Ñ , CAPITAL LETTER N WITH TILDE
+ IsLetterTab[0xD2] = true; // Ò , CAPITAL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xD3] = true; // Ó , CAPITAL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xD4] = true; // Ô , CAPITAL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xD5] = true; // Õ , CAPITAL LETTER O WITH TILDE
+ IsLetterTab[0xD6] = true; // Ö , CAPITAL LETTER O WITH DIAERESIS
+ IsLetterTab[0xD8] = true; // Ø , CAPITAL LETTER O WITH STROKE
+ IsLetterTab[0xD9] = true; // Ù , CAPITAL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xDA] = true; // Ú , CAPITAL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xDB] = true; // Û , CAPITAL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xDC] = true; // Ü , CAPITAL LETTER U WITH DIAERESIS
+ IsLetterTab[0xDD] = true; // Ý , CAPITAL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xDE] = true; // Þ , CAPITAL LETTER THORN
+ IsLetterTab[0xDF] = true; // ß , SMALL LETTER SHARP S
+ IsLetterTab[0xE0] = true; // à , SMALL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xE1] = true; // á , SMALL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xE2] = true; // â , SMALL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xE3] = true; // ã , SMALL LETTER A WITH TILDE
+ IsLetterTab[0xE4] = true; // ä , SMALL LETTER A WITH DIAERESIS
+ IsLetterTab[0xE5] = true; // å , SMALL LETTER A WITH RING ABOVE
+ IsLetterTab[0xE6] = true; // æ , SMALL LIGATURE AE
+ IsLetterTab[0xE7] = true; // ç , SMALL LETTER C WITH CEDILLA
+ IsLetterTab[0xE8] = true; // è , SMALL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xE9] = true; // é , SMALL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xEA] = true; // ê , SMALL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEB] = true; // ë , SMALL LETTER E WITH DIAERESIS
+ IsLetterTab[0xEC] = true; // ì , SMALL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xED] = true; // í , SMALL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xEE] = true; // î , SMALL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEF] = true; // ï , SMALL LETTER I WITH DIAERESIS
+ IsLetterTab[0xF0] = true; // ð , SMALL LETTER ETH
+ IsLetterTab[0xF1] = true; // ñ , SMALL LETTER N WITH TILDE
+ IsLetterTab[0xF2] = true; // ò , SMALL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xF3] = true; // ó , SMALL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xF4] = true; // ô , SMALL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xF5] = true; // õ , SMALL LETTER O WITH TILDE
+ IsLetterTab[0xF6] = true; // ö , SMALL LETTER O WITH DIAERESIS
+ IsLetterTab[0xF8] = true; // ø , SMALL LETTER O WITH OBLIQUE BAR
+ IsLetterTab[0xF9] = true; // ù , SMALL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xFA] = true; // ú , SMALL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xFB] = true; // û , SMALL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xFC] = true; // ü , SMALL LETTER U WITH DIAERESIS
+ IsLetterTab[0xFD] = true; // ý , SMALL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xFE] = true; // þ , SMALL LETTER THORN
+ IsLetterTab[0xFF] = true; // ÿ , SMALL LETTER Y WITH DIAERESIS
+}
+
+bool LetterTable::isLetterUnicode( sal_Unicode c )
+{
+ static CharClass* pCharClass = NULL;
+ if( pCharClass == NULL )
+ pCharClass = new CharClass( Application::GetSettings().GetLocale() );
+ String aStr( c );
+ bool bRet = pCharClass->isLetter( aStr, 0 );
+ return bRet;
+}
+
+// Hilfsfunktion: Zeichen-Flag Testen
+BOOL SimpleTokenizer_Impl::testCharFlags( sal_Unicode c, USHORT nTestFlags )
+{
+ bool bRet = false;
+ if( c != 0 && c <= 255 )
+ {
+ bRet = ( (aCharTypeTab[c] & nTestFlags) != 0 );
+ }
+ else if( c > 255 )
+ {
+ bRet = (( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER ) & nTestFlags) != 0
+ ? BasicSimpleCharClass::isAlpha( c, true ) : false;
+ }
+ return bRet;
+}
+
+void SimpleTokenizer_Impl::setKeyWords( const char** ppKeyWords, UINT16 nCount )
+{
+ ppListKeyWords = ppKeyWords;
+ nKeyWordCount = nCount;
+}
+
+// Neues Token holen
+BOOL SimpleTokenizer_Impl::getNextToken( /*out*/TokenTypes& reType,
+ /*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos )
+{
+ reType = TT_UNKNOWN;
+
+ // Position merken
+ rpStartPos = mpActualPos;
+
+ // Zeichen untersuchen
+ sal_Unicode c = peekChar();
+ if( c == CHAR_EOF )
+ return FALSE;
+
+ // Zeichen lesen
+ getChar();
+
+ //*** Alle Moeglichkeiten durchgehen ***
+ // Space?
+ if ( (testCharFlags( c, CHAR_SPACE ) == TRUE) )
+ {
+ while( testCharFlags( peekChar(), CHAR_SPACE ) == TRUE )
+ getChar();
+
+ reType = TT_WHITESPACE;
+ }
+
+ // Identifier?
+ else if ( (testCharFlags( c, CHAR_START_IDENTIFIER ) == TRUE) )
+ {
+ BOOL bIdentifierChar;
+ do
+ {
+ // Naechstes Zeichen holen
+ c = peekChar();
+ bIdentifierChar = testCharFlags( c, CHAR_IN_IDENTIFIER );
+ if( bIdentifierChar )
+ getChar();
+ }
+ while( bIdentifierChar );
+
+ reType = TT_IDENTIFIER;
+
+ // Schluesselwort-Tabelle
+ if (ppListKeyWords != NULL)
+ {
+ int nCount = mpActualPos - rpStartPos;
+
+ // No keyword if string contains char > 255
+ bool bCanBeKeyword = true;
+ for( int i = 0 ; i < nCount ; i++ )
+ {
+ if( rpStartPos[i] > 255 )
+ {
+ bCanBeKeyword = false;
+ break;
+ }
+ }
+
+ if( bCanBeKeyword )
+ {
+ String aKWString(rpStartPos, sal::static_int_cast< xub_StrLen >(nCount) );
+ ByteString aByteStr( aKWString, RTL_TEXTENCODING_ASCII_US );
+ aByteStr.ToLowerAscii();
+ if ( bsearch( aByteStr.GetBuffer(), ppListKeyWords, nKeyWordCount, sizeof( char* ),
+ compare_strings ) )
+ {
+ reType = TT_KEYWORDS;
+
+ if ( aByteStr.Equals( "rem" ) )
+ {
+ // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
+ sal_Unicode cPeek = peekChar();
+ while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == FALSE )
+ {
+ c = getChar();
+ cPeek = peekChar();
+ }
+
+ reType = TT_COMMENT;
+ }
+ }
+ }
+ }
+ }
+
+ // Operator?
+ // only for BASIC '\'' should be a comment, otherwise it is a normal string and handled there
+ else if ( ( testCharFlags( c, CHAR_OPERATOR ) == TRUE ) || ( (c == '\'') && (aLanguage==HIGHLIGHT_BASIC)) )
+ {
+ // paramters for SQL view
+ if ( (c==':') || (c=='?'))
+ {
+ if (c!='?')
+ {
+ BOOL bIdentifierChar;
+ do
+ {
+ // Naechstes Zeichen holen
+ c = peekChar();
+ bIdentifierChar = BasicSimpleCharClass::isAlpha( c, true );
+ if( bIdentifierChar )
+ getChar();
+ }
+ while( bIdentifierChar );
+ }
+ reType = TT_PARAMETER;
+ }
+ else if ((c=='-'))
+ {
+ sal_Unicode cPeekNext = peekChar();
+ if (cPeekNext=='-')
+ {
+ // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
+ while( cPeekNext != CHAR_EOF && testCharFlags( cPeekNext, CHAR_EOL ) == FALSE )
+ {
+ getChar();
+ cPeekNext = peekChar();
+ }
+ reType = TT_COMMENT;
+ }
+ }
+ else if (c=='/')
+ {
+ sal_Unicode cPeekNext = peekChar();
+ if (cPeekNext=='/')
+ {
+ // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
+ while( cPeekNext != CHAR_EOF && testCharFlags( cPeekNext, CHAR_EOL ) == FALSE )
+ {
+ getChar();
+ cPeekNext = peekChar();
+ }
+ reType = TT_COMMENT;
+ }
+ }
+ else
+ {
+ // Kommentar ?
+ if ( c == '\'' )
+ {
+ c = getChar(); // '/' entfernen
+
+ // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
+ sal_Unicode cPeek = peekChar();
+ while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == FALSE )
+ {
+ getChar();
+ cPeek = peekChar();
+ }
+
+ reType = TT_COMMENT;
+ }
+
+ // Echter Operator, kann hier einfach behandelt werden,
+ // da nicht der wirkliche Operator, wie z.B. += interessiert,
+ // sondern nur die Tatsache, dass es sich um einen handelt.
+ if( reType != TT_COMMENT )
+ {
+ reType = TT_OPERATOR;
+ }
+
+ }
+ }
+
+ // Objekt-Trenner? Muss vor Number abgehandelt werden
+ else if( c == '.' && ( peekChar() < '0' || peekChar() > '9' ) )
+ {
+ reType = TT_OPERATOR;
+ }
+
+ // Zahl?
+ else if( testCharFlags( c, CHAR_START_NUMBER ) == TRUE )
+ {
+ reType = TT_NUMBER;
+
+ // Zahlensystem, 10 = normal, wird bei Oct/Hex geaendert
+ int nRadix = 10;
+
+ // Ist es eine Hex- oder Oct-Zahl?
+ if( c == '&' )
+ {
+ // Octal?
+ if( peekChar() == 'o' || peekChar() == 'O' )
+ {
+ // o entfernen
+ getChar();
+ nRadix = 8; // Octal-Basis
+
+ // Alle Ziffern einlesen
+ while( testCharFlags( peekChar(), CHAR_IN_OCT_NUMBER ) )
+ c = getChar();
+ }
+ // Hex?
+ else if( peekChar() == 'h' || peekChar() == 'H' )
+ {
+ // x entfernen
+ getChar();
+ nRadix = 16; // Hex-Basis
+
+ // Alle Ziffern einlesen und puffern
+ while( testCharFlags( peekChar(), CHAR_IN_HEX_NUMBER ) )
+ c = getChar();
+ }
+ else
+ {
+ reType = TT_OPERATOR;
+ }
+ }
+
+ // Wenn nicht Oct oder Hex als double ansehen
+ if( reType == TT_NUMBER && nRadix == 10 )
+ {
+ // Flag, ob das letzte Zeichen ein Exponent war
+ BOOL bAfterExpChar = FALSE;
+
+ // Alle Ziffern einlesen
+ while( testCharFlags( peekChar(), CHAR_IN_NUMBER ) ||
+ (bAfterExpChar && peekChar() == '+' ) ||
+ (bAfterExpChar && peekChar() == '-' ) )
+ // Nach Exponent auch +/- OK
+ {
+ c = getChar(); // Zeichen lesen
+ bAfterExpChar = ( c == 'e' || c == 'E' );
+ }
+ }
+
+ // reType = TT_NUMBER;
+ }
+
+ // String?
+ else if( testCharFlags( c, CHAR_START_STRING ) == TRUE )
+ {
+ // Merken, welches Zeichen den String eroeffnet hat
+ sal_Unicode cEndString = c;
+ if( c == '[' )
+ cEndString = ']';
+
+ // Alle Ziffern einlesen und puffern
+ while( peekChar() != cEndString )
+ {
+ // #58846 EOF vor getChar() abfangen, damit EOF micht verloren geht
+ if( peekChar() == CHAR_EOF )
+ {
+ // ERROR: unterminated string literal
+ reType = TT_ERROR;
+ break;
+ }
+ c = getChar();
+ if( testCharFlags( c, CHAR_EOL ) == TRUE )
+ {
+ // ERROR: unterminated string literal
+ reType = TT_ERROR;
+ break;
+ }
+ }
+
+ // Zeichen lesen
+ if( reType != TT_ERROR )
+ {
+ getChar();
+ if( cEndString == ']' )
+ reType = TT_IDENTIFIER;
+ else
+ reType = TT_STRING;
+ }
+ }
+
+ // Zeilenende?
+ else if( testCharFlags( c, CHAR_EOL ) == TRUE )
+ {
+ // Falls ein weiteres anderes EOL-Char folgt, weg damit
+ sal_Unicode cNext = peekChar();
+ if( cNext != c && testCharFlags( cNext, CHAR_EOL ) == TRUE )
+ getChar();
+
+ // Positions-Daten auf Zeilen-Beginn setzen
+ nCol = 0;
+ nLine++;
+
+ reType = TT_EOL;
+ }
+
+ // Alles andere bleibt TT_UNKNOWN
+
+
+ // End-Position eintragen
+ rpEndPos = mpActualPos;
+ return TRUE;
+}
+
+String SimpleTokenizer_Impl::getTokStr
+ ( /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
+{
+ return String( pStartPos, (USHORT)( pEndPos - pStartPos ) );
+}
+
+#ifdef DBG_UTIL
+// TEST: Token ausgeben
+String SimpleTokenizer_Impl::getFullTokenStr( /*out*/TokenTypes eType,
+ /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
+{
+ String aOut;
+ switch( eType )
+ {
+ case TT_UNKNOWN: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_UNKNOWN:") ); break;
+ case TT_IDENTIFIER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_IDENTIFIER:") ); break;
+ case TT_WHITESPACE: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_WHITESPACE:") ); break;
+ case TT_NUMBER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_NUMBER:") ); break;
+ case TT_STRING: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_STRING:") ); break;
+ case TT_EOL: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_EOL:") ); break;
+ case TT_COMMENT: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_COMMENT:") ); break;
+ case TT_ERROR: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_ERROR:") ); break;
+ case TT_OPERATOR: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_OPERATOR:") ); break;
+ case TT_KEYWORDS: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_KEYWORD:") ); break;
+ case TT_PARAMETER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_PARAMETER:") ); break;
+ }
+ if( eType != TT_EOL )
+ {
+ aOut += String( pStartPos, (USHORT)( pEndPos - pStartPos ) );
+ }
+ aOut += String( RTL_CONSTASCII_USTRINGPARAM("\n") );
+ return aOut;
+}
+#endif
+
+SimpleTokenizer_Impl::SimpleTokenizer_Impl( HighlighterLanguage aLang ): aLanguage(aLang)
+{
+ memset( aCharTypeTab, 0, sizeof( aCharTypeTab ) );
+
+ // Zeichen-Tabelle fuellen
+ USHORT i;
+
+ // Zulaessige Zeichen fuer Identifier
+ USHORT nHelpMask = (USHORT)( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER );
+ for( i = 'a' ; i <= 'z' ; i++ )
+ aCharTypeTab[i] |= nHelpMask;
+ for( i = 'A' ; i <= 'Z' ; i++ )
+ aCharTypeTab[i] |= nHelpMask;
+ // '_' extra eintragen
+ aCharTypeTab[(int)'_'] |= nHelpMask;
+ // AB 23.6.97: '$' ist auch erlaubt
+ aCharTypeTab[(int)'$'] |= nHelpMask;
+
+ // Ziffern (Identifier und Number ist moeglich)
+ nHelpMask = (USHORT)( CHAR_IN_IDENTIFIER | CHAR_START_NUMBER |
+ CHAR_IN_NUMBER | CHAR_IN_HEX_NUMBER );
+ for( i = '0' ; i <= '9' ; i++ )
+ aCharTypeTab[i] |= nHelpMask;
+
+ // e und E sowie . von Hand ergaenzen
+ aCharTypeTab[(int)'e'] |= CHAR_IN_NUMBER;
+ aCharTypeTab[(int)'E'] |= CHAR_IN_NUMBER;
+ aCharTypeTab[(int)'.'] |= (USHORT)( CHAR_IN_NUMBER | CHAR_START_NUMBER );
+ aCharTypeTab[(int)'&'] |= CHAR_START_NUMBER;
+
+ // Hex-Ziffern
+ for( i = 'a' ; i <= 'f' ; i++ )
+ aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
+ for( i = 'A' ; i <= 'F' ; i++ )
+ aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
+
+ // Oct-Ziffern
+ for( i = '0' ; i <= '7' ; i++ )
+ aCharTypeTab[i] |= CHAR_IN_OCT_NUMBER;
+
+ // String-Beginn/End-Zeichen
+ aCharTypeTab[(int)'\''] |= CHAR_START_STRING;
+ aCharTypeTab[(int)'\"'] |= CHAR_START_STRING;
+ aCharTypeTab[(int)'['] |= CHAR_START_STRING;
+ aCharTypeTab[(int)'`'] |= CHAR_START_STRING;
+
+ // Operator-Zeichen
+ aCharTypeTab[(int)'!'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'%'] |= CHAR_OPERATOR;
+ // aCharTypeTab[(int)'&'] |= CHAR_OPERATOR; Removed because of #i14140
+ aCharTypeTab[(int)'('] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)')'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'*'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'+'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)','] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'-'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'/'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)':'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'<'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'='] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'>'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'?'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'^'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'|'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'~'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'{'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)'}'] |= CHAR_OPERATOR;
+ // aCharTypeTab[(int)'['] |= CHAR_OPERATOR; Removed because of #i17826
+ aCharTypeTab[(int)']'] |= CHAR_OPERATOR;
+ aCharTypeTab[(int)';'] |= CHAR_OPERATOR;
+
+ // Space
+ aCharTypeTab[(int)' ' ] |= CHAR_SPACE;
+ aCharTypeTab[(int)'\t'] |= CHAR_SPACE;
+
+ // Zeilen-Ende-Zeichen
+ aCharTypeTab[(int)'\r'] |= CHAR_EOL;
+ aCharTypeTab[(int)'\n'] |= CHAR_EOL;
+
+ ppListKeyWords = NULL;
+}
+
+SimpleTokenizer_Impl::~SimpleTokenizer_Impl( void )
+{
+}
+
+SimpleTokenizer_Impl* getSimpleTokenizer( void )
+{
+ static SimpleTokenizer_Impl* pSimpleTokenizer = NULL;
+ if( !pSimpleTokenizer )
+ pSimpleTokenizer = new SimpleTokenizer_Impl();
+ return pSimpleTokenizer;
+}
+
+// Heraussuchen der jeweils naechsten Funktion aus einem JavaScript-Modul
+UINT16 SimpleTokenizer_Impl::parseLine( UINT32 nParseLine, const String* aSource )
+{
+ // Position auf den Anfang des Source-Strings setzen
+ mpStringBegin = mpActualPos = aSource->GetBuffer();
+
+ // Zeile und Spalte initialisieren
+ nLine = nParseLine;
+ nCol = 0L;
+
+ // Variablen fuer die Out-Parameter
+ TokenTypes eType;
+ const sal_Unicode* pStartPos;
+ const sal_Unicode* pEndPos;
+
+ // Schleife ueber alle Tokens
+ UINT16 nTokenCount = 0;
+ while( getNextToken( eType, pStartPos, pEndPos ) )
+ nTokenCount++;
+
+ return nTokenCount;
+}
+
+void SimpleTokenizer_Impl::getHighlightPortions( UINT32 nParseLine, const String& rLine,
+ /*out*/HighlightPortions& portions )
+{
+ // Position auf den Anfang des Source-Strings setzen
+ mpStringBegin = mpActualPos = rLine.GetBuffer();
+
+ // Zeile und Spalte initialisieren
+ nLine = nParseLine;
+ nCol = 0L;
+
+ // Variablen fuer die Out-Parameter
+ TokenTypes eType;
+ const sal_Unicode* pStartPos;
+ const sal_Unicode* pEndPos;
+
+ // Schleife ueber alle Tokens
+ while( getNextToken( eType, pStartPos, pEndPos ) )
+ {
+ HighlightPortion portion;
+
+ portion.nBegin = (UINT16)(pStartPos - mpStringBegin);
+ portion.nEnd = (UINT16)(pEndPos - mpStringBegin);
+ portion.tokenType = eType;
+
+ portions.Insert(portion, portions.Count());
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Implementierung des SyntaxHighlighter
+
+SyntaxHighlighter::SyntaxHighlighter()
+{
+ m_pSimpleTokenizer = 0;
+ m_pKeyWords = NULL;
+ m_nKeyWordCount = 0;
+}
+
+SyntaxHighlighter::~SyntaxHighlighter()
+{
+ delete m_pSimpleTokenizer;
+ delete m_pKeyWords;
+}
+
+void SyntaxHighlighter::initialize( HighlighterLanguage eLanguage_ )
+{
+ eLanguage = eLanguage_;
+ delete m_pSimpleTokenizer;
+ m_pSimpleTokenizer = new SimpleTokenizer_Impl(eLanguage);
+
+ switch (eLanguage)
+ {
+ case HIGHLIGHT_BASIC:
+ m_pSimpleTokenizer->setKeyWords( strListBasicKeyWords,
+ sizeof( strListBasicKeyWords ) / sizeof( char* ));
+ break;
+ case HIGHLIGHT_SQL:
+ m_pSimpleTokenizer->setKeyWords( strListSqlKeyWords,
+ sizeof( strListSqlKeyWords ) / sizeof( char* ));
+ break;
+ default:
+ m_pSimpleTokenizer->setKeyWords( NULL, 0 );
+ }
+}
+
+const Range SyntaxHighlighter::notifyChange( UINT32 nLine, INT32 nLineCountDifference,
+ const String* pChangedLines, UINT32 nArrayLength)
+{
+ (void)nLineCountDifference;
+
+ for( UINT32 i=0 ; i < nArrayLength ; i++ )
+ m_pSimpleTokenizer->parseLine(nLine+i, &pChangedLines[i]);
+
+ return Range( nLine, nLine + nArrayLength-1 );
+}
+
+void SyntaxHighlighter::getHighlightPortions( UINT32 nLine, const String& rLine,
+ /*out*/HighlightPortions& portions )
+{
+ m_pSimpleTokenizer->getHighlightPortions( nLine, rLine, portions );
+}
diff --git a/svtools/source/edit/textdat2.hxx b/svtools/source/edit/textdat2.hxx
new file mode 100644
index 000000000000..222e8abee5a4
--- /dev/null
+++ b/svtools/source/edit/textdat2.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 _TEXTDAT2_HXX
+#define _TEXTDAT2_HXX
+
+#include <svl/svarray.hxx>
+#include <tools/list.hxx>
+#include <vcl/seleng.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/cursor.hxx>
+
+class TextNode;
+class TextView;
+
+#define PORTIONKIND_TEXT 0
+#define PORTIONKIND_TAB 1
+
+#define DELMODE_SIMPLE 0
+#define DELMODE_RESTOFWORD 1
+#define DELMODE_RESTOFCONTENT 2
+
+#define DEL_LEFT 1
+#define DEL_RIGHT 2
+#define TRAVEL_X_DONTKNOW 0xFFFF
+#define MAXCHARSINPARA 0x3FFF-CHARPOSGROW
+
+#define LINE_SEP 0x0A
+
+
+class TETextPortion
+{
+private:
+ USHORT nLen;
+ long nWidth;
+ BYTE nKind;
+ BYTE nRightToLeft;
+
+ TETextPortion() { nLen = 0; nKind = PORTIONKIND_TEXT; nWidth = -1; nRightToLeft = 0;}
+
+public:
+ TETextPortion( USHORT nL ) {
+ nLen = nL;
+ nKind = PORTIONKIND_TEXT;
+ nWidth= -1;
+ nRightToLeft = 0;
+ }
+
+ USHORT GetLen() const { return nLen; }
+ USHORT& GetLen() { return nLen; }
+
+ long GetWidth()const { return nWidth; }
+ long& GetWidth() { return nWidth; }
+
+ BYTE GetKind() const { return nKind; }
+ BYTE& GetKind() { return nKind; }
+
+ BYTE GetRightToLeft() const { return nRightToLeft; }
+ BYTE& GetRightToLeft() { return nRightToLeft; }
+ BOOL IsRightToLeft() const { return (nRightToLeft&1); }
+
+ BOOL HasValidSize() const { return nWidth != (-1); }
+};
+
+
+
+typedef TETextPortion* TextPortionPtr;
+SV_DECL_PTRARR( TextPortionArray, TextPortionPtr, 0, 8 )
+
+class TETextPortionList : public TextPortionArray
+{
+public:
+ TETextPortionList();
+ ~TETextPortionList();
+
+ void Reset();
+ USHORT FindPortion( USHORT nCharPos, USHORT& rPortionStart, BOOL bPreferStartingPortion = FALSE );
+ USHORT GetPortionStartIndex( USHORT nPortion );
+ void DeleteFromPortion( USHORT nDelFrom );
+};
+
+struct TEWritingDirectionInfo
+{
+ BYTE nType;
+ USHORT nStartPos;
+ USHORT nEndPos;
+ TEWritingDirectionInfo( BYTE _Type, USHORT _Start, USHORT _End )
+ {
+ nType = _Type;
+ nStartPos = _Start;
+ nEndPos = _End;
+ }
+};
+
+SV_DECL_VARARR( TEWritingDirectionInfos, TEWritingDirectionInfo, 0, 4 )
+
+class TextLine
+{
+private:
+ USHORT mnStart;
+ USHORT mnEnd;
+ USHORT mnStartPortion;
+ USHORT mnEndPortion;
+
+ short mnStartX;
+
+ BOOL mbInvalid; // fuer geschickte Formatierung/Ausgabe
+
+public:
+ TextLine() {
+ mnStart = mnEnd = 0;
+ mnStartPortion = mnEndPortion = 0;
+ mnStartX = 0;
+ mbInvalid = TRUE;
+ }
+
+ BOOL IsIn( USHORT nIndex ) const
+ { return ( (nIndex >= mnStart ) && ( nIndex < mnEnd ) ); }
+
+ BOOL IsIn( USHORT nIndex, BOOL bInclEnd ) const
+ { return ( ( nIndex >= mnStart ) && ( bInclEnd ? ( nIndex <= mnEnd ) : ( nIndex < mnEnd ) ) ); }
+
+ void SetStart( USHORT n ) { mnStart = n; }
+ USHORT GetStart() const { return mnStart; }
+ USHORT& GetStart() { return mnStart; }
+
+ void SetEnd( USHORT n ) { mnEnd = n; }
+ USHORT GetEnd() const { return mnEnd; }
+ USHORT& GetEnd() { return mnEnd; }
+
+ void SetStartPortion( USHORT n ) { mnStartPortion = n; }
+ USHORT GetStartPortion() const { return mnStartPortion; }
+ USHORT& GetStartPortion() { return mnStartPortion; }
+
+ void SetEndPortion( USHORT n ) { mnEndPortion = n; }
+ USHORT GetEndPortion() const { return mnEndPortion; }
+ USHORT& GetEndPortion() { return mnEndPortion; }
+
+ USHORT GetLen() const { return mnEnd - mnStart; }
+
+ BOOL IsInvalid() const { return mbInvalid; }
+ BOOL IsValid() const { return !mbInvalid; }
+ void SetInvalid() { mbInvalid = TRUE; }
+ void SetValid() { mbInvalid = FALSE; }
+
+ BOOL IsEmpty() const { return (mnEnd > mnStart) ? FALSE : TRUE; }
+
+ short GetStartX() const { return mnStartX; }
+ void SetStartX( short n ) { mnStartX = n; }
+
+ inline BOOL operator == ( const TextLine& rLine ) const;
+ inline BOOL operator != ( const TextLine& rLine ) const;
+};
+
+typedef TextLine* TextLinePtr;
+ SV_DECL_PTRARR_DEL( TextLines, TextLinePtr, 1, 4 )
+
+inline BOOL TextLine::operator == ( const TextLine& rLine ) const
+{
+ return ( ( mnStart == rLine.mnStart ) &&
+ ( mnEnd == rLine.mnEnd ) &&
+ ( mnStartPortion == rLine.mnStartPortion ) &&
+ ( mnEndPortion == rLine.mnEndPortion ) );
+}
+
+inline BOOL TextLine::operator != ( const TextLine& rLine ) const
+{
+ return !( *this == rLine );
+}
+
+
+
+class TEParaPortion
+{
+private:
+ TextNode* mpNode;
+
+ TextLines maLines;
+ TETextPortionList maTextPortions;
+ TEWritingDirectionInfos maWritingDirectionInfos;
+
+
+ USHORT mnInvalidPosStart;
+ short mnInvalidDiff;
+
+ BOOL mbInvalid;
+ BOOL mbSimple; // nur lineares Tippen
+
+
+ TEParaPortion( const TEParaPortion& ) {;}
+
+public:
+ TEParaPortion( TextNode* pNode );
+ ~TEParaPortion();
+
+
+ BOOL IsInvalid() const { return mbInvalid; }
+ BOOL IsSimpleInvalid() const { return mbSimple; }
+ void SetNotSimpleInvalid() { mbSimple = FALSE; }
+ void SetValid() { mbInvalid = FALSE; mbSimple = TRUE;}
+
+ void MarkInvalid( USHORT nStart, short nDiff);
+ void MarkSelectionInvalid( USHORT nStart, USHORT nEnd );
+
+ USHORT GetInvalidPosStart() const { return mnInvalidPosStart; }
+ short GetInvalidDiff() const { return mnInvalidDiff; }
+
+ TextNode* GetNode() const { return mpNode; }
+ TextLines& GetLines() { return maLines; }
+ TETextPortionList& GetTextPortions() { return maTextPortions; }
+ TEWritingDirectionInfos& GetWritingDirectionInfos() { return maWritingDirectionInfos; }
+
+
+ USHORT GetLineNumber( USHORT nIndex, BOOL bInclEnd );
+ void CorrectValuesBehindLastFormattedLine( USHORT nLastFormattedLine );
+};
+
+
+class TEParaPortions : public ToolsList<TEParaPortion*>
+{
+public:
+ TEParaPortions();
+ ~TEParaPortions();
+ void Reset();
+};
+
+
+class TextSelFunctionSet: public FunctionSet
+{
+private:
+ TextView* mpView;
+
+public:
+ TextSelFunctionSet( TextView* pView );
+
+ virtual void BeginDrag();
+
+ virtual void CreateAnchor();
+
+ virtual BOOL SetCursorAtPoint( const Point& rPointPixel, BOOL bDontSelectAtCursor = FALSE );
+
+ virtual BOOL IsSelectionAtPoint( const Point& rPointPixel );
+ virtual void DeselectAll();
+
+ virtual void DeselectAtPoint( const Point& );
+ virtual void DestroyAnchor();
+};
+
+
+class IdleFormatter : public Timer
+{
+private:
+ TextView* mpView;
+ USHORT mnRestarts;
+
+public:
+ IdleFormatter();
+ ~IdleFormatter();
+
+ void DoIdleFormat( TextView* pV, USHORT nMaxRestarts );
+ void ForceTimeout();
+ TextView* GetView() { return mpView; }
+};
+
+struct TextDDInfo
+{
+ Cursor maCursor;
+ TextPaM maDropPos;
+
+ BOOL mbStarterOfDD;
+ BOOL mbVisCursor;
+
+ TextDDInfo()
+ {
+ maCursor.SetStyle( CURSOR_SHADOW );
+ mbStarterOfDD = FALSE;
+ mbVisCursor = FALSE;
+ }
+};
+
+#endif // _TEXTDAT2_HXX
diff --git a/svtools/source/edit/textdata.cxx b/svtools/source/edit/textdata.cxx
new file mode 100644
index 000000000000..32bdfe40a3fb
--- /dev/null
+++ b/svtools/source/edit/textdata.cxx
@@ -0,0 +1,361 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/textdata.hxx>
+#include <textdat2.hxx>
+
+#include <tools/debug.hxx>
+
+SV_IMPL_PTRARR( TextLines, TextLinePtr );
+SV_IMPL_VARARR( TEWritingDirectionInfos, TEWritingDirectionInfo );
+
+
+ // -------------------------------------------------------------------------
+// (+) class TextSelection
+// -------------------------------------------------------------------------
+
+TextSelection::TextSelection()
+{
+}
+
+TextSelection::TextSelection( const TextPaM& rPaM ) :
+ maStartPaM( rPaM ), maEndPaM( rPaM )
+{
+}
+
+TextSelection::TextSelection( const TextPaM& rStart, const TextPaM& rEnd ) :
+ maStartPaM( rStart ), maEndPaM( rEnd )
+{
+}
+
+void TextSelection::Justify()
+{
+ if ( maEndPaM < maStartPaM )
+ {
+ TextPaM aTemp( maStartPaM );
+ maStartPaM = maEndPaM;
+ maEndPaM = aTemp;
+ }
+}
+
+
+ // -------------------------------------------------------------------------
+// (+) class TETextPortionList
+// -------------------------------------------------------------------------
+TETextPortionList::TETextPortionList()
+{
+}
+
+TETextPortionList::~TETextPortionList()
+{
+ Reset();
+}
+
+void TETextPortionList::Reset()
+{
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ delete GetObject( nPortion );
+ Remove( 0, Count() );
+}
+
+void TETextPortionList::DeleteFromPortion( USHORT nDelFrom )
+{
+ DBG_ASSERT( ( nDelFrom < Count() ) || ( (nDelFrom == 0) && (Count() == 0) ), "DeleteFromPortion: Out of range" );
+ for ( USHORT nP = nDelFrom; nP < Count(); nP++ )
+ delete GetObject( nP );
+ Remove( nDelFrom, Count()-nDelFrom );
+}
+
+USHORT TETextPortionList::FindPortion( USHORT nCharPos, USHORT& nPortionStart, BOOL bPreferStartingPortion )
+{
+ // Bei nCharPos an Portion-Grenze wird die linke Portion gefunden
+ USHORT nTmpPos = 0;
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ {
+ TETextPortion* pPortion = GetObject( nPortion );
+ nTmpPos = nTmpPos + pPortion->GetLen();
+ if ( nTmpPos >= nCharPos )
+ {
+ // take this one if we don't prefer the starting portion, or if it's the last one
+ if ( ( nTmpPos != nCharPos ) || !bPreferStartingPortion || ( nPortion == Count() - 1 ) )
+ {
+ nPortionStart = nTmpPos - pPortion->GetLen();
+ return nPortion;
+ }
+ }
+ }
+ DBG_ERROR( "FindPortion: Nicht gefunden!" );
+ return ( Count() - 1 );
+}
+
+/*
+USHORT TETextPortionList::GetPortionStartIndex( USHORT nPortion )
+{
+ USHORT nPos = 0;
+ for ( USHORT nP = 0; nP < nPortion; nP++ )
+ {
+ TETextPortion* pPortion = GetObject( nP );
+ nPos += pPortion->GetLen();
+ }
+ return nPos;
+}
+*/
+
+
+ // -------------------------------------------------------------------------
+// (+) class TEParaPortion
+// -------------------------------------------------------------------------
+TEParaPortion::TEParaPortion( TextNode* pN )
+{
+ mpNode = pN;
+ mnInvalidPosStart = mnInvalidDiff = 0;
+ mbInvalid = TRUE;
+ mbSimple = FALSE;
+}
+
+TEParaPortion::~TEParaPortion()
+{
+}
+
+void TEParaPortion::MarkInvalid( USHORT nStart, short nDiff )
+{
+ if ( mbInvalid == FALSE )
+ {
+ mnInvalidPosStart = ( nDiff >= 0 ) ? nStart : ( nStart + nDiff );
+ mnInvalidDiff = nDiff;
+ }
+ else
+ {
+ // Einfaches hintereinander tippen
+ if ( ( nDiff > 0 ) && ( mnInvalidDiff > 0 ) &&
+ ( ( mnInvalidPosStart+mnInvalidDiff ) == nStart ) )
+ {
+ mnInvalidDiff = mnInvalidDiff + nDiff;
+ }
+ // Einfaches hintereinander loeschen
+ else if ( ( nDiff < 0 ) && ( mnInvalidDiff < 0 ) && ( mnInvalidPosStart == nStart ) )
+ {
+ mnInvalidPosStart = mnInvalidPosStart + nDiff;
+ mnInvalidDiff = mnInvalidDiff + nDiff;
+ }
+ else
+ {
+ DBG_ASSERT( ( nDiff >= 0 ) || ( (nStart+nDiff) >= 0 ), "MarkInvalid: Diff out of Range" );
+ mnInvalidPosStart = Min( mnInvalidPosStart, (USHORT) ( (nDiff < 0) ? nStart+nDiff : nDiff ) );
+ mnInvalidDiff = 0;
+ mbSimple = FALSE;
+ }
+ }
+
+ maWritingDirectionInfos.Remove( 0, maWritingDirectionInfos.Count() );
+
+ mbInvalid = TRUE;
+}
+
+void TEParaPortion::MarkSelectionInvalid( USHORT nStart, USHORT /*nEnd*/ )
+{
+ if ( mbInvalid == FALSE )
+ {
+ mnInvalidPosStart = nStart;
+// nInvalidPosEnd = nEnd;
+ }
+ else
+ {
+ mnInvalidPosStart = Min( mnInvalidPosStart, nStart );
+// nInvalidPosEnd = pNode->Len();
+ }
+
+ maWritingDirectionInfos.Remove( 0, maWritingDirectionInfos.Count() );
+
+ mnInvalidDiff = 0;
+ mbInvalid = TRUE;
+ mbSimple = FALSE;
+}
+
+USHORT TEParaPortion::GetLineNumber( USHORT nChar, BOOL bInclEnd )
+{
+ for ( USHORT nLine = 0; nLine < maLines.Count(); nLine++ )
+ {
+ TextLine* pLine = maLines.GetObject( nLine );
+ if ( ( bInclEnd && ( pLine->GetEnd() >= nChar ) ) ||
+ ( pLine->GetEnd() > nChar ) )
+ {
+ return nLine;
+ }
+ }
+
+ // Dann sollte es am Ende der letzten Zeile sein!
+ DBG_ASSERT( nChar == maLines[ maLines.Count() - 1 ]->GetEnd(), "Index voll daneben!" );
+ DBG_ASSERT( !bInclEnd, "Zeile nicht gefunden: FindLine" );
+ return ( maLines.Count() - 1 );
+}
+
+
+void TEParaPortion::CorrectValuesBehindLastFormattedLine( USHORT nLastFormattedLine )
+{
+ USHORT nLines = maLines.Count();
+ DBG_ASSERT( nLines, "CorrectPortionNumbersFromLine: Leere Portion?" );
+ if ( nLastFormattedLine < ( nLines - 1 ) )
+ {
+ const TextLine* pLastFormatted = maLines[ nLastFormattedLine ];
+ const TextLine* pUnformatted = maLines[ nLastFormattedLine+1 ];
+ short nPortionDiff = pUnformatted->GetStartPortion() - pLastFormatted->GetEndPortion();
+ short nTextDiff = pUnformatted->GetStart() - pLastFormatted->GetEnd();
+ nTextDiff++; // LastFormatted->GetEnd() war incl. => 1 zuviel abgezogen!
+
+ // Die erste unformatierte muss genau eine Portion hinter der letzten der
+ // formatierten beginnen:
+ // Wenn in der geaenderten Zeile eine Portion gesplittet wurde,
+ // kann nLastEnd > nNextStart sein!
+ short nPDiff = sal::static_int_cast< short >(-( nPortionDiff-1 ));
+ short nTDiff = sal::static_int_cast< short >(-( nTextDiff-1 ));
+ if ( nPDiff || nTDiff )
+ {
+ for ( USHORT nL = nLastFormattedLine+1; nL < nLines; nL++ )
+ {
+ TextLine* pLine = maLines[ nL ];
+
+ pLine->GetStartPortion() = pLine->GetStartPortion() + nPDiff;
+ pLine->GetEndPortion() = pLine->GetEndPortion() + nPDiff;
+
+ pLine->GetStart() = pLine->GetStart() + nTDiff;
+ pLine->GetEnd() = pLine->GetEnd() + nTDiff;
+
+ pLine->SetValid();
+ }
+ }
+ }
+}
+
+ // -------------------------------------------------------------------------
+// (+) class TEParaPortions
+// -------------------------------------------------------------------------
+TEParaPortions::TEParaPortions()
+{
+}
+
+TEParaPortions::~TEParaPortions()
+{
+ Reset();
+}
+
+void TEParaPortions::Reset()
+{
+ TEParaPortions::iterator aIter( begin() );
+ while ( aIter != end() )
+ delete *aIter++;
+ clear();
+}
+
+ // -------------------------------------------------------------------------
+// (+) class IdleFormatter
+// -------------------------------------------------------------------------
+IdleFormatter::IdleFormatter()
+{
+ mpView = 0;
+ mnRestarts = 0;
+}
+
+IdleFormatter::~IdleFormatter()
+{
+ mpView = 0;
+}
+
+void IdleFormatter::DoIdleFormat( TextView* pV, USHORT nMaxRestarts )
+{
+ mpView = pV;
+
+ if ( IsActive() )
+ mnRestarts++;
+
+ if ( mnRestarts > nMaxRestarts )
+ {
+ mnRestarts = 0;
+ ((Link&)GetTimeoutHdl()).Call( this );
+ }
+ else
+ {
+ Start();
+ }
+}
+
+void IdleFormatter::ForceTimeout()
+{
+ if ( IsActive() )
+ {
+ Stop();
+ mnRestarts = 0;
+ ((Link&)GetTimeoutHdl()).Call( this );
+ }
+}
+
+TYPEINIT1( TextHint, SfxSimpleHint );
+
+TextHint::TextHint( ULONG Id ) : SfxSimpleHint( Id )
+{
+ mnValue = 0;
+}
+
+TextHint::TextHint( ULONG Id, ULONG nValue ) : SfxSimpleHint( Id )
+{
+ mnValue = nValue;
+}
+
+TEIMEInfos::TEIMEInfos( const TextPaM& rPos, const String& rOldTextAfterStartPos )
+: aOldTextAfterStartPos( rOldTextAfterStartPos )
+{
+ aPos = rPos;
+ nLen = 0;
+ bCursor = TRUE;
+ pAttribs = NULL;
+ bWasCursorOverwrite = FALSE;
+}
+
+TEIMEInfos::~TEIMEInfos()
+{
+ delete[] pAttribs;
+}
+
+void TEIMEInfos::CopyAttribs( const USHORT* pA, USHORT nL )
+{
+ nLen = nL;
+ delete pAttribs;
+ pAttribs = new USHORT[ nL ];
+ memcpy( pAttribs, pA, nL*sizeof(USHORT) );
+}
+
+void TEIMEInfos::DestroyAttribs()
+{
+ delete pAttribs;
+ pAttribs = NULL;
+ nLen = 0;
+}
+
+
diff --git a/svtools/source/edit/textdoc.cxx b/svtools/source/edit/textdoc.cxx
new file mode 100644
index 000000000000..d4470904077e
--- /dev/null
+++ b/svtools/source/edit/textdoc.cxx
@@ -0,0 +1,1047 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <textdoc.hxx>
+
+#include <stdlib.h>
+
+SV_IMPL_PTRARR( TextCharAttribs, TextCharAttribPtr );
+
+
+
+// Vergleichmethode wird von QuickSort gerufen...
+
+EXTERN_C
+#if defined( PM2 ) && (!defined( CSET ) && !defined ( MTW ) && !defined( WTC ))
+int _stdcall
+#else
+#ifdef WNT
+#if _MSC_VER >= 1200
+int __cdecl
+#else
+int _cdecl
+#endif
+#else
+int
+#endif
+#endif
+
+CompareStart( const void* pFirst, const void* pSecond )
+{
+ if ( (*((TextCharAttrib**)pFirst))->GetStart() < (*((TextCharAttrib**)pSecond))->GetStart() )
+ return (-1);
+ else if ( (*((TextCharAttrib**)pFirst))->GetStart() > (*((TextCharAttrib**)pSecond))->GetStart() )
+ return (1);
+ return 0;
+}
+
+
+ // -------------------------------------------------------------------------
+// (+) class TextCharAttrib
+// -------------------------------------------------------------------------
+TextCharAttrib::TextCharAttrib( const TextAttrib& rAttr, USHORT nStart, USHORT nEnd )
+{
+ mpAttr = rAttr.Clone();
+ mnStart = nStart,
+ mnEnd = nEnd;
+}
+
+TextCharAttrib::TextCharAttrib( const TextCharAttrib& rTextCharAttrib )
+{
+ mpAttr = rTextCharAttrib.GetAttr().Clone();
+ mnStart = rTextCharAttrib.mnStart;
+ mnEnd = rTextCharAttrib.mnEnd;
+}
+
+TextCharAttrib::~TextCharAttrib()
+{
+ delete mpAttr;
+}
+
+ // -------------------------------------------------------------------------
+// (+) class TextCharAttribList
+// -------------------------------------------------------------------------
+
+TextCharAttribList::TextCharAttribList()
+{
+ mbHasEmptyAttribs = FALSE;
+}
+
+TextCharAttribList::~TextCharAttribList()
+{
+ // PTRARR_DEL
+}
+
+void TextCharAttribList::Clear( BOOL bDestroyAttribs )
+{
+ if ( bDestroyAttribs )
+ TextCharAttribs::DeleteAndDestroy( 0, Count() );
+ else
+ TextCharAttribs::Remove( 0, Count() );
+}
+
+
+void TextCharAttribList::InsertAttrib( TextCharAttrib* pAttrib )
+{
+ if ( pAttrib->IsEmpty() )
+ mbHasEmptyAttribs = TRUE;
+
+ const USHORT nCount = Count();
+ const USHORT nStart = pAttrib->GetStart(); // vielleicht besser fuer Comp.Opt.
+ BOOL bInserted = FALSE;
+ for ( USHORT x = 0; x < nCount; x++ )
+ {
+ TextCharAttrib* pCurAttrib = GetObject( x );
+ if ( pCurAttrib->GetStart() > nStart )
+ {
+ Insert( pAttrib, x );
+ bInserted = TRUE;
+ break;
+ }
+ }
+ if ( !bInserted )
+ Insert( pAttrib, nCount );
+}
+
+void TextCharAttribList::ResortAttribs()
+{
+ if ( Count() )
+ qsort( (void*)GetData(), Count(), sizeof( TextCharAttrib* ), CompareStart );
+}
+
+TextCharAttrib* TextCharAttribList::FindAttrib( USHORT nWhich, USHORT nPos )
+{
+ // Rueckwaerts, falls eins dort endet, das naechste startet.
+ // => Das startende gilt...
+
+ for ( USHORT nAttr = Count(); nAttr; )
+ {
+ TextCharAttrib* pAttr = GetObject( --nAttr );
+
+ if ( pAttr->GetEnd() < nPos )
+ return 0;
+
+ if ( ( pAttr->Which() == nWhich ) && pAttr->IsIn(nPos) )
+ return pAttr;
+ }
+ return NULL;
+}
+
+TextCharAttrib* TextCharAttribList::FindNextAttrib( USHORT nWhich, USHORT nFromPos, USHORT nMaxPos ) const
+{
+ DBG_ASSERT( nWhich, "FindNextAttrib: Which?" );
+ const USHORT nAttribs = Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ TextCharAttrib* pAttr = GetObject( nAttr );
+ if ( ( pAttr->GetStart() >= nFromPos ) &&
+ ( pAttr->GetEnd() <= nMaxPos ) &&
+ ( pAttr->Which() == nWhich ) )
+ return pAttr;
+ }
+ return NULL;
+}
+
+BOOL TextCharAttribList::HasAttrib( USHORT nWhich ) const
+{
+ for ( USHORT nAttr = Count(); nAttr; )
+ {
+ const TextCharAttrib* pAttr = GetObject( --nAttr );
+ if ( pAttr->Which() == nWhich )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL TextCharAttribList::HasBoundingAttrib( USHORT nBound )
+{
+ // Rueckwaerts, falls eins dort endet, das naechste startet.
+ // => Das startende gilt...
+ for ( USHORT nAttr = Count(); nAttr; )
+ {
+ TextCharAttrib* pAttr = GetObject( --nAttr );
+
+ if ( pAttr->GetEnd() < nBound )
+ return FALSE;
+
+ if ( ( pAttr->GetStart() == nBound ) || ( pAttr->GetEnd() == nBound ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+TextCharAttrib* TextCharAttribList::FindEmptyAttrib( USHORT nWhich, USHORT nPos )
+{
+ if ( !mbHasEmptyAttribs )
+ return 0;
+
+ const USHORT nAttribs = Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ TextCharAttrib* pAttr = GetObject( nAttr );
+ if ( pAttr->GetStart() > nPos )
+ return 0;
+
+ if ( ( pAttr->GetStart() == nPos ) && ( pAttr->GetEnd() == nPos ) && ( pAttr->Which() == nWhich ) )
+ return pAttr;
+ }
+ return 0;
+}
+
+void TextCharAttribList::DeleteEmptyAttribs()
+{
+ for ( USHORT nAttr = 0; nAttr < Count(); nAttr++ )
+ {
+ TextCharAttrib* pAttr = GetObject( nAttr );
+ if ( pAttr->IsEmpty() )
+ {
+ Remove( nAttr );
+ delete pAttr;
+ nAttr--;
+ }
+ }
+ mbHasEmptyAttribs = FALSE;
+}
+
+#ifdef DBG_UTIL
+BOOL TextCharAttribList::DbgCheckAttribs()
+{
+ BOOL bOK = TRUE;
+ for ( USHORT nAttr = 0; nAttr < Count(); nAttr++ )
+ {
+ TextCharAttrib* pAttr = GetObject( nAttr );
+ if ( pAttr->GetStart() > pAttr->GetEnd() )
+ {
+ bOK = FALSE;
+ DBG_ERROR( "Attr verdreht" );
+ }
+ }
+ return bOK;
+}
+#endif
+
+ // -------------------------------------------------------------------------
+// (+) class TextNode
+// -------------------------------------------------------------------------
+
+TextNode::TextNode( const String& rText ) :
+ maText( rText )
+{
+}
+
+void TextNode::ExpandAttribs( USHORT nIndex, USHORT nNew )
+{
+ if ( !nNew )
+ return;
+
+ BOOL bResort = FALSE;
+ USHORT nAttribs = maCharAttribs.Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ TextCharAttrib* pAttrib = maCharAttribs.GetAttrib( nAttr );
+ if ( pAttrib->GetEnd() >= nIndex )
+ {
+ // Alle Attribute hinter der Einfuegeposition verschieben...
+ if ( pAttrib->GetStart() > nIndex )
+ {
+ pAttrib->MoveForward( nNew );
+ }
+ // 0: Leeres Attribut expandieren, wenn an Einfuegestelle
+ else if ( pAttrib->IsEmpty() )
+ {
+ // Index nicht pruefen, leeres durfte nur dort liegen.
+ // Wenn spaeter doch Ueberpruefung:
+ // Spezialfall: Start == 0; AbsLen == 1, nNew = 1 => Expand, weil durch Absatzumbruch!
+ // Start <= nIndex, End >= nIndex => Start=End=nIndex!
+// if ( pAttrib->GetStart() == nIndex )
+ pAttrib->Expand( nNew );
+ }
+ // 1: Attribut startet davor, geht bis Index...
+ else if ( pAttrib->GetEnd() == nIndex ) // Start muss davor liegen
+ {
+ // Nur expandieren, wenn kein Feature,
+ // und wenn nicht in ExcludeListe!
+ // Sonst geht z.B. ein UL bis zum neuen ULDB, beide expandieren
+ if ( !maCharAttribs.FindEmptyAttrib( pAttrib->Which(), nIndex ) )
+ {
+ pAttrib->Expand( nNew );
+ }
+ else
+ bResort = TRUE;
+ }
+ // 2: Attribut startet davor, geht hinter Index...
+ else if ( ( pAttrib->GetStart() < nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
+ {
+ pAttrib->Expand( nNew );
+ }
+ // 3: Attribut startet auf Index...
+ else if ( pAttrib->GetStart() == nIndex )
+ {
+ if ( nIndex == 0 )
+ {
+ pAttrib->Expand( nNew );
+// bResort = TRUE; // es gibt ja keine Features mehr...
+ }
+ else
+ pAttrib->MoveForward( nNew );
+ }
+ }
+
+ DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Expand: Attribut verdreht!" );
+ DBG_ASSERT( ( pAttrib->GetEnd() <= maText.Len() ), "Expand: Attrib groesser als Absatz!" );
+ DBG_ASSERT( !pAttrib->IsEmpty(), "Leeres Attribut nach ExpandAttribs?" );
+ }
+
+ if ( bResort )
+ maCharAttribs.ResortAttribs();
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( CheckOrderedList( (TextCharAttribs*)&maCharAttribs ), "Expand: Start-Liste verdreht" );
+#endif
+}
+
+void TextNode::CollapsAttribs( USHORT nIndex, USHORT nDeleted )
+{
+ if ( !nDeleted )
+ return;
+
+ BOOL bResort = FALSE;
+ USHORT nEndChanges = nIndex+nDeleted;
+
+ for ( USHORT nAttr = 0; nAttr < maCharAttribs.Count(); nAttr++ )
+ {
+ TextCharAttrib* pAttrib = maCharAttribs.GetAttrib( nAttr );
+ BOOL bDelAttr = FALSE;
+ if ( pAttrib->GetEnd() >= nIndex )
+ {
+ // Alles Attribute hinter der Einfuegeposition verschieben...
+ if ( pAttrib->GetStart() >= nEndChanges )
+ {
+ pAttrib->MoveBackward( nDeleted );
+ }
+ // 1. Innenliegende Attribute loeschen...
+ else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() <= nEndChanges ) )
+ {
+ // Spezialfall: Attrubt deckt genau den Bereich ab
+ // => als leeres Attribut behalten.
+ if ( ( pAttrib->GetStart() == nIndex ) && ( pAttrib->GetEnd() == nEndChanges ) )
+ pAttrib->GetEnd() = nIndex; // leer
+ else
+ bDelAttr = TRUE;
+ }
+ // 2. Attribut beginnt davor, endet drinnen oder dahinter...
+ else if ( ( pAttrib->GetStart() <= nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
+ {
+ if ( pAttrib->GetEnd() <= nEndChanges ) // endet drinnen
+ pAttrib->GetEnd() = nIndex;
+ else
+ pAttrib->Collaps( nDeleted ); // endet dahinter
+ }
+ // 3. Attribut beginnt drinnen, endet dahinter...
+ else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() > nEndChanges ) )
+ {
+ // Features duerfen nicht expandieren!
+ pAttrib->GetStart() = nEndChanges;
+ pAttrib->MoveBackward( nDeleted );
+ }
+ }
+
+ DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Collaps: Attribut verdreht!" );
+ DBG_ASSERT( ( pAttrib->GetEnd() <= maText.Len()) || bDelAttr, "Collaps: Attrib groesser als Absatz!" );
+ if ( bDelAttr /* || pAttrib->IsEmpty() */ )
+ {
+ bResort = TRUE;
+ maCharAttribs.RemoveAttrib( nAttr );
+ delete pAttrib;
+ nAttr--;
+ }
+ else if ( pAttrib->IsEmpty() )
+ maCharAttribs.HasEmptyAttribs() = TRUE;
+ }
+
+ if ( bResort )
+ maCharAttribs.ResortAttribs();
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( CheckOrderedList( (TextCharAttribs)&maCharAttribs ), "Collaps: Start-Liste verdreht" );
+#endif
+}
+
+void TextNode::InsertText( USHORT nPos, const String& rText )
+{
+ maText.Insert( rText, nPos );
+ ExpandAttribs( nPos, rText.Len() );
+}
+
+void TextNode::InsertText( USHORT nPos, sal_Unicode c )
+{
+ maText.Insert( c, nPos );
+ ExpandAttribs( nPos, 1 );
+}
+
+void TextNode::RemoveText( USHORT nPos, USHORT nChars )
+{
+ maText.Erase( nPos, nChars );
+ CollapsAttribs( nPos, nChars );
+}
+
+TextNode* TextNode::Split( USHORT nPos, BOOL bKeepEndingAttribs )
+{
+ String aNewText;
+ if ( nPos < maText.Len() )
+ {
+ aNewText = maText.Copy( nPos );
+ maText.Erase( nPos );
+ }
+ TextNode* pNew = new TextNode( aNewText );
+
+ for ( USHORT nAttr = 0; nAttr < maCharAttribs.Count(); nAttr++ )
+ {
+ TextCharAttrib* pAttrib = maCharAttribs.GetAttrib( nAttr );
+ if ( pAttrib->GetEnd() < nPos )
+ {
+ // bleiben unveraendert....
+ ;
+ }
+ else if ( pAttrib->GetEnd() == nPos )
+ {
+ // muessen als leeres Attribut kopiert werden.
+ // !FindAttrib nur sinnvoll, wenn Rueckwaerts durch Liste!
+ if ( bKeepEndingAttribs && !pNew->maCharAttribs.FindAttrib( pAttrib->Which(), 0 ) )
+ {
+ TextCharAttrib* pNewAttrib = new TextCharAttrib( *pAttrib );
+ pNewAttrib->GetStart() = 0;
+ pNewAttrib->GetEnd() = 0;
+ pNew->maCharAttribs.InsertAttrib( pNewAttrib );
+ }
+ }
+ else if ( pAttrib->IsInside( nPos ) || ( !nPos && !pAttrib->GetStart() ) )
+ {
+ // Wenn ganz vorne gecuttet wird, muss das Attribut erhalten bleiben!
+ // muessen kopiert und geaendert werden
+ TextCharAttrib* pNewAttrib = new TextCharAttrib( *pAttrib );
+ pNewAttrib->GetStart() = 0;
+ pNewAttrib->GetEnd() = pAttrib->GetEnd()-nPos;
+ pNew->maCharAttribs.InsertAttrib( pNewAttrib );
+ // stutzen:
+ pAttrib->GetEnd() = nPos;
+ }
+ else
+ {
+ DBG_ASSERT( pAttrib->GetStart() >= nPos, "Start < nPos!" );
+ DBG_ASSERT( pAttrib->GetEnd() >= nPos, "End < nPos!" );
+ // alle dahinter verschieben in den neuen Node (this)
+ maCharAttribs.RemoveAttrib( nAttr );
+ pNew->maCharAttribs.InsertAttrib( pAttrib );
+ pAttrib->GetStart() = pAttrib->GetStart() - nPos;
+ pAttrib->GetEnd() = pAttrib->GetEnd() - nPos;
+ nAttr--;
+ }
+ }
+ return pNew;
+}
+
+void TextNode::Append( const TextNode& rNode )
+{
+ USHORT nOldLen = maText.Len();
+
+ maText += rNode.GetText();
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( maCharAttribs.DbgCheckAttribs(), "Attribute VOR AppendAttribs kaputt" );
+#endif
+
+ const USHORT nAttribs = rNode.GetCharAttribs().Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ TextCharAttrib* pAttrib = rNode.GetCharAttribs().GetAttrib( nAttr );
+ BOOL bMelted = FALSE;
+ if ( pAttrib->GetStart() == 0 )
+ {
+ // Evtl koennen Attribute zusammengefasst werden:
+ USHORT nTmpAttribs = maCharAttribs.Count();
+ for ( USHORT nTmpAttr = 0; nTmpAttr < nTmpAttribs; nTmpAttr++ )
+ {
+ TextCharAttrib* pTmpAttrib = maCharAttribs.GetAttrib( nTmpAttr );
+
+ if ( pTmpAttrib->GetEnd() == nOldLen )
+ {
+ if ( ( pTmpAttrib->Which() == pAttrib->Which() ) &&
+ ( pTmpAttrib->GetAttr() == pAttrib->GetAttr() ) )
+ {
+ pTmpAttrib->GetEnd() =
+ pTmpAttrib->GetEnd() + pAttrib->GetLen();
+ bMelted = TRUE;
+ break; // es kann nur eins von der Sorte an der Stelle geben
+ }
+ }
+ }
+ }
+
+ if ( !bMelted )
+ {
+ TextCharAttrib* pNewAttrib = new TextCharAttrib( *pAttrib );
+ pNewAttrib->GetStart() = pNewAttrib->GetStart() + nOldLen;
+ pNewAttrib->GetEnd() = pNewAttrib->GetEnd() + nOldLen;
+ maCharAttribs.InsertAttrib( pNewAttrib );
+ }
+ }
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( maCharAttribs.DbgCheckAttribs(), "Attribute NACH AppendAttribs kaputt" );
+#endif
+}
+
+ // -------------------------------------------------------------------------
+// (+) class TextDoc
+// -------------------------------------------------------------------------
+
+TextDoc::TextDoc()
+{
+ mnLeftMargin = 0;
+};
+
+TextDoc::~TextDoc()
+{
+ DestroyTextNodes();
+}
+
+void TextDoc::Clear()
+{
+ DestroyTextNodes();
+}
+
+void TextDoc::DestroyTextNodes()
+{
+ for ( ULONG nNode = 0; nNode < maTextNodes.Count(); nNode++ )
+ delete maTextNodes.GetObject( nNode );
+ maTextNodes.clear();
+}
+
+String TextDoc::GetText( const sal_Unicode* pSep ) const
+{
+ ULONG nLen = GetTextLen( pSep );
+ ULONG nNodes = maTextNodes.Count();
+
+ if ( nLen > STRING_MAXLEN )
+ {
+ DBG_ERROR( "Text zu gross fuer String" );
+ return String();
+ }
+
+ String aASCIIText;
+ ULONG nLastNode = nNodes-1;
+ for ( ULONG nNode = 0; nNode < nNodes; nNode++ )
+ {
+ TextNode* pNode = maTextNodes.GetObject( nNode );
+ String aTmp( pNode->GetText() );
+ aASCIIText += aTmp;
+ if ( pSep && ( nNode != nLastNode ) )
+ aASCIIText += pSep;
+ }
+
+ return aASCIIText;
+}
+
+XubString TextDoc::GetText( ULONG nPara ) const
+{
+ XubString aText;
+ TextNode* pNode = ( nPara < maTextNodes.Count() ) ? maTextNodes.GetObject( nPara ) : 0;
+ if ( pNode )
+ aText = pNode->GetText();
+
+ return aText;
+}
+
+
+ULONG TextDoc::GetTextLen( const xub_Unicode* pSep, const TextSelection* pSel ) const
+{
+ ULONG nLen = 0;
+ ULONG nNodes = maTextNodes.Count();
+ if ( nNodes )
+ {
+ ULONG nStartNode = 0;
+ ULONG nEndNode = nNodes-1;
+ if ( pSel )
+ {
+ nStartNode = pSel->GetStart().GetPara();
+ nEndNode = pSel->GetEnd().GetPara();
+ }
+
+ for ( ULONG nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ TextNode* pNode = maTextNodes.GetObject( nNode );
+
+ USHORT nS = 0;
+ ULONG nE = pNode->GetText().Len();
+ if ( pSel && ( nNode == pSel->GetStart().GetPara() ) )
+ nS = pSel->GetStart().GetIndex();
+ if ( pSel && ( nNode == pSel->GetEnd().GetPara() ) )
+ nE = pSel->GetEnd().GetIndex();
+
+ nLen += ( nE - nS );
+ }
+
+ if ( pSep )
+ nLen += (nEndNode-nStartNode) * String( pSep ).Len();
+ }
+
+ return nLen;
+}
+
+TextPaM TextDoc::InsertText( const TextPaM& rPaM, xub_Unicode c )
+{
+ DBG_ASSERT( c != 0x0A, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( c != 0x0D, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+
+ TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
+ pNode->InsertText( rPaM.GetIndex(), c );
+
+ TextPaM aPaM( rPaM.GetPara(), rPaM.GetIndex()+1 );
+ return aPaM;
+}
+
+TextPaM TextDoc::InsertText( const TextPaM& rPaM, const XubString& rStr )
+{
+ DBG_ASSERT( rStr.Search( 0x0A ) == STRING_NOTFOUND, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( rStr.Search( 0x0D ) == STRING_NOTFOUND, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+
+ TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
+ pNode->InsertText( rPaM.GetIndex(), rStr );
+
+ TextPaM aPaM( rPaM.GetPara(), rPaM.GetIndex()+rStr.Len() );
+ return aPaM;
+}
+
+TextPaM TextDoc::InsertParaBreak( const TextPaM& rPaM, BOOL bKeepEndingAttribs )
+{
+ TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
+ TextNode* pNew = pNode->Split( rPaM.GetIndex(), bKeepEndingAttribs );
+
+ maTextNodes.Insert( pNew, rPaM.GetPara()+1 );
+
+ TextPaM aPaM( rPaM.GetPara()+1, 0 );
+ return aPaM;
+}
+
+TextPaM TextDoc::ConnectParagraphs( TextNode* pLeft, TextNode* pRight )
+{
+ USHORT nPrevLen = pLeft->GetText().Len();
+ pLeft->Append( *pRight );
+
+ // der rechte verschwindet.
+ ULONG nRight = maTextNodes.GetPos( pRight );
+ maTextNodes.Remove( nRight );
+ delete pRight;
+
+ ULONG nLeft = maTextNodes.GetPos( pLeft );
+ TextPaM aPaM( nLeft, nPrevLen );
+ return aPaM;
+}
+
+TextPaM TextDoc::RemoveChars( const TextPaM& rPaM, USHORT nChars )
+{
+ TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
+ pNode->RemoveText( rPaM.GetIndex(), nChars );
+
+ return rPaM;
+}
+
+BOOL TextDoc::IsValidPaM( const TextPaM& rPaM )
+{
+ if ( rPaM.GetPara() >= maTextNodes.Count() )
+ {
+ DBG_ERROR( "PaM: Para out of range" );
+ return FALSE;
+ }
+ TextNode * pNode = maTextNodes.GetObject( rPaM.GetPara() );
+ if ( rPaM.GetIndex() > pNode->GetText().Len() )
+ {
+ DBG_ERROR( "PaM: Index out of range" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+
+void TextDoc::InsertAttribInSelection( TextNode* pNode, USHORT nStart, USHORT nEnd, const SfxPoolItem& rPoolItem )
+{
+ DBG_ASSERT( pNode, "Wohin mit dem Attribut?" );
+ DBG_ASSERT( nEnd <= pNode->Len(), "InsertAttrib: Attribut zu gross!" );
+
+ // fuer Optimierung:
+ // dieses endet am Anfang der Selektion => kann erweitert werden
+ TextCharAttrib* pEndingAttrib = 0;
+ // dieses startet am Ende der Selektion => kann erweitert werden
+ TextCharAttrib* pStartingAttrib = 0;
+
+ DBG_ASSERT( nStart <= nEnd, "Kleiner Rechenfehler in InsertAttribInSelection" );
+
+ RemoveAttribs( pNode, nStart, nEnd, pStartingAttrib, pEndingAttrib, rPoolItem.Which() );
+
+ if ( pStartingAttrib && pEndingAttrib &&
+ ( *(pStartingAttrib->GetItem()) == rPoolItem ) &&
+ ( *(pEndingAttrib->GetItem()) == rPoolItem ) )
+ {
+ // wird ein groesses Attribut.
+ pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd();
+ pCurPool->Remove( *(pStartingAttrib->GetItem()) );
+ pNode->GetCharAttribs().GetAttribs().Remove( pNode->GetCharAttribs().GetAttribs().GetPos( pStartingAttrib ) );
+ delete pStartingAttrib;
+ }
+ else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem ) )
+ pStartingAttrib->GetStart() = nStart;
+ else if ( pEndingAttrib && ( *(pEndingAttrib->GetItem()) == rPoolItem ) )
+ pEndingAttrib->GetEnd() = nEnd;
+ else
+ InsertAttrib( rPoolItem, pNode, nStart, nEnd );
+
+ if ( pStartingAttrib )
+ pNode->GetCharAttribs().ResortAttribs();
+}
+
+BOOL TextDoc::RemoveAttribs( TextNode* pNode, USHORT nStart, USHORT nEnd, USHORT nWhich )
+{
+ TextCharAttrib* pStarting;
+ TextCharAttrib* pEnding;
+ return RemoveAttribs( pNode, nStart, nEnd, pStarting, pEnding, nWhich );
+}
+
+BOOL TextDoc::RemoveAttribs( TextNode* pNode, USHORT nStart, USHORT nEnd, TextCharAttrib*& rpStarting, TextCharAttrib*& rpEnding, USHORT nWhich )
+{
+ DBG_ASSERT( pNode, "Wohin mit dem Attribut?" );
+ DBG_ASSERT( nEnd <= pNode->Len(), "InsertAttrib: Attribut zu gross!" );
+
+ // dieses endet am Anfang der Selektion => kann erweitert werden
+ rpEnding = 0;
+ // dieses startet am Ende der Selektion => kann erweitert werden
+ rpStarting = 0;
+
+ BOOL bChanged = FALSE;
+
+ DBG_ASSERT( nStart <= nEnd, "Kleiner Rechenfehler in InsertAttribInSelection" );
+
+ // ueber die Attribute iterieren...
+ USHORT nAttr = 0;
+ TextCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttr )
+ {
+ BOOL bRemoveAttrib = FALSE;
+ if ( !nWhich || ( pAttr->Which() == nWhich ) )
+ {
+ // Attribut beginnt in Selection
+ if ( ( pAttr->GetStart() >= nStart ) && ( pAttr->GetStart() <= nEnd ) )
+ {
+ bChanged = TRUE;
+ if ( pAttr->GetEnd() > nEnd )
+ {
+ pAttr->GetStart() = nEnd; // dann faengt es dahinter an
+ rpStarting = pAttr;
+ break; // es kann kein weiteres Attrib hier liegen
+ }
+ else if ( !pAttr->IsFeature() || ( pAttr->GetStart() == nStart ) )
+ {
+ // Feature nur loeschen, wenn genau an der Stelle
+ bRemoveAttrib = TRUE;
+ }
+ }
+
+ // Attribut endet in Selection
+ else if ( ( pAttr->GetEnd() >= nStart ) && ( pAttr->GetEnd() <= nEnd ) )
+ {
+ bChanged = TRUE;
+ if ( ( pAttr->GetStart() < nStart ) && !pAttr->IsFeature() )
+ {
+ pAttr->GetEnd() = nStart; // dann hoert es hier auf
+ rpEnding = pAttr;
+ }
+ else if ( !pAttr->IsFeature() || ( pAttr->GetStart() == nStart ) )
+ {
+ // Feature nur loeschen, wenn genau an der Stelle
+ bRemoveAttrib = TRUE;
+ }
+ }
+ // Attribut ueberlappt die Selektion
+ else if ( ( pAttr->GetStart() <= nStart ) && ( pAttr->GetEnd() >= nEnd ) )
+ {
+ bChanged = TRUE;
+ if ( pAttr->GetStart() == nStart )
+ {
+ pAttr->GetStart() = nEnd;
+ rpStarting = pAttr;
+ break; // es kann weitere Attribute geben!
+ }
+ else if ( pAttr->GetEnd() == nEnd )
+ {
+ pAttr->GetEnd() = nStart;
+ rpEnding = pAttr;
+ break; // es kann weitere Attribute geben!
+ }
+ else // Attribut muss gesplittet werden...
+ {
+ USHORT nOldEnd = pAttr->GetEnd();
+ pAttr->GetEnd() = nStart;
+ rpEnding = pAttr;
+// ULONG nSavePos = pNode->GetCharAttribs().GetStartList().GetCurPos();
+ InsertAttrib( *pAttr->GetItem(), pNode, nEnd, nOldEnd );
+// pNode->GetCharAttribs().GetStartList().Seek( nSavePos );
+ break; // es kann weitere Attribute geben!
+ }
+ }
+ }
+ if ( bRemoveAttrib )
+ {
+ DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), "Loeschen und behalten des gleichen Attributs ?" );
+ pNode->GetCharAttribs().GetAttribs().Remove(nAttr);
+ pCurPool->Remove( *pAttr->GetItem() );
+ delete pAttr;
+ nAttr--;
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ return bChanged;
+}
+
+#pragma SEG_FUNCDEF(editdoc_3f)
+
+void TextDoc::InsertAttrib( const SfxPoolItem& rPoolItem, TextNode* pNode, USHORT nStart, USHORT nEnd )
+{
+ // Diese Methode prueft nicht mehr, ob ein entspr. Attribut
+ // schon an der Stelle existiert!
+
+ // pruefen, ob neues Attrib oder einfach nur Ende eines Attribs...
+// const SfxPoolItem& rDefItem = pNode->GetContentAttribs().GetItem( rPoolItem.Which() );
+// BOOL bCreateAttrib = ( rDefItem != rPoolItem );
+
+ // Durch den Verlust der Exclude-Liste geht es nicht mehr, dass ich
+ // kein neues Attribut benoetige und nur das alte nicht expandiere...
+// if ( !bCreateAttrib )
+ {
+ // => Wenn schon Default-Item, dann wenigstens nur dann einstellen,
+ // wenn davor wirklich ein entsprechendes Attribut.
+// if ( pNode->GetCharAttribs().FindAttrib( rPoolItem.Which(), nStart ) )
+// bCreateAttrib = TRUE;
+ // Aber kleiner Trost:
+ // Die wenigsten schreiben, aendern das Attr, schreiben, und
+ // stellen dann wieder das Default-Attr ein.
+ }
+
+ // 22.9.95:
+ // Die Uberlegung, einfach das andere Attribut nicht zu expandieren, war
+ // sowieso falsch, da das DefAttr aus einer Vorlage kommen kann,
+ // die irgendwann verschwindet!
+// if ( bCreateAttrib )
+// {
+ TextCharAttrib* pAttrib = MakeCharAttrib( *pCurPool, rPoolItem, nStart, nEnd );
+ DBG_ASSERT( pAttrib, "MakeCharAttrib fehlgeschlagen!" );
+ pNode->GetCharAttribs().InsertAttrib( pAttrib );
+// }
+// else
+// {
+// TextCharAttrib* pTmpAttrib =
+// pNode->GetCharAttribs().FindAnyAttrib( rPoolItem.Which() );
+// if ( pTmpAttrib ) // sonst benoetige ich es sowieso nicht....
+// {
+// aExcludeList.Insert( pTmpAttrib->GetItem() );
+// }
+// }
+}
+
+#pragma SEG_FUNCDEF(editdoc_40)
+
+void TextDoc::InsertAttrib( TextNode* pNode, USHORT nStart, USHORT nEnd, const SfxPoolItem& rPoolItem )
+{
+ if ( nStart != nEnd )
+ {
+ InsertAttribInSelection( pNode, nStart, nEnd, rPoolItem );
+ }
+ else
+ {
+ // Pruefen, ob schon ein neues Attribut mit der WhichId an der Stelle:
+ TextCharAttrib* pAttr = pNode->GetCharAttribs().FindEmptyAttrib( rPoolItem.Which(), nStart );
+ if ( pAttr )
+ {
+ // Attribut entfernen....
+ pNode->GetCharAttribs().GetAttribs().Remove(
+ pNode->GetCharAttribs().GetAttribs().GetPos( pAttr ) );
+ }
+
+ // pruefen, ob ein 'gleiches' Attribut an der Stelle liegt.
+ pAttr = pNode->GetCharAttribs().FindAttrib( rPoolItem.Which(), nStart );
+ if ( pAttr )
+ {
+ if ( pAttr->IsInside( nStart ) ) // splitten
+ {
+ // ???????????????????????????????
+ // eigentlich noch pruefen, ob wirklich splittet, oder return !
+ // ???????????????????????????????
+ USHORT nOldEnd = pAttr->GetEnd();
+ pAttr->GetEnd() = nStart;
+ pAttr = MakeCharAttrib( *pCurPool, *(pAttr->GetItem()), nStart, nOldEnd );
+ pNode->GetCharAttribs().InsertAttrib( pAttr );
+ }
+ else if ( pAttr->GetEnd() == nStart )
+ {
+ DBG_ASSERT( !pAttr->IsEmpty(), "Doch noch ein leeres Attribut?" );
+ // pruefen, ob genau das gleiche Attribut
+ if ( *(pAttr->GetItem()) == rPoolItem )
+ return;
+ }
+ }
+ InsertAttrib( rPoolItem, pNode, nStart, nStart );
+ }
+}
+
+#pragma SEG_FUNCDEF(editdoc_41)
+
+void TextDoc::FindAttribs( TextNode* pNode, USHORT nStartPos, USHORT nEndPos, SfxItemSet& rCurSet )
+{
+ DBG_ASSERT( pNode, "Wo soll ich suchen ?" );
+ DBG_ASSERT( nStartPos <= nEndPos, "Ungueltiger Bereich!" );
+
+ USHORT nAttr = 0;
+ TextCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ // keine Selection...
+ if ( nStartPos == nEndPos )
+ {
+ while ( pAttr && ( pAttr->GetStart() <= nEndPos) )
+ {
+ const SfxPoolItem* pItem = 0;
+ // Attribut liegt dadrueber...
+ if ( ( pAttr->GetStart() < nStartPos ) && ( pAttr->GetEnd() > nStartPos ) )
+ pItem = pAttr->GetItem();
+ // Attribut endet hier, ist nicht leer
+ else if ( ( pAttr->GetStart() < nStartPos ) && ( pAttr->GetEnd() == nStartPos ) )
+ {
+ if ( !pNode->GetCharAttribs().FindEmptyAttrib( pAttr->GetItem()->Which(), nStartPos ) )
+ pItem = pAttr->GetItem();
+ }
+ // Attribut endet hier, ist leer
+ else if ( ( pAttr->GetStart() == nStartPos ) && ( pAttr->GetEnd() == nStartPos ) )
+ {
+// if ( aExcludeList.FindAttrib( pAttr->GetItem()->Which() ) )
+ pItem = pAttr->GetItem();
+// else if ( pNode->Len() == 0 ) // Sonderfall
+// pItem = pAttr->GetItem();
+ }
+ // Attribut beginnt hier
+ else if ( ( pAttr->GetStart() == nStartPos ) && ( pAttr->GetEnd() > nStartPos ) )
+ {
+ if ( nStartPos == 0 ) // Sonderfall
+ pItem = pAttr->GetItem();
+ }
+
+ if ( pItem )
+ {
+ USHORT nWhich = pItem->Which();
+ if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
+ {
+ rCurSet.Put( *pItem );
+ }
+ else if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = rCurSet.Get( nWhich );
+ if ( rItem != *pItem )
+ {
+ rCurSet.InvalidateItem( nWhich );
+ }
+ }
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ }
+ else // Selektion
+ {
+ while ( pAttr && ( pAttr->GetStart() < nEndPos) )
+ {
+ const SfxPoolItem* pItem = 0;
+ // Attribut liegt dadrueber...
+ if ( ( pAttr->GetStart() <= nStartPos ) && ( pAttr->GetEnd() >= nEndPos ) )
+ pItem = pAttr->GetItem();
+ // Attribut startet mitten drin...
+ else if ( pAttr->GetStart() >= nStartPos )
+ {
+ // !!! pItem = pAttr->GetItem();
+ // einfach nur pItem reicht nicht, da ich z.B. bei Shadow
+ // niemals ein ungleiches Item finden wuerde, da ein solche
+ // seine Anwesenheit durch Abwesenheit repraesentiert!
+ // if ( ... )
+ // Es muesste geprueft werden, on genau das gleiche Attribut
+ // an der Bruchstelle aufsetzt, was recht aufwendig ist.
+ // Da ich beim Einfuegen von Attributen aber etwas optimiere
+ // tritt der Fall nicht so schnell auf...
+ // Also aus Geschwindigkeitsgruenden:
+ rCurSet.InvalidateItem( pAttr->GetItem()->Which() );
+
+ }
+ // Attribut endet mitten drin...
+ else if ( pAttr->GetEnd() > nStartPos )
+ {
+ // pItem = pAttr->GetItem();
+ // s.o.
+
+ // -----------------31.05.95 16:01-------------------
+ // Ist falsch, wenn das gleiche Attribut sofort wieder
+ // eingestellt wird!
+ // => Sollte am besten nicht vorkommen, also gleich beim
+ // Setzen von Attributen richtig machen!
+ // --------------------------------------------------
+ rCurSet.InvalidateItem( pAttr->GetItem()->Which() );
+ }
+
+ if ( pItem )
+ {
+ USHORT nWhich = pItem->Which();
+ if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
+ {
+ rCurSet.Put( *pItem );
+ }
+ else if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = rCurSet.Get( nWhich );
+ if ( rItem != *pItem )
+ {
+ rCurSet.InvalidateItem( nWhich );
+ }
+ }
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ }
+}
+
+
+*/
+
+
diff --git a/svtools/source/edit/textdoc.hxx b/svtools/source/edit/textdoc.hxx
new file mode 100644
index 000000000000..0c875b4fe07f
--- /dev/null
+++ b/svtools/source/edit/textdoc.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 _TEXTDOC_HXX
+#define _TEXTDOC_HXX
+
+#include <svl/svarray.hxx>
+#include <svtools/textdata.hxx>
+#include <txtattr.hxx>
+
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include <tools/list.hxx>
+
+typedef TextCharAttrib* TextCharAttribPtr;
+SV_DECL_PTRARR_DEL( TextCharAttribs, TextCharAttribPtr, 0, 4 )
+
+class TextCharAttribList : private TextCharAttribs
+{
+private:
+ BOOL mbHasEmptyAttribs;
+
+ TextCharAttribList( const TextCharAttribList& ) : TextCharAttribs() {}
+
+public:
+ TextCharAttribList();
+ ~TextCharAttribList();
+
+ void Clear( BOOL bDestroyAttribs );
+ USHORT Count() const { return TextCharAttribs::Count(); }
+
+ TextCharAttrib* GetAttrib( USHORT n ) const { return TextCharAttribs::GetObject( n ); }
+ void RemoveAttrib( USHORT n ) { TextCharAttribs::Remove( n, 1 ); }
+
+ void InsertAttrib( TextCharAttrib* pAttrib );
+
+ void DeleteEmptyAttribs();
+ void ResortAttribs();
+
+ BOOL HasEmptyAttribs() const { return mbHasEmptyAttribs; }
+ BOOL& HasEmptyAttribs() { return mbHasEmptyAttribs; }
+
+ TextCharAttrib* FindAttrib( USHORT nWhich, USHORT nPos );
+ TextCharAttrib* FindNextAttrib( USHORT nWhich, USHORT nFromPos, USHORT nMaxPos = 0xFFFF ) const;
+ TextCharAttrib* FindEmptyAttrib( USHORT nWhich, USHORT nPos );
+ BOOL HasAttrib( USHORT nWhich ) const;
+ BOOL HasBoundingAttrib( USHORT nBound );
+
+#ifdef DBG_UTIL
+ BOOL DbgCheckAttribs();
+#endif
+};
+
+
+class TextNode
+{
+private:
+ String maText;
+ TextCharAttribList maCharAttribs;
+
+ TextNode( const TextNode& ) {;}
+protected:
+ void ExpandAttribs( USHORT nIndex, USHORT nNewChars );
+ void CollapsAttribs( USHORT nIndex, USHORT nDelChars );
+
+public:
+ TextNode( const String& rText );
+
+
+ const String& GetText() const { return maText; }
+
+ const TextCharAttribList& GetCharAttribs() const { return maCharAttribs; }
+ TextCharAttribList& GetCharAttribs() { return maCharAttribs; }
+
+ void InsertText( USHORT nPos, const String& rText );
+ void InsertText( USHORT nPos, sal_Unicode c );
+ void RemoveText( USHORT nPos, USHORT nChars );
+
+ TextNode* Split( USHORT nPos, BOOL bKeepEndigAttribs );
+ void Append( const TextNode& rNode );
+};
+
+class TextDoc
+{
+private:
+ ToolsList<TextNode*> maTextNodes;
+ USHORT mnLeftMargin;
+
+protected:
+ void DestroyTextNodes();
+
+public:
+ TextDoc();
+ ~TextDoc();
+
+ void Clear();
+
+ ToolsList<TextNode*>& GetNodes() { return maTextNodes; }
+ const ToolsList<TextNode*>& GetNodes() const { return maTextNodes; }
+
+ TextPaM RemoveChars( const TextPaM& rPaM, USHORT nChars );
+ TextPaM InsertText( const TextPaM& rPaM, sal_Unicode c );
+ TextPaM InsertText( const TextPaM& rPaM, const String& rStr );
+
+ TextPaM InsertParaBreak( const TextPaM& rPaM, BOOL bKeepEndingAttribs );
+ TextPaM ConnectParagraphs( TextNode* pLeft, TextNode* pRight );
+
+ ULONG GetTextLen( const sal_Unicode* pSep, const TextSelection* pSel = NULL ) const;
+ String GetText( const sal_Unicode* pSep ) const;
+ String GetText( ULONG nPara ) const;
+
+ void SetLeftMargin( USHORT n ) { mnLeftMargin = n; }
+ USHORT GetLeftMargin() const { return mnLeftMargin; }
+
+// BOOL RemoveAttribs( TextNode* pNode, USHORT nStart, USHORT nEnd ), USHORT nWhich = 0 );
+// BOOL RemoveAttribs( TextNode* pNode, USHORT nStart, USHORT nEnd, TextCharAttrib*& rpStarting, TextCharAttrib*& rpEnding, USHORT nWhich = 0 );
+// void InsertAttrib( const EditCharAttrib* pAttr );
+// void InsertAttribInSelection( const EditCharAttrib* pAttr );
+// void FindAttribs( TextNode* pNode, USHORT nStartPos, USHORT nEndPos, SfxItemSet& rCurSet );
+
+ BOOL IsValidPaM( const TextPaM& rPaM );
+};
+
+#endif // _TEXTDOC_HXX
diff --git a/svtools/source/edit/texteng.cxx b/svtools/source/edit/texteng.cxx
new file mode 100644
index 000000000000..e0e136089d78
--- /dev/null
+++ b/svtools/source/edit/texteng.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_svtools.hxx"
+
+
+#include <tools/stream.hxx>
+
+#include <svtools/texteng.hxx>
+#include <svtools/textview.hxx>
+#include <textdoc.hxx>
+#include <textdat2.hxx>
+#include <textundo.hxx>
+#include <textund2.hxx>
+#include <svl/ctloptions.hxx>
+#include <vcl/window.hxx>
+
+#include <vcl/edit.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+
+#ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_CHARACTERITERATORMODE_HPP_
+#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
+#include <com/sun/star/i18n/WordType.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_I18N_XEXTENDEDINPUTSEQUENCECHECKER_HDL_
+#include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
+#endif
+#include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/unohelp.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/unohelp.hxx>
+#include <vcl/metric.hxx>
+
+#include <unicode/ubidi.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+
+typedef TextView* TextViewPtr;
+SV_DECL_PTRARR( TextViews, TextViewPtr, 0, 1 )
+// SV_IMPL_PTRARR( TextViews, TextViewPtr );
+
+SV_DECL_VARARR_SORT( TESortedPositions, ULONG, 16, 8 )
+SV_IMPL_VARARR_SORT( TESortedPositions, ULONG )
+
+#define RESDIFF 10
+#define SCRLRANGE 20 // 1/20 der Breite/Hoehe scrollen, wenn im QueryDrop
+
+
+ // -------------------------------------------------------------------------
+// (-) class TextEngine
+// -------------------------------------------------------------------------
+TextEngine::TextEngine()
+{
+ mpDoc = 0;
+ mpTEParaPortions = 0;
+
+ mpViews = new TextViews;
+ mpActiveView = NULL;
+
+ mbIsFormatting = FALSE;
+ mbFormatted = FALSE;
+ mbUpdate = TRUE;
+ mbModified = FALSE;
+ mbUndoEnabled = FALSE;
+ mbIsInUndo = FALSE;
+ mbDowning = FALSE;
+ mbRightToLeft = FALSE;
+ mbHasMultiLineParas = FALSE;
+
+ meAlign = TXTALIGN_LEFT;
+
+ mnMaxTextWidth = 0;
+ mnMaxTextLen = 0;
+ mnCurTextWidth = 0xFFFFFFFF;
+ mnCurTextHeight = 0;
+
+ mpUndoManager = NULL;
+ mpIMEInfos = NULL;
+ mpLocaleDataWrapper = NULL;
+
+ mpIdleFormatter = new IdleFormatter;
+ mpIdleFormatter->SetTimeoutHdl( LINK( this, TextEngine, IdleFormatHdl ) );
+
+ mpRefDev = new VirtualDevice;
+
+ ImpInitLayoutMode( mpRefDev );
+
+ ImpInitDoc();
+
+ maTextColor = COL_BLACK;
+ Font aFont;
+ aFont.SetTransparent( FALSE );
+ Color aFillColor( aFont.GetFillColor() );
+ aFillColor.SetTransparency( 0 );
+ aFont.SetFillColor( aFillColor );
+ SetFont( aFont );
+}
+
+TextEngine::~TextEngine()
+{
+ mbDowning = TRUE;
+
+ delete mpIdleFormatter;
+ delete mpDoc;
+ delete mpTEParaPortions;
+ delete mpViews; // nur die Liste, nicht die Vies
+ delete mpRefDev;
+ delete mpUndoManager;
+ delete mpIMEInfos;
+ delete mpLocaleDataWrapper;
+}
+
+void TextEngine::InsertView( TextView* pTextView )
+{
+ mpViews->Insert( pTextView, mpViews->Count() );
+ pTextView->SetSelection( TextSelection() );
+
+ if ( !GetActiveView() )
+ SetActiveView( pTextView );
+}
+
+void TextEngine::RemoveView( TextView* pTextView )
+{
+ USHORT nPos = mpViews->GetPos( pTextView );
+ if( nPos != USHRT_MAX )
+ {
+ pTextView->HideCursor();
+ mpViews->Remove( nPos, 1 );
+ if ( pTextView == GetActiveView() )
+ SetActiveView( 0 );
+ }
+}
+
+USHORT TextEngine::GetViewCount() const
+{
+ return mpViews->Count();
+}
+
+TextView* TextEngine::GetView( USHORT nView ) const
+{
+ return mpViews->GetObject( nView );
+}
+
+TextView* TextEngine::GetActiveView() const
+{
+ return mpActiveView;
+}
+
+void TextEngine::SetActiveView( TextView* pTextView )
+{
+ if ( pTextView != mpActiveView )
+ {
+ if ( mpActiveView )
+ mpActiveView->HideSelection();
+
+ mpActiveView = pTextView;
+
+ if ( mpActiveView )
+ mpActiveView->ShowSelection();
+ }
+}
+
+void TextEngine::SetFont( const Font& rFont )
+{
+ if ( rFont != maFont )
+ {
+ maFont = rFont;
+ // #i40221# As the font's color now defaults to transparent (since i35764)
+ // we have to choose a useful textcolor in this case.
+ // Otherwise maTextColor and maFont.GetColor() are both transparent....
+ if( rFont.GetColor() == COL_TRANSPARENT )
+ maTextColor = COL_BLACK;
+ else
+ maTextColor = rFont.GetColor();
+
+ // Wegen Selektion keinen Transparenten Font zulassen...
+ // (Sonst spaeter in ImplPaint den Hintergrund anders loeschen...)
+ maFont.SetTransparent( FALSE );
+ // Tell VCL not to use the font color, use text color from OutputDevice
+ maFont.SetColor( COL_TRANSPARENT );
+ Color aFillColor( maFont.GetFillColor() );
+ aFillColor.SetTransparency( 0 );
+ maFont.SetFillColor( aFillColor );
+
+ maFont.SetAlign( ALIGN_TOP );
+ mpRefDev->SetFont( maFont);
+ Size aTextSize;
+ aTextSize.Width() = mpRefDev->GetTextWidth( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( " " ) ) );
+ aTextSize.Height() = mpRefDev->GetTextHeight();
+ if ( !aTextSize.Width() )
+ aTextSize.Width() = mpRefDev->GetTextWidth( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "XXXX" ) ) );
+
+ mnDefTab = (USHORT)aTextSize.Width();
+ if ( !mnDefTab )
+ mnDefTab = 1;
+ mnCharHeight = (USHORT)aTextSize.Height();
+/*
+ // #93746# Doesn't work with CJK HalfWidth/FullWidth
+ FontMetric aRealFont( mpRefDev->GetFontMetric() );
+ if ( aRealFont.GetPitch() == PITCH_FIXED )
+ {
+ String aX100;
+ aX100.Fill( 100, 'X' );
+ mnFixCharWidth100 = (USHORT)mpRefDev->GetTextWidth( aX100 );
+ }
+ else
+*/
+ mnFixCharWidth100 = 0;
+
+ FormatFullDoc();
+ UpdateViews();
+
+ for ( USHORT nView = mpViews->Count(); nView; )
+ {
+ TextView* pView = mpViews->GetObject( --nView );
+ pView->GetWindow()->SetInputContext( InputContext( GetFont(), !pView->IsReadOnly() ? INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT : 0 ) );
+ }
+ }
+}
+
+void TextEngine::SetDefTab( USHORT nDefTab )
+{
+ mnDefTab = nDefTab;
+ // evtl neu setzen?
+}
+
+void TextEngine::SetMaxTextLen( ULONG nLen )
+{
+ mnMaxTextLen = nLen;
+}
+
+void TextEngine::SetMaxTextWidth( ULONG nMaxWidth )
+{
+ if ( nMaxWidth != mnMaxTextWidth )
+ {
+ mnMaxTextWidth = Min( nMaxWidth, (ULONG)0x7FFFFFFF );
+ FormatFullDoc();
+ UpdateViews();
+ }
+}
+
+static sal_Unicode static_aLFText[] = { '\n', 0 };
+static sal_Unicode static_aCRText[] = { '\r', 0 };
+static sal_Unicode static_aCRLFText[] = { '\r', '\n', 0 };
+
+static inline const sal_Unicode* static_getLineEndText( LineEnd aLineEnd )
+{
+ const sal_Unicode* pRet = NULL;
+
+ switch( aLineEnd )
+ {
+ case LINEEND_LF: pRet = static_aLFText;break;
+ case LINEEND_CR: pRet = static_aCRText;break;
+ case LINEEND_CRLF: pRet = static_aCRLFText;break;
+ }
+ return pRet;
+}
+
+void TextEngine::ReplaceText(const TextSelection& rSel, const String& rText)
+{
+ ImpInsertText( rSel, rText );
+}
+
+String TextEngine::GetText( LineEnd aSeparator ) const
+{
+ return mpDoc->GetText( static_getLineEndText( aSeparator ) );
+}
+
+String TextEngine::GetTextLines( LineEnd aSeparator ) const
+{
+ String aText;
+ ULONG nParas = mpTEParaPortions->Count();
+ const sal_Unicode* pSep = static_getLineEndText( aSeparator );
+ for ( ULONG nP = 0; nP < nParas; nP++ )
+ {
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nP );
+
+ USHORT nLines = pTEParaPortion->GetLines().Count();
+ for ( USHORT nL = 0; nL < nLines; nL++ )
+ {
+ TextLine* pLine = pTEParaPortion->GetLines()[nL];
+ aText += pTEParaPortion->GetNode()->GetText().Copy( pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
+ if ( pSep && ( ( (nP+1) < nParas ) || ( (nL+1) < nLines ) ) )
+ aText += pSep;
+ }
+ }
+ return aText;
+}
+
+String TextEngine::GetText( ULONG nPara ) const
+{
+ return mpDoc->GetText( nPara );
+}
+
+ULONG TextEngine::GetTextLen( LineEnd aSeparator ) const
+{
+ return mpDoc->GetTextLen( static_getLineEndText( aSeparator ) );
+}
+
+ULONG TextEngine::GetTextLen( const TextSelection& rSel, LineEnd aSeparator ) const
+{
+ TextSelection aSel( rSel );
+ aSel.Justify();
+ ValidateSelection( aSel );
+ return mpDoc->GetTextLen( static_getLineEndText( aSeparator ), &aSel );
+}
+
+USHORT TextEngine::GetTextLen( ULONG nPara ) const
+{
+ return mpDoc->GetNodes().GetObject( nPara )->GetText().Len();
+}
+
+void TextEngine::SetUpdateMode( BOOL bUpdate )
+{
+ if ( bUpdate != mbUpdate )
+ {
+ mbUpdate = bUpdate;
+ if ( mbUpdate )
+ {
+ FormatAndUpdate( GetActiveView() );
+ if ( GetActiveView() )
+ GetActiveView()->ShowCursor();
+ }
+ }
+}
+
+BOOL TextEngine::DoesKeyMoveCursor( const KeyEvent& rKeyEvent )
+{
+ BOOL bDoesMove = FALSE;
+
+ switch ( rKeyEvent.GetKeyCode().GetCode() )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_HOME:
+ case KEY_END:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod2() )
+ bDoesMove = TRUE;
+ }
+ break;
+ }
+ return bDoesMove;
+}
+
+BOOL TextEngine::DoesKeyChangeText( const KeyEvent& rKeyEvent )
+{
+ BOOL bDoesChange = FALSE;
+
+ KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_UNDO:
+ case KEYFUNC_REDO:
+ case KEYFUNC_CUT:
+ case KEYFUNC_PASTE: bDoesChange = TRUE;
+ break;
+ default: // wird dann evtl. unten bearbeitet.
+ eFunc = KEYFUNC_DONTKNOW;
+ }
+ }
+ if ( eFunc == KEYFUNC_DONTKNOW )
+ {
+ switch ( rKeyEvent.GetKeyCode().GetCode() )
+ {
+ case KEY_DELETE:
+ case KEY_BACKSPACE:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod2() )
+ bDoesChange = TRUE;
+ }
+ break;
+ case KEY_RETURN:
+ case KEY_TAB:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() )
+ bDoesChange = TRUE;
+ }
+ break;
+ default:
+ {
+ bDoesChange = TextEngine::IsSimpleCharInput( rKeyEvent );
+ }
+ }
+ }
+ return bDoesChange;
+}
+
+BOOL TextEngine::IsSimpleCharInput( const KeyEvent& rKeyEvent )
+{
+ if( rKeyEvent.GetCharCode() >= 32 && rKeyEvent.GetCharCode() != 127 &&
+ KEY_MOD1 != (rKeyEvent.GetKeyCode().GetModifier() & ~KEY_SHIFT) && // (ssa) #i45714#:
+ KEY_MOD2 != (rKeyEvent.GetKeyCode().GetModifier() & ~KEY_SHIFT) ) // check for Ctrl and Alt separately
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void TextEngine::ImpInitDoc()
+{
+ if ( mpDoc )
+ mpDoc->Clear();
+ else
+ mpDoc = new TextDoc;
+
+ delete mpTEParaPortions;
+ mpTEParaPortions = new TEParaPortions;
+
+ TextNode* pNode = new TextNode( String() );
+ mpDoc->GetNodes().Insert( pNode, 0 );
+
+ TEParaPortion* pIniPortion = new TEParaPortion( pNode );
+ mpTEParaPortions->Insert( pIniPortion, (ULONG)0 );
+
+ mbFormatted = FALSE;
+
+ ImpParagraphRemoved( TEXT_PARA_ALL );
+ ImpParagraphInserted( 0 );
+}
+
+String TextEngine::GetText( const TextSelection& rSel, LineEnd aSeparator ) const
+{
+ String aText;
+
+ if ( !rSel.HasRange() )
+ return aText;
+
+ TextSelection aSel( rSel );
+ aSel.Justify();
+
+ ULONG nStartPara = aSel.GetStart().GetPara();
+ ULONG nEndPara = aSel.GetEnd().GetPara();
+ const sal_Unicode* pSep = static_getLineEndText( aSeparator );
+ for ( ULONG nNode = aSel.GetStart().GetPara(); nNode <= nEndPara; nNode++ )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nNode );
+
+ USHORT nStartPos = 0;
+ USHORT nEndPos = pNode->GetText().Len();
+ if ( nNode == nStartPara )
+ nStartPos = aSel.GetStart().GetIndex();
+ if ( nNode == nEndPara ) // kann auch == nStart sein!
+ nEndPos = aSel.GetEnd().GetIndex();
+
+ aText += pNode->GetText().Copy( nStartPos, nEndPos-nStartPos );
+ if ( nNode < nEndPara )
+ aText += pSep;
+ }
+ return aText;
+}
+
+void TextEngine::ImpRemoveText()
+{
+ ImpInitDoc();
+
+ TextPaM aStartPaM( 0, 0 );
+ TextSelection aEmptySel( aStartPaM, aStartPaM );
+ for ( USHORT nView = 0; nView < mpViews->Count(); nView++ )
+ {
+ TextView* pView = mpViews->GetObject( nView );
+ pView->ImpSetSelection( aEmptySel );
+ }
+ ResetUndo();
+}
+
+void TextEngine::SetText( const XubString& rText )
+{
+ ImpRemoveText();
+
+ BOOL bUndoCurrentlyEnabled = IsUndoEnabled();
+ // Der von Hand reingesteckte Text kann nicht vom Anwender rueckgaengig gemacht werden.
+ EnableUndo( FALSE );
+
+ TextPaM aStartPaM( 0, 0 );
+ TextSelection aEmptySel( aStartPaM, aStartPaM );
+
+ TextPaM aPaM = aStartPaM;
+ if ( rText.Len() )
+ aPaM = ImpInsertText( aEmptySel, rText );
+
+ for ( USHORT nView = 0; nView < mpViews->Count(); nView++ )
+ {
+ TextView* pView = mpViews->GetObject( nView );
+ pView->ImpSetSelection( aEmptySel );
+
+ // Wenn kein Text, dann auch Kein Format&Update
+ // => Der Text bleibt stehen.
+ if ( !rText.Len() && GetUpdateMode() )
+ pView->Invalidate();
+ }
+
+ if( !rText.Len() ) // sonst muss spaeter noch invalidiert werden, !bFormatted reicht.
+ mnCurTextHeight = 0;
+
+ FormatAndUpdate();
+
+ EnableUndo( bUndoCurrentlyEnabled );
+ DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "Undo nach SetText?" );
+}
+
+
+void TextEngine::CursorMoved( ULONG nNode )
+{
+ // Leere Attribute loeschen, aber nur, wenn Absatz nicht leer!
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nNode );
+ if ( pNode && pNode->GetCharAttribs().HasEmptyAttribs() && pNode->GetText().Len() )
+ pNode->GetCharAttribs().DeleteEmptyAttribs();
+}
+
+void TextEngine::ImpRemoveChars( const TextPaM& rPaM, USHORT nChars, SfxUndoAction* )
+{
+ DBG_ASSERT( nChars, "ImpRemoveChars - 0 Chars?!" );
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ // Attribute muessen hier vorm RemoveChars fuer UNDO gesichert werden!
+ TextNode* pNode = mpDoc->GetNodes().GetObject( rPaM.GetPara() );
+ XubString aStr( pNode->GetText().Copy( rPaM.GetIndex(), nChars ) );
+
+ // Pruefen, ob Attribute geloescht oder geaendert werden:
+ USHORT nStart = rPaM.GetIndex();
+ USHORT nEnd = nStart + nChars;
+ for ( USHORT nAttr = pNode->GetCharAttribs().Count(); nAttr; )
+ {
+ TextCharAttrib* pAttr = pNode->GetCharAttribs().GetAttrib( --nAttr );
+ if ( ( pAttr->GetEnd() >= nStart ) && ( pAttr->GetStart() < nEnd ) )
+ {
+// TextSelection aSel( rPaM );
+// aSel.GetEnd().GetIndex() += nChars;
+// TextUndoSetAttribs* pAttrUndo = CreateAttribUndo( aSel );
+// InsertUndo( pAttrUndo );
+ break; // for
+ }
+ }
+// if ( pCurUndo && ( CreateTextPaM( pCurUndo->GetEPaM() ) == rPaM ) )
+// pCurUndo->GetStr() += aStr;
+// else
+ InsertUndo( new TextUndoRemoveChars( this, rPaM, aStr ) );
+ }
+
+ mpDoc->RemoveChars( rPaM, nChars );
+ ImpCharsRemoved( rPaM.GetPara(), rPaM.GetIndex(), nChars );
+}
+
+TextPaM TextEngine::ImpConnectParagraphs( ULONG nLeft, ULONG nRight )
+{
+ DBG_ASSERT( nLeft != nRight, "Den gleichen Absatz zusammenfuegen ?" );
+
+ TextNode* pLeft = mpDoc->GetNodes().GetObject( nLeft );
+ TextNode* pRight = mpDoc->GetNodes().GetObject( nRight );
+
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new TextUndoConnectParas( this, nLeft, pLeft->GetText().Len() ) );
+
+ // Erstmal Portions suchen, da pRight nach ConnectParagraphs weg.
+ TEParaPortion* pLeftPortion = mpTEParaPortions->GetObject( nLeft );
+ TEParaPortion* pRightPortion = mpTEParaPortions->GetObject( nRight );
+ DBG_ASSERT( pLeft && pLeftPortion, "Blinde Portion in ImpConnectParagraphs(1)" );
+ DBG_ASSERT( pRight && pRightPortion, "Blinde Portion in ImpConnectParagraphs(2)" );
+
+ TextPaM aPaM = mpDoc->ConnectParagraphs( pLeft, pRight );
+ ImpParagraphRemoved( nRight );
+
+ pLeftPortion->MarkSelectionInvalid( aPaM.GetIndex(), pLeft->GetText().Len() );
+
+ mpTEParaPortions->Remove( nRight );
+ delete pRightPortion;
+ // der rechte Node wird von EditDoc::ConnectParagraphs() geloescht.
+
+ return aPaM;
+}
+
+TextPaM TextEngine::ImpDeleteText( const TextSelection& rSel )
+{
+ if ( !rSel.HasRange() )
+ return rSel.GetStart();
+
+ TextSelection aSel( rSel );
+ aSel.Justify();
+ TextPaM aStartPaM( aSel.GetStart() );
+ TextPaM aEndPaM( aSel.GetEnd() );
+
+ CursorMoved( aStartPaM.GetPara() ); // nur damit neu eingestellte Attribute verschwinden...
+ CursorMoved( aEndPaM.GetPara() ); // nur damit neu eingestellte Attribute verschwinden...
+
+ DBG_ASSERT( mpDoc->IsValidPaM( aStartPaM ), "Index im Wald in ImpDeleteText" );
+ DBG_ASSERT( mpDoc->IsValidPaM( aEndPaM ), "Index im Wald in ImpDeleteText" );
+
+ ULONG nStartNode = aStartPaM.GetPara();
+ ULONG nEndNode = aEndPaM.GetPara();
+
+ // Alle Nodes dazwischen entfernen....
+ for ( ULONG z = nStartNode+1; z < nEndNode; z++ )
+ {
+ // Immer nStartNode+1, wegen Remove()!
+ ImpRemoveParagraph( nStartNode+1 );
+ }
+
+ if ( nStartNode != nEndNode )
+ {
+ // Den Rest des StartNodes...
+ TextNode* pLeft = mpDoc->GetNodes().GetObject( nStartNode );
+ USHORT nChars = pLeft->GetText().Len() - aStartPaM.GetIndex();
+ if ( nChars )
+ {
+ ImpRemoveChars( aStartPaM, nChars );
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nStartNode );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteText(3)" );
+ pPortion->MarkSelectionInvalid( aStartPaM.GetIndex(), pLeft->GetText().Len() );
+ }
+
+ // Den Anfang des EndNodes....
+ nEndNode = nStartNode+1; // Die anderen Absaetze wurden geloescht
+ nChars = aEndPaM.GetIndex();
+ if ( nChars )
+ {
+ aEndPaM.GetPara() = nEndNode;
+ aEndPaM.GetIndex() = 0;
+ ImpRemoveChars( aEndPaM, nChars );
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nEndNode );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteText(4)" );
+ pPortion->MarkSelectionInvalid( 0, pPortion->GetNode()->GetText().Len() );
+ }
+
+ // Zusammenfuegen....
+ aStartPaM = ImpConnectParagraphs( nStartNode, nEndNode );
+ }
+ else
+ {
+ USHORT nChars;
+ nChars = aEndPaM.GetIndex() - aStartPaM.GetIndex();
+ ImpRemoveChars( aStartPaM, nChars );
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nStartNode );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteText(5)" );
+ pPortion->MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - aEndPaM.GetIndex() );
+ }
+
+// UpdateSelections();
+ TextModified();
+ return aStartPaM;
+}
+
+void TextEngine::ImpRemoveParagraph( ULONG nPara )
+{
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPara );
+
+ // Der Node wird vom Undo verwaltet und ggf. zerstoert!
+ /* delete */ mpDoc->GetNodes().Remove( nPara );
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new TextUndoDelPara( this, pNode, nPara ) );
+ else
+ delete pNode;
+
+ mpTEParaPortions->Remove( nPara );
+ delete pPortion;
+
+ ImpParagraphRemoved( nPara );
+}
+
+uno::Reference < i18n::XExtendedInputSequenceChecker > TextEngine::GetInputSequenceChecker() const
+{
+ uno::Reference < i18n::XExtendedInputSequenceChecker > xISC;
+// if ( !xISC.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ uno::Reference< uno::XInterface > xI = xMSF->createInstance( OUString::createFromAscii( "com.sun.star.i18n.InputSequenceChecker" ) );
+ if ( xI.is() )
+ {
+ Any x = xI->queryInterface( ::getCppuType((const uno::Reference< i18n::XExtendedInputSequenceChecker >*)0) );
+ x >>= xISC;
+ }
+ }
+ return xISC;
+}
+
+BOOL TextEngine::IsInputSequenceCheckingRequired( sal_Unicode c, const TextSelection& rCurSel ) const
+{
+ uno::Reference< i18n::XBreakIterator > xBI = ((TextEngine *) this)->GetBreakIterator();
+ SvtCTLOptions aCTLOptions;
+
+ // get the index that really is first
+ USHORT nFirstPos = rCurSel.GetStart().GetIndex();
+ USHORT nMaxPos = rCurSel.GetEnd().GetIndex();
+ if (nMaxPos < nFirstPos)
+ nFirstPos = nMaxPos;
+
+ sal_Bool bIsSequenceChecking =
+ aCTLOptions.IsCTLFontEnabled() &&
+ aCTLOptions.IsCTLSequenceChecking() &&
+ nFirstPos != 0 && /* first char needs not to be checked */
+ xBI.is() && i18n::ScriptType::COMPLEX == xBI->getScriptType( rtl::OUString( c ), 0 );
+
+ return bIsSequenceChecking;
+}
+
+TextPaM TextEngine::ImpInsertText( const TextSelection& rCurSel, sal_Unicode c, BOOL bOverwrite )
+{
+ return ImpInsertText( c, rCurSel, bOverwrite, sal_False );
+}
+
+TextPaM TextEngine::ImpInsertText( sal_Unicode c, const TextSelection& rCurSel, BOOL bOverwrite, BOOL bIsUserInput )
+{
+ DBG_ASSERT( c != '\n', "Zeilenumbruch bei InsertText ?" );
+ DBG_ASSERT( c != '\r', "Zeilenumbruch bei InsertText ?" );
+
+ TextPaM aPaM( rCurSel.GetStart() );
+ TextNode* pNode = mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+
+ if ( pNode->GetText().Len() < STRING_MAXLEN )
+ {
+ BOOL bDoOverwrite = ( bOverwrite &&
+ ( aPaM.GetIndex() < pNode->GetText().Len() ) ) ? TRUE : FALSE;
+
+ BOOL bUndoAction = ( rCurSel.HasRange() || bDoOverwrite );
+
+ if ( bUndoAction )
+ UndoActionStart( TEXTUNDO_INSERT );
+
+ if ( rCurSel.HasRange() )
+ {
+ aPaM = ImpDeleteText( rCurSel );
+ }
+ else if ( bDoOverwrite )
+ {
+ // Wenn Selektion, dann kein Zeichen ueberschreiben
+ TextSelection aTmpSel( aPaM );
+ aTmpSel.GetEnd().GetIndex()++;
+ ImpDeleteText( aTmpSel );
+ }
+
+ if (bIsUserInput && IsInputSequenceCheckingRequired( c, rCurSel ))
+ {
+ uno::Reference < i18n::XExtendedInputSequenceChecker > xISC = GetInputSequenceChecker();
+ SvtCTLOptions aCTLOptions;
+
+ if (xISC.is())
+ {
+ xub_StrLen nTmpPos = aPaM.GetIndex();
+ sal_Int16 nCheckMode = aCTLOptions.IsCTLSequenceCheckingRestricted() ?
+ i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
+
+ // the text that needs to be checked is only the one
+ // before the current cursor position
+ rtl::OUString aOldText( mpDoc->GetText( aPaM.GetPara() ).Copy(0, nTmpPos) );
+ rtl::OUString aNewText( aOldText );
+ if (aCTLOptions.IsCTLSequenceCheckingTypeAndReplace())
+ {
+ xISC->correctInputSequence( aNewText, nTmpPos - 1, c, nCheckMode );
+
+ // find position of first character that has changed
+ sal_Int32 nOldLen = aOldText.getLength();
+ sal_Int32 nNewLen = aNewText.getLength();
+ const sal_Unicode *pOldTxt = aOldText.getStr();
+ const sal_Unicode *pNewTxt = aNewText.getStr();
+ sal_Int32 nChgPos = 0;
+ while ( nChgPos < nOldLen && nChgPos < nNewLen &&
+ pOldTxt[nChgPos] == pNewTxt[nChgPos] )
+ ++nChgPos;
+
+ xub_StrLen nChgLen = static_cast< xub_StrLen >(nNewLen - nChgPos);
+ String aChgText( aNewText.copy( nChgPos ), nChgLen );
+
+ // select text from first pos to be changed to current pos
+ TextSelection aSel( TextPaM( aPaM.GetPara(), (USHORT) nChgPos ), aPaM );
+
+ if (aChgText.Len())
+ // ImpInsertText implicitly handles undo...
+ return ImpInsertText( aSel, aChgText );
+ else
+ return aPaM;
+ }
+ else
+ {
+ // should the character be ignored (i.e. not get inserted) ?
+ if (!xISC->checkInputSequence( aOldText, nTmpPos - 1, c, nCheckMode ))
+ return aPaM; // nothing to be done -> no need for undo
+ }
+ }
+
+ // at this point now we will insert the character 'normally' some lines below...
+ }
+
+
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ TextUndoInsertChars* pNewUndo = new TextUndoInsertChars( this, aPaM, c );
+ BOOL bTryMerge = ( !bDoOverwrite && ( c != ' ' ) ) ? TRUE : FALSE;
+ InsertUndo( pNewUndo, bTryMerge );
+ }
+
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( aPaM.GetPara() );
+ pPortion->MarkInvalid( aPaM.GetIndex(), 1 );
+ if ( c == '\t' )
+ pPortion->SetNotSimpleInvalid();
+ aPaM = mpDoc->InsertText( aPaM, c );
+ ImpCharsInserted( aPaM.GetPara(), aPaM.GetIndex()-1, 1 );
+
+ TextModified();
+
+ if ( bUndoAction )
+ UndoActionEnd( TEXTUNDO_INSERT );
+ }
+
+ return aPaM;
+}
+
+
+TextPaM TextEngine::ImpInsertText( const TextSelection& rCurSel, const XubString& rStr )
+{
+ UndoActionStart( TEXTUNDO_INSERT );
+
+ TextPaM aPaM;
+
+ if ( rCurSel.HasRange() )
+ aPaM = ImpDeleteText( rCurSel );
+ else
+ aPaM = rCurSel.GetEnd();
+
+ XubString aText( rStr );
+ aText.ConvertLineEnd( LINEEND_LF );
+
+ USHORT nStart = 0;
+ while ( nStart < aText.Len() )
+ {
+ USHORT nEnd = aText.Search( LINE_SEP, nStart );
+ if ( nEnd == STRING_NOTFOUND )
+ nEnd = aText.Len(); // nicht dereferenzieren!
+
+ // Start == End => Leerzeile
+ if ( nEnd > nStart )
+ {
+ ULONG nL = aPaM.GetIndex();
+ nL += ( nEnd-nStart );
+ if ( nL > STRING_MAXLEN )
+ {
+ USHORT nDiff = (USHORT) (nL-STRING_MAXLEN);
+ nEnd = nEnd - nDiff;
+ }
+
+ XubString aLine( aText, nStart, nEnd-nStart );
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new TextUndoInsertChars( this, aPaM, aLine ) );
+
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( aPaM.GetPara() );
+ pPortion->MarkInvalid( aPaM.GetIndex(), aLine.Len() );
+ if ( aLine.Search( '\t' ) != STRING_NOTFOUND )
+ pPortion->SetNotSimpleInvalid();
+
+ aPaM = mpDoc->InsertText( aPaM, aLine );
+ ImpCharsInserted( aPaM.GetPara(), aPaM.GetIndex()-aLine.Len(), aLine.Len() );
+
+ }
+ if ( nEnd < aText.Len() )
+ aPaM = ImpInsertParaBreak( aPaM );
+
+ nStart = nEnd+1;
+
+ if ( nStart < nEnd ) // #108611# overflow
+ break;
+ }
+
+ UndoActionEnd( TEXTUNDO_INSERT );
+
+ TextModified();
+ return aPaM;
+}
+
+TextPaM TextEngine::ImpInsertParaBreak( const TextSelection& rCurSel, BOOL bKeepEndingAttribs )
+{
+ TextPaM aPaM;
+ if ( rCurSel.HasRange() )
+ aPaM = ImpDeleteText( rCurSel );
+ else
+ aPaM = rCurSel.GetEnd();
+
+ return ImpInsertParaBreak( aPaM, bKeepEndingAttribs );
+}
+
+TextPaM TextEngine::ImpInsertParaBreak( const TextPaM& rPaM, BOOL bKeepEndingAttribs )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new TextUndoSplitPara( this, rPaM.GetPara(), rPaM.GetIndex() ) );
+
+ TextNode* pNode = mpDoc->GetNodes().GetObject( rPaM.GetPara() );
+ BOOL bFirstParaContentChanged = rPaM.GetIndex() < pNode->GetText().Len();
+
+ TextPaM aPaM( mpDoc->InsertParaBreak( rPaM, bKeepEndingAttribs ) );
+
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( rPaM.GetPara() );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpInsertParaBreak" );
+ pPortion->MarkInvalid( rPaM.GetIndex(), 0 );
+
+ TextNode* pNewNode = mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ TEParaPortion* pNewPortion = new TEParaPortion( pNewNode );
+ mpTEParaPortions->Insert( pNewPortion, aPaM.GetPara() );
+ ImpParagraphInserted( aPaM.GetPara() );
+
+ CursorMoved( rPaM.GetPara() ); // falls leeres Attribut entstanden.
+ TextModified();
+
+ if ( bFirstParaContentChanged )
+ Broadcast( TextHint( TEXT_HINT_PARACONTENTCHANGED, rPaM.GetPara() ) );
+
+ return aPaM;
+}
+
+Rectangle TextEngine::PaMtoEditCursor( const TextPaM& rPaM, BOOL bSpecial )
+{
+ DBG_ASSERT( GetUpdateMode(), "Darf bei Update=FALSE nicht erreicht werden: PaMtoEditCursor" );
+
+ Rectangle aEditCursor;
+ long nY = 0;
+
+ if ( !mbHasMultiLineParas )
+ {
+ nY = rPaM.GetPara() * mnCharHeight;
+ }
+ else
+ {
+ for ( ULONG nPortion = 0; nPortion < rPaM.GetPara(); nPortion++ )
+ {
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject(nPortion);
+ nY += pPortion->GetLines().Count() * mnCharHeight;
+ }
+ }
+
+ aEditCursor = GetEditCursor( rPaM, bSpecial );
+ aEditCursor.Top() += nY;
+ aEditCursor.Bottom() += nY;
+ return aEditCursor;
+}
+
+Rectangle TextEngine::GetEditCursor( const TextPaM& rPaM, BOOL bSpecial, BOOL bPreferPortionStart )
+{
+ if ( !IsFormatted() && !IsFormatting() )
+ FormatAndUpdate();
+
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( rPaM.GetPara() );
+ //TextNode* pNode = mpDoc->GetNodes().GetObject( rPaM.GetPara() );
+
+ /*
+ bSpecial: Wenn hinter dem letzten Zeichen einer umgebrochenen Zeile,
+ am Ende der Zeile bleiben, nicht am Anfang der naechsten.
+ Zweck: - END => wirklich hinter das letzte Zeichen
+ - Selektion....
+ bSpecial: If behind the last character of a made up line, stay at the
+ end of the line, not at the start of the next line.
+ Purpose: - really END = > behind the last character
+ - to selection...
+
+ */
+
+ long nY = 0;
+ USHORT nCurIndex = 0;
+ TextLine* pLine = 0;
+ for ( USHORT nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
+ {
+ TextLine* pTmpLine = pPortion->GetLines().GetObject( nLine );
+ if ( ( pTmpLine->GetStart() == rPaM.GetIndex() ) || ( pTmpLine->IsIn( rPaM.GetIndex(), bSpecial ) ) )
+ {
+ pLine = pTmpLine;
+ break;
+ }
+
+ nCurIndex = nCurIndex + pTmpLine->GetLen();
+ nY += mnCharHeight;
+ }
+ if ( !pLine )
+ {
+ // Cursor am Ende des Absatzes.
+ DBG_ASSERT( rPaM.GetIndex() == nCurIndex, "Index voll daneben in GetEditCursor!" );
+
+ pLine = pPortion->GetLines().GetObject( pPortion->GetLines().Count()-1 );
+ nY -= mnCharHeight;
+ nCurIndex = nCurIndex - pLine->GetLen();
+ }
+
+ Rectangle aEditCursor;
+
+ aEditCursor.Top() = nY;
+ nY += mnCharHeight;
+ aEditCursor.Bottom() = nY-1;
+
+ // innerhalb der Zeile suchen....
+ long nX = ImpGetXPos( rPaM.GetPara(), pLine, rPaM.GetIndex(), bPreferPortionStart );
+ aEditCursor.Left() = aEditCursor.Right() = nX;
+ return aEditCursor;
+}
+
+long TextEngine::ImpGetXPos( ULONG nPara, TextLine* pLine, USHORT nIndex, BOOL bPreferPortionStart )
+{
+ DBG_ASSERT( ( nIndex >= pLine->GetStart() ) && ( nIndex <= pLine->GetEnd() ) , "ImpGetXPos muss richtig gerufen werden!" );
+
+ BOOL bDoPreferPortionStart = bPreferPortionStart;
+ // Assure that the portion belongs to this line:
+ if ( nIndex == pLine->GetStart() )
+ bDoPreferPortionStart = TRUE;
+ else if ( nIndex == pLine->GetEnd() )
+ bDoPreferPortionStart = FALSE;
+
+ TEParaPortion* pParaPortion = mpTEParaPortions->GetObject( nPara );
+
+ USHORT nTextPortionStart = 0;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( nIndex, nTextPortionStart, bDoPreferPortionStart );
+
+ DBG_ASSERT( ( nTextPortion >= pLine->GetStartPortion() ) && ( nTextPortion <= pLine->GetEndPortion() ), "GetXPos: Portion not in current line! " );
+
+ TETextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+
+ long nX = ImpGetPortionXOffset( nPara, pLine, nTextPortion );
+
+ long nPortionTextWidth = pPortion->GetWidth();
+
+ if ( nTextPortionStart != nIndex )
+ {
+ // Search within portion...
+ if ( nIndex == ( nTextPortionStart + pPortion->GetLen() ) )
+ {
+ // End of Portion
+ if ( ( pPortion->GetKind() == PORTIONKIND_TAB ) ||
+ ( !IsRightToLeft() && !pPortion->IsRightToLeft() ) ||
+ ( IsRightToLeft() && pPortion->IsRightToLeft() ) )
+ {
+ nX += nPortionTextWidth;
+ if ( ( pPortion->GetKind() == PORTIONKIND_TAB ) && ( (nTextPortion+1) < pParaPortion->GetTextPortions().Count() ) )
+ {
+ TETextPortion* pNextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion+1 );
+ if ( ( pNextPortion->GetKind() != PORTIONKIND_TAB ) && (
+ ( !IsRightToLeft() && pNextPortion->IsRightToLeft() ) ||
+ ( IsRightToLeft() && !pNextPortion->IsRightToLeft() ) ) )
+ {
+// nX += pNextPortion->GetWidth();
+ // End of the tab portion, use start of next for cursor pos
+ DBG_ASSERT( !bPreferPortionStart, "ImpGetXPos - How can we this tab portion here???" );
+ nX = ImpGetXPos( nPara, pLine, nIndex, TRUE );
+ }
+
+ }
+ }
+ }
+ else if ( pPortion->GetKind() == PORTIONKIND_TEXT )
+ {
+ DBG_ASSERT( nIndex != pLine->GetStart(), "Strange behavior in new ImpGetXPos()" );
+
+ long nPosInPortion = (long)CalcTextWidth( nPara, nTextPortionStart, nIndex-nTextPortionStart );
+
+ if ( ( !IsRightToLeft() && !pPortion->IsRightToLeft() ) ||
+ ( IsRightToLeft() && pPortion->IsRightToLeft() ) )
+ {
+ nX += nPosInPortion;
+ }
+ else
+ {
+ nX += nPortionTextWidth - nPosInPortion;
+ }
+ }
+ }
+ else // if ( nIndex == pLine->GetStart() )
+ {
+ if ( ( pPortion->GetKind() != PORTIONKIND_TAB ) &&
+ ( ( !IsRightToLeft() && pPortion->IsRightToLeft() ) ||
+ ( IsRightToLeft() && !pPortion->IsRightToLeft() ) ) )
+ {
+ nX += nPortionTextWidth;
+ }
+ }
+
+ return nX;
+}
+
+const TextAttrib* TextEngine::FindAttrib( const TextPaM& rPaM, USHORT nWhich ) const
+{
+ const TextAttrib* pAttr = NULL;
+ const TextCharAttrib* pCharAttr = FindCharAttrib( rPaM, nWhich );
+ if ( pCharAttr )
+ pAttr = &pCharAttr->GetAttr();
+ return pAttr;
+}
+
+const TextCharAttrib* TextEngine::FindCharAttrib( const TextPaM& rPaM, USHORT nWhich ) const
+{
+ const TextCharAttrib* pAttr = NULL;
+ TextNode* pNode = mpDoc->GetNodes().GetObject( rPaM.GetPara() );
+ if ( pNode && ( rPaM.GetIndex() < pNode->GetText().Len() ) )
+ pAttr = pNode->GetCharAttribs().FindAttrib( nWhich, rPaM.GetIndex() );
+ return pAttr;
+}
+
+BOOL TextEngine::HasAttrib( USHORT nWhich ) const
+{
+ BOOL bAttr = FALSE;
+ for ( ULONG n = mpDoc->GetNodes().Count(); --n && !bAttr; )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( n );
+ bAttr = pNode->GetCharAttribs().HasAttrib( nWhich );
+ }
+ return bAttr;
+}
+
+TextPaM TextEngine::GetPaM( const Point& rDocPos, BOOL bSmart )
+{
+ DBG_ASSERT( GetUpdateMode(), "Darf bei Update=FALSE nicht erreicht werden: GetPaM" );
+
+ long nY = 0;
+ for ( ULONG nPortion = 0; nPortion < mpTEParaPortions->Count(); nPortion++ )
+ {
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPortion );
+ long nTmpHeight = pPortion->GetLines().Count() * mnCharHeight;
+ nY += nTmpHeight;
+ if ( nY > rDocPos.Y() )
+ {
+ nY -= nTmpHeight;
+ Point aPosInPara( rDocPos );
+ aPosInPara.Y() -= nY;
+
+ TextPaM aPaM( nPortion, 0 );
+ aPaM.GetIndex() = ImpFindIndex( nPortion, aPosInPara, bSmart );
+ return aPaM;
+ }
+ }
+
+ // Nicht gefunden - Dann den letzten sichtbare...
+ ULONG nLastNode = mpDoc->GetNodes().Count() - 1;
+ TextNode* pLast = mpDoc->GetNodes().GetObject( nLastNode );
+ return TextPaM( nLastNode, pLast->GetText().Len() );
+}
+
+USHORT TextEngine::ImpFindIndex( ULONG nPortion, const Point& rPosInPara, BOOL bSmart )
+{
+ DBG_ASSERT( IsFormatted(), "GetPaM: Nicht formatiert" );
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPortion );
+
+ USHORT nCurIndex = 0;
+
+ long nY = 0;
+ TextLine* pLine = 0;
+ USHORT nLine;
+ for ( nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
+ {
+ TextLine* pTmpLine = pPortion->GetLines().GetObject( nLine );
+ nY += mnCharHeight;
+ if ( nY > rPosInPara.Y() ) // das war 'se
+ {
+ pLine = pTmpLine;
+ break; // richtige Y-Position intressiert nicht
+ }
+ }
+ DBG_ASSERT( pLine, "ImpFindIndex: pLine ?" );
+
+ nCurIndex = GetCharPos( nPortion, nLine, rPosInPara.X(), bSmart );
+
+ if ( nCurIndex && ( nCurIndex == pLine->GetEnd() ) &&
+ ( pLine != pPortion->GetLines().GetObject( pPortion->GetLines().Count()-1) ) )
+ {
+ uno::Reference < i18n::XBreakIterator > xBI = GetBreakIterator();
+ sal_Int32 nCount = 1;
+ nCurIndex = (USHORT)xBI->previousCharacters( pPortion->GetNode()->GetText(), nCurIndex, GetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
+ }
+ return nCurIndex;
+}
+
+USHORT TextEngine::GetCharPos( ULONG nPortion, USHORT nLine, long nXPos, BOOL )
+{
+
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPortion );
+ TextLine* pLine = pPortion->GetLines().GetObject( nLine );
+
+ USHORT nCurIndex = pLine->GetStart();
+
+ long nTmpX = pLine->GetStartX();
+ if ( nXPos <= nTmpX )
+ return nCurIndex;
+
+ for ( USHORT i = pLine->GetStartPortion(); i <= pLine->GetEndPortion(); i++ )
+ {
+ TETextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( i );
+ nTmpX += pTextPortion->GetWidth();
+
+ if ( nTmpX > nXPos )
+ {
+ if( pTextPortion->GetLen() > 1 )
+ {
+ nTmpX -= pTextPortion->GetWidth(); // vor die Portion stellen
+ // Optimieren: Kein GetTextBreak, wenn feste Fontbreite...
+ Font aFont;
+ SeekCursor( nPortion, nCurIndex+1, aFont, NULL );
+ mpRefDev->SetFont( aFont);
+ long nPosInPortion = nXPos-nTmpX;
+ if ( IsRightToLeft() != pTextPortion->IsRightToLeft() )
+ nPosInPortion = pTextPortion->GetWidth() - nPosInPortion;
+ nCurIndex = mpRefDev->GetTextBreak( pPortion->GetNode()->GetText(), nPosInPortion, nCurIndex );
+ // MT: GetTextBreak should assure that we are not withing a CTL cell...
+ }
+ return nCurIndex;
+ }
+ nCurIndex = nCurIndex + pTextPortion->GetLen();
+ }
+ return nCurIndex;
+}
+
+
+ULONG TextEngine::GetTextHeight() const
+{
+ DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=FALSE nicht verwendet werden: GetTextHeight" );
+
+ if ( !IsFormatted() && !IsFormatting() )
+ ((TextEngine*)this)->FormatAndUpdate();
+
+ return mnCurTextHeight;
+}
+
+ULONG TextEngine::GetTextHeight( ULONG nParagraph ) const
+{
+ DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=FALSE nicht verwendet werden: GetTextHeight" );
+
+ if ( !IsFormatted() && !IsFormatting() )
+ ((TextEngine*)this)->FormatAndUpdate();
+
+ return CalcParaHeight( nParagraph );
+}
+
+ULONG TextEngine::CalcTextWidth( ULONG nPara )
+{
+ ULONG nParaWidth = 0;
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPara );
+ for ( USHORT nLine = pPortion->GetLines().Count(); nLine; )
+ {
+ ULONG nLineWidth = 0;
+ TextLine* pLine = pPortion->GetLines().GetObject( --nLine );
+ for ( USHORT nTP = pLine->GetStartPortion(); nTP <= pLine->GetEndPortion(); nTP++ )
+ {
+ TETextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( nTP );
+ nLineWidth += pTextPortion->GetWidth();
+ }
+ if ( nLineWidth > nParaWidth )
+ nParaWidth = nLineWidth;
+ }
+ return nParaWidth;
+}
+
+ULONG TextEngine::CalcTextWidth()
+{
+ if ( !IsFormatted() && !IsFormatting() )
+ FormatAndUpdate();
+
+ if ( mnCurTextWidth == 0xFFFFFFFF )
+ {
+ mnCurTextWidth = 0;
+ for ( ULONG nPara = mpTEParaPortions->Count(); nPara; )
+ {
+ ULONG nParaWidth = CalcTextWidth( --nPara );
+ if ( nParaWidth > mnCurTextWidth )
+ mnCurTextWidth = nParaWidth;
+ }
+ }
+ return mnCurTextWidth+1;// Ein breiter, da in CreateLines bei >= umgebrochen wird.
+}
+
+ULONG TextEngine::CalcTextHeight()
+{
+ DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=FALSE nicht verwendet werden: CalcTextHeight" );
+
+ ULONG nY = 0;
+ for ( ULONG nPortion = mpTEParaPortions->Count(); nPortion; )
+ nY += CalcParaHeight( --nPortion );
+ return nY;
+}
+
+ULONG TextEngine::CalcTextWidth( ULONG nPara, USHORT nPortionStart, USHORT nLen, const Font* pFont )
+{
+ // Innerhalb des Textes darf es keinen Portionwechsel (Attribut/Tab) geben!
+ DBG_ASSERT( mpDoc->GetNodes().GetObject( nPara )->GetText().Search( '\t', nPortionStart ) >= (nPortionStart+nLen), "CalcTextWidth: Tab!" );
+
+ ULONG nWidth;
+ if ( mnFixCharWidth100 )
+ {
+ nWidth = (ULONG)nLen*mnFixCharWidth100/100;
+ }
+ else
+ {
+ if ( pFont )
+ {
+ if ( !mpRefDev->GetFont().IsSameInstance( *pFont ) )
+ mpRefDev->SetFont( *pFont );
+ }
+ else
+ {
+ Font aFont;
+ SeekCursor( nPara, nPortionStart+1, aFont, NULL );
+ mpRefDev->SetFont( aFont );
+ }
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ nWidth = (ULONG)mpRefDev->GetTextWidth( pNode->GetText(), nPortionStart, nLen );
+
+ }
+ return nWidth;
+}
+
+
+USHORT TextEngine::GetLineCount( ULONG nParagraph ) const
+{
+ DBG_ASSERT( nParagraph < mpTEParaPortions->Count(), "GetLineCount: Out of range" );
+
+ TEParaPortion* pPPortion = mpTEParaPortions->GetObject( nParagraph );
+ if ( pPPortion )
+ return pPPortion->GetLines().Count();
+
+ return 0xFFFF;
+}
+
+USHORT TextEngine::GetLineLen( ULONG nParagraph, USHORT nLine ) const
+{
+ DBG_ASSERT( nParagraph < mpTEParaPortions->Count(), "GetLineCount: Out of range" );
+
+ TEParaPortion* pPPortion = mpTEParaPortions->GetObject( nParagraph );
+ if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
+ {
+ TextLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ return pLine->GetLen();
+ }
+
+ return 0xFFFF;
+}
+
+ULONG TextEngine::CalcParaHeight( ULONG nParagraph ) const
+{
+ ULONG nHeight = 0;
+
+ TEParaPortion* pPPortion = mpTEParaPortions->GetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetParaHeight" );
+ if ( pPPortion )
+ nHeight = pPPortion->GetLines().Count() * mnCharHeight;
+
+ return nHeight;
+}
+
+void TextEngine::UpdateSelections()
+{
+}
+
+Range TextEngine::GetInvalidYOffsets( ULONG nPortion )
+{
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPortion );
+ USHORT nLines = pTEParaPortion->GetLines().Count();
+ USHORT nLastInvalid, nFirstInvalid = 0;
+ USHORT nLine;
+ for ( nLine = 0; nLine < nLines; nLine++ )
+ {
+ TextLine* pL = pTEParaPortion->GetLines().GetObject( nLine );
+ if ( pL->IsInvalid() )
+ {
+ nFirstInvalid = nLine;
+ break;
+ }
+ }
+
+ for ( nLastInvalid = nFirstInvalid; nLastInvalid < nLines; nLastInvalid++ )
+ {
+ TextLine* pL = pTEParaPortion->GetLines().GetObject( nLine );
+ if ( pL->IsValid() )
+ break;
+ }
+
+ if ( nLastInvalid >= nLines )
+ nLastInvalid = nLines-1;
+
+ return Range( nFirstInvalid*mnCharHeight, ((nLastInvalid+1)*mnCharHeight)-1 );
+}
+
+ULONG TextEngine::GetParagraphCount() const
+{
+ return mpDoc->GetNodes().Count();
+}
+
+void TextEngine::EnableUndo( BOOL bEnable )
+{
+ // Beim Umschalten des Modus Liste loeschen:
+ if ( bEnable != IsUndoEnabled() )
+ ResetUndo();
+
+ mbUndoEnabled = bEnable;
+}
+
+SfxUndoManager& TextEngine::GetUndoManager()
+{
+ if ( !mpUndoManager )
+ mpUndoManager = new TextUndoManager( this );
+ return *mpUndoManager;
+}
+
+void TextEngine::UndoActionStart( USHORT nId )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ String aComment;
+ // ...
+ GetUndoManager().EnterListAction( aComment, XubString(), nId );
+ }
+}
+
+void TextEngine::UndoActionEnd( USHORT )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ GetUndoManager().LeaveListAction();
+}
+
+void TextEngine::InsertUndo( TextUndo* pUndo, BOOL bTryMerge )
+{
+ DBG_ASSERT( !IsInUndo(), "InsertUndo im Undomodus!" );
+ GetUndoManager().AddUndoAction( pUndo, bTryMerge );
+}
+
+void TextEngine::ResetUndo()
+{
+ if ( mpUndoManager )
+ mpUndoManager->Clear();
+}
+
+void TextEngine::InsertContent( TextNode* pNode, ULONG nPara )
+{
+ DBG_ASSERT( pNode, "NULL-Pointer in InsertContent! " );
+ DBG_ASSERT( IsInUndo(), "InsertContent nur fuer Undo()!" );
+ TEParaPortion* pNew = new TEParaPortion( pNode );
+ mpTEParaPortions->Insert( pNew, nPara );
+ mpDoc->GetNodes().Insert( pNode, nPara );
+ ImpParagraphInserted( nPara );
+}
+
+TextPaM TextEngine::SplitContent( ULONG nNode, USHORT nSepPos )
+{
+ #ifdef DBG_UTIL
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nNode );
+ DBG_ASSERT( pNode, "Ungueltiger Node in SplitContent" );
+ DBG_ASSERT( IsInUndo(), "SplitContent nur fuer Undo()!" );
+ DBG_ASSERT( nSepPos <= pNode->GetText().Len(), "Index im Wald: SplitContent" );
+ #endif
+ TextPaM aPaM( nNode, nSepPos );
+ return ImpInsertParaBreak( aPaM );
+}
+
+TextPaM TextEngine::ConnectContents( ULONG nLeftNode )
+{
+ DBG_ASSERT( IsInUndo(), "ConnectContent nur fuer Undo()!" );
+ return ImpConnectParagraphs( nLeftNode, nLeftNode+1 );
+}
+
+void TextEngine::SeekCursor( ULONG nPara, USHORT nPos, Font& rFont, OutputDevice* pOutDev )
+{
+ rFont = maFont;
+ if ( pOutDev )
+ pOutDev->SetTextColor( maTextColor );
+
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ USHORT nAttribs = pNode->GetCharAttribs().Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ TextCharAttrib* pAttrib = pNode->GetCharAttribs().GetAttrib( nAttr );
+ if ( pAttrib->GetStart() > nPos )
+ break;
+
+ // Beim Seeken nicht die Attr beruecksichtigen, die dort beginnen!
+ // Leere Attribute werden beruecksichtigt( verwendet), da diese
+ // gerade eingestellt wurden.
+ // 12.4.95: Doch keine Leeren Attribute verwenden:
+ // - Wenn gerade eingestellt und leer => keine Auswirkung auf Font
+ // In einem leeren Absatz eingestellte Zeichen werden sofort wirksam.
+ if ( ( ( pAttrib->GetStart() < nPos ) && ( pAttrib->GetEnd() >= nPos ) )
+ || !pNode->GetText().Len() )
+ {
+ if ( pAttrib->Which() != TEXTATTR_FONTCOLOR )
+ {
+ pAttrib->GetAttr().SetFont( rFont );
+ }
+ else
+ {
+ if ( pOutDev )
+ pOutDev->SetTextColor( ((TextAttribFontColor&)pAttrib->GetAttr()).GetColor() );
+ }
+ }
+ }
+
+ if ( mpIMEInfos && mpIMEInfos->pAttribs && ( mpIMEInfos->aPos.GetPara() == nPara ) &&
+ ( nPos > mpIMEInfos->aPos.GetIndex() ) && ( nPos <= ( mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen ) ) )
+ {
+ sal_uInt16 nAttr = mpIMEInfos->pAttribs[ nPos - mpIMEInfos->aPos.GetIndex() - 1 ];
+ if ( nAttr & EXTTEXTINPUT_ATTR_UNDERLINE )
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_BOLDUNDERLINE )
+ rFont.SetUnderline( UNDERLINE_BOLD );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE )
+ rFont.SetUnderline( UNDERLINE_DOTTED );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE )
+ rFont.SetUnderline( UNDERLINE_DOTTED );
+ if ( nAttr & EXTTEXTINPUT_ATTR_REDTEXT )
+ rFont.SetColor( Color( COL_RED ) );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_HALFTONETEXT )
+ rFont.SetColor( Color( COL_LIGHTGRAY ) );
+ if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
+ {
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ rFont.SetColor( rStyleSettings.GetHighlightTextColor() );
+ rFont.SetFillColor( rStyleSettings.GetHighlightColor() );
+ rFont.SetTransparent( FALSE );
+ }
+ else if ( nAttr & EXTTEXTINPUT_ATTR_GRAYWAVELINE )
+ {
+ rFont.SetUnderline( UNDERLINE_WAVE );
+// if( pOut )
+// pOut->SetTextLineColor( Color( COL_LIGHTGRAY ) );
+ }
+ }
+}
+
+void TextEngine::SetUpdateMode( BOOL bUp, TextView* pCurView, BOOL bForceUpdate )
+{
+ BOOL bChanged = ( GetUpdateMode() != bUp );
+
+ mbUpdate = bUp;
+ if ( mbUpdate && ( bChanged || bForceUpdate ) )
+ FormatAndUpdate( pCurView );
+}
+
+void TextEngine::FormatAndUpdate( TextView* pCurView )
+{
+ if ( mbDowning )
+ return ;
+
+ if ( IsInUndo() )
+ IdleFormatAndUpdate( pCurView );
+ else
+ {
+ FormatDoc();
+ UpdateViews( pCurView );
+ }
+}
+
+
+void TextEngine::IdleFormatAndUpdate( TextView* pCurView, USHORT nMaxTimerRestarts )
+{
+ mpIdleFormatter->DoIdleFormat( pCurView, nMaxTimerRestarts );
+}
+
+void TextEngine::TextModified()
+{
+ mbFormatted = FALSE;
+ mbModified = TRUE;
+}
+
+void TextEngine::UpdateViews( TextView* pCurView )
+{
+ if ( !GetUpdateMode() || IsFormatting() || maInvalidRec.IsEmpty() )
+ return;
+
+ DBG_ASSERT( IsFormatted(), "UpdateViews: Doc nicht formatiert!" );
+
+ for ( USHORT nView = 0; nView < mpViews->Count(); nView++ )
+ {
+ TextView* pView = mpViews->GetObject( nView );
+ pView->HideCursor();
+
+ Rectangle aClipRec( maInvalidRec );
+ Size aOutSz = pView->GetWindow()->GetOutputSizePixel();
+ Rectangle aVisArea( pView->GetStartDocPos(), aOutSz );
+ aClipRec.Intersection( aVisArea );
+ if ( !aClipRec.IsEmpty() )
+ {
+ // in Fensterkoordinaten umwandeln....
+ Point aNewPos = pView->GetWindowPos( aClipRec.TopLeft() );
+ if ( IsRightToLeft() )
+ aNewPos.X() -= aOutSz.Width() - 1;
+ aClipRec.SetPos( aNewPos );
+
+ if ( pView == pCurView )
+ pView->ImpPaint( aClipRec, !pView->GetWindow()->IsPaintTransparent() );
+ else
+ pView->GetWindow()->Invalidate( aClipRec );
+ }
+ }
+
+ if ( pCurView )
+ {
+ pCurView->ShowCursor( pCurView->IsAutoScroll() );
+ }
+
+ maInvalidRec = Rectangle();
+}
+
+IMPL_LINK( TextEngine, IdleFormatHdl, Timer *, EMPTYARG )
+{
+ FormatAndUpdate( mpIdleFormatter->GetView() );
+ return 0;
+}
+
+void TextEngine::CheckIdleFormatter()
+{
+ mpIdleFormatter->ForceTimeout();
+}
+
+void TextEngine::FormatFullDoc()
+{
+ for ( ULONG nPortion = 0; nPortion < mpTEParaPortions->Count(); nPortion++ )
+ {
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPortion ); USHORT nLen = pTEParaPortion->GetNode()->GetText().Len();
+ pTEParaPortion->MarkSelectionInvalid( 0, nLen );
+ }
+ mbFormatted = FALSE;
+ FormatDoc();
+}
+
+void TextEngine::FormatDoc()
+{
+ if ( IsFormatted() || !GetUpdateMode() || IsFormatting() )
+ return;
+
+ mbIsFormatting = TRUE;
+ mbHasMultiLineParas = FALSE;
+
+ long nY = 0;
+ BOOL bGrow = FALSE;
+
+ maInvalidRec = Rectangle(); // leermachen
+ for ( ULONG nPara = 0; nPara < mpTEParaPortions->Count(); nPara++ )
+ {
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ if ( pTEParaPortion->IsInvalid() )
+ {
+ ULONG nOldParaWidth = 0xFFFFFFFF;
+ if ( mnCurTextWidth != 0xFFFFFFFF )
+ nOldParaWidth = CalcTextWidth( nPara );
+
+ ImpFormattingParagraph( nPara );
+
+ if ( CreateLines( nPara ) )
+ bGrow = TRUE;
+
+ // InvalidRec nur einmal setzen...
+ if ( maInvalidRec.IsEmpty() )
+ {
+ // Bei Paperwidth 0 (AutoPageSize) bleibt es sonst Empty()...
+ long nWidth = (long)mnMaxTextWidth;
+ if ( !nWidth )
+ nWidth = 0x7FFFFFFF;
+ Range aInvRange( GetInvalidYOffsets( nPara ) );
+ maInvalidRec = Rectangle( Point( 0, nY+aInvRange.Min() ),
+ Size( nWidth, aInvRange.Len() ) );
+ }
+ else
+ {
+ maInvalidRec.Bottom() = nY + CalcParaHeight( nPara );
+ }
+
+ if ( mnCurTextWidth != 0xFFFFFFFF )
+ {
+ ULONG nNewParaWidth = CalcTextWidth( nPara );
+ if ( nNewParaWidth >= mnCurTextWidth )
+ mnCurTextWidth = nNewParaWidth;
+ else if ( ( nOldParaWidth != 0xFFFFFFFF ) && ( nOldParaWidth >= mnCurTextWidth ) )
+ mnCurTextWidth = 0xFFFFFFFF;
+ }
+ }
+ else if ( bGrow )
+ {
+ maInvalidRec.Bottom() = nY + CalcParaHeight( nPara );
+ }
+ nY += CalcParaHeight( nPara );
+ if ( !mbHasMultiLineParas && pTEParaPortion->GetLines().Count() > 1 )
+ mbHasMultiLineParas = TRUE;
+ }
+
+ if ( !maInvalidRec.IsEmpty() )
+ {
+ ULONG nNewHeight = CalcTextHeight();
+ long nDiff = nNewHeight - mnCurTextHeight;
+ if ( nNewHeight < mnCurTextHeight )
+ {
+ maInvalidRec.Bottom() = (long)Max( nNewHeight, mnCurTextHeight );
+ if ( maInvalidRec.IsEmpty() )
+ {
+ maInvalidRec.Top() = 0;
+ // Left und Right werden nicht ausgewertet, aber wegen IsEmpty gesetzt.
+ maInvalidRec.Left() = 0;
+ maInvalidRec.Right() = mnMaxTextWidth;
+ }
+ }
+
+ mnCurTextHeight = nNewHeight;
+ if ( nDiff )
+ {
+ mbFormatted = TRUE;
+ ImpTextHeightChanged();
+ }
+ }
+
+ mbIsFormatting = FALSE;
+ mbFormatted = TRUE;
+
+ ImpTextFormatted();
+}
+
+void TextEngine::CreateAndInsertEmptyLine( ULONG nPara )
+{
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+
+ TextLine* pTmpLine = new TextLine;
+ pTmpLine->SetStart( pNode->GetText().Len() );
+ pTmpLine->SetEnd( pTmpLine->GetStart() );
+ pTEParaPortion->GetLines().Insert( pTmpLine, pTEParaPortion->GetLines().Count() );
+
+ if ( ImpGetAlign() == TXTALIGN_CENTER )
+ pTmpLine->SetStartX( (short)(mnMaxTextWidth / 2) );
+ else if ( ImpGetAlign() == TXTALIGN_RIGHT )
+ pTmpLine->SetStartX( (short)mnMaxTextWidth );
+ else
+ pTmpLine->SetStartX( mpDoc->GetLeftMargin() );
+
+ BOOL bLineBreak = pNode->GetText().Len() ? TRUE : FALSE;
+
+ TETextPortion* pDummyPortion = new TETextPortion( 0 );
+ pDummyPortion->GetWidth() = 0;
+ pTEParaPortion->GetTextPortions().Insert( pDummyPortion, pTEParaPortion->GetTextPortions().Count() );
+
+ if ( bLineBreak == TRUE )
+ {
+ // -2: Die neue ist bereits eingefuegt.
+ #ifdef DBG_UTIL
+ TextLine* pLastLine = pTEParaPortion->GetLines().GetObject( pTEParaPortion->GetLines().Count()-2 );
+ DBG_ASSERT( pLastLine, "Weicher Umbruch, keine Zeile ?!" );
+ #endif
+ USHORT nPos = (USHORT) pTEParaPortion->GetTextPortions().Count() - 1 ;
+ pTmpLine->SetStartPortion( nPos );
+ pTmpLine->SetEndPortion( nPos );
+ }
+}
+
+void TextEngine::ImpBreakLine( ULONG nPara, TextLine* pLine, TETextPortion*, USHORT nPortionStart, long nRemainingWidth )
+{
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+
+ // Font sollte noch eingestellt sein.
+ USHORT nMaxBreakPos = mpRefDev->GetTextBreak( pNode->GetText(), nRemainingWidth, nPortionStart );
+
+ DBG_ASSERT( nMaxBreakPos < pNode->GetText().Len(), "Break?!" );
+
+ if ( nMaxBreakPos == STRING_LEN ) // GetTextBreak() ist anderer Auffassung als GetTextSize()
+ nMaxBreakPos = pNode->GetText().Len() - 1;
+
+ uno::Reference < i18n::XBreakIterator > xBI = GetBreakIterator();
+ i18n::LineBreakHyphenationOptions aHyphOptions( NULL, uno::Sequence< beans::PropertyValue >(), 1 );
+
+ i18n::LineBreakUserOptions aUserOptions;
+ aUserOptions.forbiddenBeginCharacters = ImpGetLocaleDataWrapper()->getForbiddenCharacters().beginLine;
+ aUserOptions.forbiddenEndCharacters = ImpGetLocaleDataWrapper()->getForbiddenCharacters().endLine;
+ aUserOptions.applyForbiddenRules = sal_True;
+ aUserOptions.allowPunctuationOutsideMargin = sal_False;
+ aUserOptions.allowHyphenateEnglish = sal_False;
+
+ static const com::sun::star::lang::Locale aDefLocale;
+ i18n::LineBreakResults aLBR = xBI->getLineBreak( pNode->GetText(), nMaxBreakPos, aDefLocale, pLine->GetStart(), aHyphOptions, aUserOptions );
+ USHORT nBreakPos = (USHORT)aLBR.breakIndex;
+ if ( nBreakPos <= pLine->GetStart() )
+ {
+ nBreakPos = nMaxBreakPos;
+ if ( nBreakPos <= pLine->GetStart() )
+ nBreakPos = pLine->GetStart() + 1; // Sonst Endlosschleife!
+ }
+
+
+ // die angeknackste Portion ist die End-Portion
+ pLine->SetEnd( nBreakPos );
+ USHORT nEndPortion = SplitTextPortion( nPara, nBreakPos );
+
+ sal_Bool bBlankSeparator = ( ( nBreakPos >= pLine->GetStart() ) &&
+ ( pNode->GetText().GetChar( nBreakPos ) == ' ' ) ) ? sal_True : sal_False;
+ if ( bBlankSeparator )
+ {
+ // Blanks am Zeilenende generell unterdruecken...
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ TETextPortion* pTP = pTEParaPortion->GetTextPortions().GetObject( nEndPortion );
+ DBG_ASSERT( nBreakPos > pLine->GetStart(), "SplitTextPortion am Anfang der Zeile?" );
+ pTP->GetWidth() = (long)CalcTextWidth( nPara, nBreakPos-pTP->GetLen(), pTP->GetLen()-1 );
+ }
+ pLine->SetEndPortion( nEndPortion );
+}
+
+USHORT TextEngine::SplitTextPortion( ULONG nPara, USHORT nPos )
+{
+
+ // Die Portion bei nPos wird geplittet, wenn bei nPos nicht
+ // sowieso ein Wechsel ist
+ if ( nPos == 0 )
+ return 0;
+
+ USHORT nSplitPortion;
+ USHORT nTmpPos = 0;
+ TETextPortion* pTextPortion = 0;
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ USHORT nPortions = pTEParaPortion->GetTextPortions().Count();
+ for ( nSplitPortion = 0; nSplitPortion < nPortions; nSplitPortion++ )
+ {
+ TETextPortion* pTP = pTEParaPortion->GetTextPortions().GetObject(nSplitPortion);
+ nTmpPos = nTmpPos + pTP->GetLen();
+ if ( nTmpPos >= nPos )
+ {
+ if ( nTmpPos == nPos ) // dann braucht nichts geteilt werden
+ return nSplitPortion;
+ pTextPortion = pTP;
+ break;
+ }
+ }
+
+ DBG_ASSERT( pTextPortion, "Position ausserhalb des Bereichs!" );
+
+ USHORT nOverlapp = nTmpPos - nPos;
+ pTextPortion->GetLen() = pTextPortion->GetLen() - nOverlapp;
+ TETextPortion* pNewPortion = new TETextPortion( nOverlapp );
+ pTEParaPortion->GetTextPortions().Insert( pNewPortion, nSplitPortion+1 );
+ pTextPortion->GetWidth() = (long)CalcTextWidth( nPara, nPos-pTextPortion->GetLen(), pTextPortion->GetLen() );
+
+ return nSplitPortion;
+}
+
+void TextEngine::CreateTextPortions( ULONG nPara, USHORT nStartPos )
+{
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ TextNode* pNode = pTEParaPortion->GetNode();
+ DBG_ASSERT( pNode->GetText().Len(), "CreateTextPortions sollte nicht fuer leere Absaetze verwendet werden!" );
+
+ TESortedPositions aPositions;
+ ULONG nZero = 0;
+ aPositions.Insert( nZero );
+
+ USHORT nAttribs = pNode->GetCharAttribs().Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ TextCharAttrib* pAttrib = pNode->GetCharAttribs().GetAttrib( nAttr );
+
+ // Start und Ende in das Array eintragen...
+ // Die InsertMethode laesst keine doppelten Werte zu....
+ aPositions.Insert( pAttrib->GetStart() );
+ aPositions.Insert( pAttrib->GetEnd() );
+ }
+ aPositions.Insert( pNode->GetText().Len() );
+
+ const TEWritingDirectionInfos& rWritingDirections = pTEParaPortion->GetWritingDirectionInfos();
+ for ( USHORT nD = 0; nD < rWritingDirections.Count(); nD++ )
+ aPositions.Insert( rWritingDirections[nD].nStartPos );
+
+ if ( mpIMEInfos && mpIMEInfos->pAttribs && ( mpIMEInfos->aPos.GetPara() == nPara ) )
+ {
+ sal_uInt16 nLastAttr = 0xFFFF;
+ for( sal_uInt16 n = 0; n < mpIMEInfos->nLen; n++ )
+ {
+ if ( mpIMEInfos->pAttribs[n] != nLastAttr )
+ {
+ aPositions.Insert( mpIMEInfos->aPos.GetIndex() + n );
+ nLastAttr = mpIMEInfos->pAttribs[n];
+ }
+ }
+ }
+
+ USHORT nTabPos = pNode->GetText().Search( '\t', 0 );
+ while ( nTabPos != STRING_NOTFOUND )
+ {
+ aPositions.Insert( nTabPos );
+ aPositions.Insert( nTabPos + 1 );
+ nTabPos = pNode->GetText().Search( '\t', nTabPos+1 );
+ }
+
+ // Ab ... loeschen:
+ // Leider muss die Anzahl der TextPortions mit aPositions.Count()
+ // nicht uebereinstimmen, da evtl. Zeilenumbrueche...
+ USHORT nPortionStart = 0;
+ USHORT nInvPortion = 0;
+ USHORT nP;
+ for ( nP = 0; nP < pTEParaPortion->GetTextPortions().Count(); nP++ )
+ {
+ TETextPortion* pTmpPortion = pTEParaPortion->GetTextPortions().GetObject(nP);
+ nPortionStart = nPortionStart + pTmpPortion->GetLen();
+ if ( nPortionStart >= nStartPos )
+ {
+ nPortionStart = nPortionStart - pTmpPortion->GetLen();
+ nInvPortion = nP;
+ break;
+ }
+ }
+ DBG_ASSERT( nP < pTEParaPortion->GetTextPortions().Count() || !pTEParaPortion->GetTextPortions().Count(), "Nichts zum loeschen: CreateTextPortions" );
+ if ( nInvPortion && ( nPortionStart+pTEParaPortion->GetTextPortions().GetObject(nInvPortion)->GetLen() > nStartPos ) )
+ {
+ // lieber eine davor...
+ // Aber nur wenn es mitten in der Portion war, sonst ist es evtl.
+ // die einzige in der Zeile davor !
+ nInvPortion--;
+ nPortionStart = nPortionStart - pTEParaPortion->GetTextPortions().GetObject(nInvPortion)->GetLen();
+ }
+ pTEParaPortion->GetTextPortions().DeleteFromPortion( nInvPortion );
+
+ // Eine Portion kann auch durch einen Zeilenumbruch entstanden sein:
+ aPositions.Insert( nPortionStart );
+
+ USHORT nInvPos;
+ #ifdef DBG_UTIL
+ BOOL bFound =
+ #endif
+ aPositions.Seek_Entry( nPortionStart, &nInvPos );
+ DBG_ASSERT( bFound && ( nInvPos < (aPositions.Count()-1) ), "InvPos ?!" );
+ for ( USHORT i = nInvPos+1; i < aPositions.Count(); i++ )
+ {
+ TETextPortion* pNew = new TETextPortion( (USHORT)aPositions[i] - (USHORT)aPositions[i-1] );
+ pTEParaPortion->GetTextPortions().Insert( pNew, pTEParaPortion->GetTextPortions().Count());
+ }
+
+ DBG_ASSERT( pTEParaPortion->GetTextPortions().Count(), "Keine Portions?!" );
+#ifdef EDITDEBUG
+ DBG_ASSERT( pTEParaPortion->DbgCheckTextPortions(), "Portions kaputt?" );
+#endif
+}
+
+void TextEngine::RecalcTextPortion( ULONG nPara, USHORT nStartPos, short nNewChars )
+{
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ DBG_ASSERT( pTEParaPortion->GetTextPortions().Count(), "Keine Portions!" );
+ DBG_ASSERT( nNewChars, "RecalcTextPortion mit Diff == 0" );
+
+ TextNode* const pNode = pTEParaPortion->GetNode();
+ if ( nNewChars > 0 )
+ {
+ // Wenn an nStartPos ein Attribut beginnt/endet, oder vor nStartPos
+ // ein Tab steht, faengt eine neue Portion an,
+ // ansonsten wird die Portion an nStartPos erweitert.
+ // Oder wenn ganz vorne ( StartPos 0 ) und dann ein Tab
+
+ if ( ( pNode->GetCharAttribs().HasBoundingAttrib( nStartPos ) ) ||
+ ( nStartPos && ( pNode->GetText().GetChar( nStartPos - 1 ) == '\t' ) ) ||
+ ( ( !nStartPos && ( nNewChars < pNode->GetText().Len() ) && pNode->GetText().GetChar( nNewChars ) == '\t' ) ) )
+ {
+ USHORT nNewPortionPos = 0;
+ if ( nStartPos )
+ nNewPortionPos = SplitTextPortion( nPara, nStartPos ) + 1;
+// else if ( ( pTEParaPortion->GetTextPortions().Count() == 1 ) &&
+// !pTEParaPortion->GetTextPortions()[0]->GetLen() )
+// pTEParaPortion->GetTextPortions().Reset(); // DummyPortion
+
+ // Eine leere Portion kann hier stehen, wenn der Absatz leer war,
+ // oder eine Zeile durch einen harten Zeilenumbruch entstanden ist.
+ if ( ( nNewPortionPos < pTEParaPortion->GetTextPortions().Count() ) &&
+ !pTEParaPortion->GetTextPortions()[nNewPortionPos]->GetLen() )
+ {
+ // Dann die leere Portion verwenden.
+ USHORT & r =
+ pTEParaPortion->GetTextPortions()[nNewPortionPos]->GetLen();
+ r = r + nNewChars;
+ }
+ else
+ {
+ TETextPortion* pNewPortion = new TETextPortion( nNewChars );
+ pTEParaPortion->GetTextPortions().Insert( pNewPortion, nNewPortionPos );
+ }
+ }
+ else
+ {
+ USHORT nPortionStart;
+ const USHORT nTP = pTEParaPortion->GetTextPortions().
+ FindPortion( nStartPos, nPortionStart );
+ TETextPortion* const pTP = pTEParaPortion->GetTextPortions()[ nTP ];
+ DBG_ASSERT( pTP, "RecalcTextPortion: Portion nicht gefunden" );
+ pTP->GetLen() = pTP->GetLen() + nNewChars;
+ pTP->GetWidth() = (-1);
+ }
+ }
+ else
+ {
+ // Portion schrumpfen oder ggf. entfernen.
+ // Vor Aufruf dieser Methode muss sichergestellt sein, dass
+ // keine Portions in dem geloeschten Bereich lagen!
+
+ // Es darf keine reinragende oder im Bereich startende Portion geben,
+ // also muss nStartPos <= nPos <= nStartPos - nNewChars(neg.) sein
+ USHORT nPortion = 0;
+ USHORT nPos = 0;
+ USHORT nEnd = nStartPos-nNewChars;
+ USHORT nPortions = pTEParaPortion->GetTextPortions().Count();
+ TETextPortion* pTP = 0;
+ for ( nPortion = 0; nPortion < nPortions; nPortion++ )
+ {
+ pTP = pTEParaPortion->GetTextPortions()[ nPortion ];
+ if ( ( nPos+pTP->GetLen() ) > nStartPos )
+ {
+ DBG_ASSERT( nPos <= nStartPos, "Start falsch!" );
+ DBG_ASSERT( nPos+pTP->GetLen() >= nEnd, "End falsch!" );
+ break;
+ }
+ nPos = nPos + pTP->GetLen();
+ }
+ DBG_ASSERT( pTP, "RecalcTextPortion: Portion nicht gefunden" );
+ if ( ( nPos == nStartPos ) && ( (nPos+pTP->GetLen()) == nEnd ) )
+ {
+ // Portion entfernen;
+ pTEParaPortion->GetTextPortions().Remove( nPortion );
+ delete pTP;
+ }
+ else
+ {
+ DBG_ASSERT( pTP->GetLen() > (-nNewChars), "Portion zu klein zum schrumpfen!" );
+ pTP->GetLen() = pTP->GetLen() + nNewChars;
+ }
+ DBG_ASSERT( pTEParaPortion->GetTextPortions().Count(), "RecalcTextPortions: Keine mehr da!" );
+ }
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( pTEParaPortion->DbgCheckTextPortions(), "Portions kaputt?" );
+#endif
+}
+
+void TextEngine::ImpPaint( OutputDevice* pOutDev, const Point& rStartPos, Rectangle const* pPaintArea, TextSelection const* pPaintRange, TextSelection const* pSelection )
+{
+ if ( !GetUpdateMode() )
+ return;
+
+ if ( !IsFormatted() )
+ FormatDoc();
+
+ bool bTransparent = false;
+ Window* pOutWin = dynamic_cast<Window*>(pOutDev);
+ bTransparent = (pOutWin && pOutWin->IsPaintTransparent());
+
+ long nY = rStartPos.Y();
+
+ TextPaM const* pSelStart = 0;
+ TextPaM const* pSelEnd = 0;
+ if ( pSelection && pSelection->HasRange() )
+ {
+ BOOL bInvers = pSelection->GetEnd() < pSelection->GetStart();
+ pSelStart = !bInvers ? &pSelection->GetStart() : &pSelection->GetEnd();
+ pSelEnd = bInvers ? &pSelection->GetStart() : &pSelection->GetEnd();
+ }
+ DBG_ASSERT( !pPaintRange || ( pPaintRange->GetStart() < pPaintRange->GetEnd() ), "ImpPaint: Paint-Range?!" );
+
+ const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
+
+ // --------------------------------------------------
+ // Ueber alle Absaetze...
+ // --------------------------------------------------
+ for ( ULONG nPara = 0; nPara < mpTEParaPortions->Count(); nPara++ )
+ {
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPara );
+ // falls beim Tippen Idle-Formatierung, asynchrones Paint.
+ if ( pPortion->IsInvalid() )
+ return;
+
+ ULONG nParaHeight = CalcParaHeight( nPara );
+ USHORT nIndex = 0;
+ if ( ( !pPaintArea || ( ( nY + (long)nParaHeight ) > pPaintArea->Top() ) )
+ && ( !pPaintRange || ( ( nPara >= pPaintRange->GetStart().GetPara() ) && ( nPara <= pPaintRange->GetEnd().GetPara() ) ) ) )
+ {
+ // --------------------------------------------------
+ // Ueber die Zeilen des Absatzes...
+ // --------------------------------------------------
+ USHORT nLines = pPortion->GetLines().Count();
+ for ( USHORT nLine = 0; nLine < nLines; nLine++ )
+ {
+ TextLine* pLine = pPortion->GetLines().GetObject(nLine);
+ Point aTmpPos( rStartPos.X() + pLine->GetStartX(), nY );
+
+ if ( ( !pPaintArea || ( ( nY + mnCharHeight ) > pPaintArea->Top() ) )
+ && ( !pPaintRange || (
+ ( TextPaM( nPara, pLine->GetStart() ) < pPaintRange->GetEnd() ) &&
+ ( TextPaM( nPara, pLine->GetEnd() ) > pPaintRange->GetStart() ) ) ) )
+ {
+ // --------------------------------------------------
+ // Ueber die Portions der Zeile...
+ // --------------------------------------------------
+ nIndex = pLine->GetStart();
+ for ( USHORT y = pLine->GetStartPortion(); y <= pLine->GetEndPortion(); y++ )
+ {
+ DBG_ASSERT( pPortion->GetTextPortions().Count(), "Zeile ohne Textportion im Paint!" );
+ TETextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( y );
+ DBG_ASSERT( pTextPortion, "NULL-Pointer im Portioniterator in UpdateViews" );
+
+ ImpInitLayoutMode( pOutDev /*, pTextPortion->IsRightToLeft() */);
+
+ long nTxtWidth = pTextPortion->GetWidth();
+ aTmpPos.X() = rStartPos.X() + ImpGetOutputOffset( nPara, pLine, nIndex, nIndex );
+
+ // nur ausgeben, was im sichtbaren Bereich beginnt:
+ if ( ( ( aTmpPos.X() + nTxtWidth ) >= 0 )
+ && ( !pPaintRange || (
+ ( TextPaM( nPara, nIndex ) < pPaintRange->GetEnd() ) &&
+ ( TextPaM( nPara, nIndex + pTextPortion->GetLen() ) > pPaintRange->GetStart() ) ) ) )
+ {
+ switch ( pTextPortion->GetKind() )
+ {
+ case PORTIONKIND_TEXT:
+ {
+ {
+ Font aFont;
+ SeekCursor( nPara, nIndex+1, aFont, pOutDev );
+ if( bTransparent )
+ aFont.SetTransparent( TRUE );
+ else if ( pSelection )
+ aFont.SetTransparent( FALSE );
+ pOutDev->SetFont( aFont );
+
+ USHORT nTmpIndex = nIndex;
+ USHORT nEnd = nTmpIndex + pTextPortion->GetLen();
+ Point aPos = aTmpPos;
+ if ( pPaintRange )
+ {
+ // evtl soll nicht alles ausgegeben werden...
+ if ( ( pPaintRange->GetStart().GetPara() == nPara )
+ && ( nTmpIndex < pPaintRange->GetStart().GetIndex() ) )
+ {
+ nTmpIndex = pPaintRange->GetStart().GetIndex();
+ }
+ if ( ( pPaintRange->GetEnd().GetPara() == nPara )
+ && ( nEnd > pPaintRange->GetEnd().GetIndex() ) )
+ {
+ nEnd = pPaintRange->GetEnd().GetIndex();
+ }
+ }
+
+ BOOL bDone = FALSE;
+ if ( pSelStart )
+ {
+ // liegt ein Teil in der Selektion???
+ TextPaM aTextStart( nPara, nTmpIndex );
+ TextPaM aTextEnd( nPara, nEnd );
+ if ( ( aTextStart < *pSelEnd ) && ( aTextEnd > *pSelStart ) )
+ {
+ USHORT nL;
+
+ // 1) Bereich vor Selektion
+ if ( aTextStart < *pSelStart )
+ {
+ nL = pSelStart->GetIndex() - nTmpIndex;
+ pOutDev->SetFont( aFont);
+ aPos.X() = rStartPos.X() + ImpGetOutputOffset( nPara, pLine, nTmpIndex, nTmpIndex+nL );
+ pOutDev->DrawText( aPos, pPortion->GetNode()->GetText(), nTmpIndex, nL );
+ nTmpIndex = nTmpIndex + nL;
+
+ }
+ // 2) Bereich mit Selektion
+ nL = nEnd-nTmpIndex;
+ if ( aTextEnd > *pSelEnd )
+ nL = pSelEnd->GetIndex() - nTmpIndex;
+ if ( nL )
+ {
+ Color aOldTextColor = pOutDev->GetTextColor();
+ pOutDev->SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ pOutDev->SetTextFillColor( rStyleSettings.GetHighlightColor() );
+ aPos.X() = rStartPos.X() + ImpGetOutputOffset( nPara, pLine, nTmpIndex, nTmpIndex+nL );
+ pOutDev->DrawText( aPos, pPortion->GetNode()->GetText(), nTmpIndex, nL );
+ pOutDev->SetTextColor( aOldTextColor );
+ pOutDev->SetTextFillColor();
+ nTmpIndex = nTmpIndex + nL;
+ }
+
+ // 3) Bereich nach Selektion
+ if ( nTmpIndex < nEnd )
+ {
+ nL = nEnd-nTmpIndex;
+ aPos.X() = rStartPos.X() + ImpGetOutputOffset( nPara, pLine, nTmpIndex, nTmpIndex+nL );
+ pOutDev->DrawText( aPos, pPortion->GetNode()->GetText(), nTmpIndex, nEnd-nTmpIndex );
+ }
+ bDone = TRUE;
+ }
+ }
+ if ( !bDone )
+ {
+ aPos.X() = rStartPos.X() + ImpGetOutputOffset( nPara, pLine, nTmpIndex, nEnd );
+ pOutDev->DrawText( aPos, pPortion->GetNode()->GetText(), nTmpIndex, nEnd-nTmpIndex );
+ }
+ }
+
+ }
+ break;
+ case PORTIONKIND_TAB:
+ {
+ // Bei HideSelection() nur Range, pSelection = 0.
+ if ( pSelStart || pPaintRange )
+ {
+ Rectangle aTabArea( aTmpPos, Point( aTmpPos.X()+nTxtWidth, aTmpPos.Y()+mnCharHeight-1 ) );
+ BOOL bDone = FALSE;
+ if ( pSelStart )
+ {
+ // liegt der Tab in der Selektion???
+ TextPaM aTextStart( nPara, nIndex );
+ TextPaM aTextEnd( nPara, nIndex+1 );
+ if ( ( aTextStart < *pSelEnd ) && ( aTextEnd > *pSelStart ) )
+ {
+ Color aOldColor = pOutDev->GetFillColor();
+ pOutDev->SetFillColor( rStyleSettings.GetHighlightColor() );
+ pOutDev->DrawRect( aTabArea );
+ pOutDev->SetFillColor( aOldColor );
+ bDone = TRUE;
+ }
+ }
+ if ( !bDone )
+ {
+ pOutDev->Erase( aTabArea );
+ }
+ }
+#ifdef EDITDEBUG
+ Rectangle aTabArea( aTmpPos, Point( aTmpPos.X()+nTxtWidth, aTmpPos.Y()+mnCharHeight-1 ) );
+ Color aOldColor = pOutDev->GetFillColor();
+ pOutDev->SetFillColor( (y%2) ? COL_RED : COL_GREEN );
+ pOutDev->DrawRect( aTabArea );
+ pOutDev->SetFillColor( aOldColor );
+#endif
+ }
+ break;
+ default: DBG_ERROR( "ImpPaint: Unknown Portion-Type !" );
+ }
+ }
+
+ nIndex = nIndex + pTextPortion->GetLen();
+ }
+ }
+
+ nY += mnCharHeight;
+
+ if ( pPaintArea && ( nY >= pPaintArea->Bottom() ) )
+ break; // keine sichtbaren Aktionen mehr...
+ }
+ }
+ else
+ {
+ nY += nParaHeight;
+ }
+
+ if ( pPaintArea && ( nY > pPaintArea->Bottom() ) )
+ break; // keine sichtbaren Aktionen mehr...
+ }
+}
+
+BOOL TextEngine::CreateLines( ULONG nPara )
+{
+ // BOOL: Aenderung der Hoehe des Absatzes Ja/Nein - TRUE/FALSE
+
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ DBG_ASSERT( pTEParaPortion->IsInvalid(), "CreateLines: Portion nicht invalid!" );
+
+ USHORT nOldLineCount = pTEParaPortion->GetLines().Count();
+
+ // ---------------------------------------------------------------
+ // Schnelle Sonderbehandlung fuer leere Absaetze...
+ // ---------------------------------------------------------------
+ if ( pTEParaPortion->GetNode()->GetText().Len() == 0 )
+ {
+ // schnelle Sonderbehandlung...
+ if ( pTEParaPortion->GetTextPortions().Count() )
+ pTEParaPortion->GetTextPortions().Reset();
+ if ( pTEParaPortion->GetLines().Count() )
+ pTEParaPortion->GetLines().DeleteAndDestroy( 0, pTEParaPortion->GetLines().Count() );
+ CreateAndInsertEmptyLine( nPara );
+ pTEParaPortion->SetValid();
+ return nOldLineCount != pTEParaPortion->GetLines().Count();
+ }
+
+ // ---------------------------------------------------------------
+ // Initialisierung......
+ // ---------------------------------------------------------------
+
+ if ( pTEParaPortion->GetLines().Count() == 0 )
+ {
+ TextLine* pL = new TextLine;
+ pTEParaPortion->GetLines().Insert( pL, 0 );
+ }
+
+ const short nInvalidDiff = pTEParaPortion->GetInvalidDiff();
+ const USHORT nInvalidStart = pTEParaPortion->GetInvalidPosStart();
+ const USHORT nInvalidEnd = nInvalidStart + Abs( nInvalidDiff );
+ BOOL bQuickFormat = FALSE;
+
+ if ( !pTEParaPortion->GetWritingDirectionInfos().Count() )
+ ImpInitWritingDirections( nPara );
+
+ if ( pTEParaPortion->GetWritingDirectionInfos().Count() == 1 )
+ {
+ if ( pTEParaPortion->IsSimpleInvalid() && ( nInvalidDiff > 0 ) )
+ {
+ bQuickFormat = TRUE;
+ }
+ else if ( ( pTEParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff < 0 ) )
+ {
+ // pruefen, ob loeschen ueber Portiongrenzen erfolgte...
+ USHORT nStart = nInvalidStart; // DOPPELT !!!!!!!!!!!!!!!
+ USHORT nEnd = nStart - nInvalidDiff; // neg.
+ bQuickFormat = TRUE;
+ USHORT nPos = 0;
+ USHORT nPortions = pTEParaPortion->GetTextPortions().Count();
+ for ( USHORT nTP = 0; nTP < nPortions; nTP++ )
+ {
+ // Es darf kein Start/Ende im geloeschten Bereich liegen.
+ TETextPortion* const pTP = pTEParaPortion->GetTextPortions().GetObject( nTP );
+ nPos = nPos + pTP->GetLen();
+ if ( ( nPos > nStart ) && ( nPos < nEnd ) )
+ {
+ bQuickFormat = FALSE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( bQuickFormat )
+ RecalcTextPortion( nPara, nInvalidStart, nInvalidDiff );
+ else
+ CreateTextPortions( nPara, nInvalidStart );
+
+ // ---------------------------------------------------------------
+ // Zeile mit InvalidPos suchen, eine Zeile davor beginnen...
+ // Zeilen flaggen => nicht removen !
+ // ---------------------------------------------------------------
+
+ USHORT nLine = pTEParaPortion->GetLines().Count()-1;
+ for ( USHORT nL = 0; nL <= nLine; nL++ )
+ {
+ TextLine* pLine = pTEParaPortion->GetLines().GetObject( nL );
+ if ( pLine->GetEnd() > nInvalidStart )
+ {
+ nLine = nL;
+ break;
+ }
+ pLine->SetValid();
+ }
+ // Eine Zeile davor beginnen...
+ // Wenn ganz hinten getippt wird, kann sich die Zeile davor nicht aendern.
+ if ( nLine && ( !pTEParaPortion->IsSimpleInvalid() || ( nInvalidEnd < pNode->GetText().Len() ) || ( nInvalidDiff <= 0 ) ) )
+ nLine--;
+
+ TextLine* pLine = pTEParaPortion->GetLines().GetObject( nLine );
+
+ // ---------------------------------------------------------------
+ // Ab hier alle Zeilen durchformatieren...
+ // ---------------------------------------------------------------
+ USHORT nDelFromLine = 0xFFFF;
+ BOOL bLineBreak = FALSE;
+
+ USHORT nIndex = pLine->GetStart();
+ TextLine aSaveLine( *pLine );
+
+ Font aFont;
+
+ BOOL bCalcPortion = TRUE;
+
+ while ( nIndex < pNode->GetText().Len() )
+ {
+ BOOL bEOL = FALSE;
+ BOOL bEOC = FALSE;
+ USHORT nPortionStart = 0;
+ USHORT nPortionEnd = 0;
+
+ USHORT nTmpPos = nIndex;
+ USHORT nTmpPortion = pLine->GetStartPortion();
+ long nTmpWidth = mpDoc->GetLeftMargin();
+// long nXWidth = mnMaxTextWidth ? ( mnMaxTextWidth - mpDoc->GetLeftMargin() ) : 0x7FFFFFFF;
+ // Margin nicht abziehen, ist schon in TmpWidth enthalten.
+ long nXWidth = mnMaxTextWidth ? mnMaxTextWidth : 0x7FFFFFFF;
+ if ( nXWidth < nTmpWidth )
+ nXWidth = nTmpWidth;
+
+ // Portion suchen, die nicht mehr in Zeile passt....
+ TETextPortion* pPortion = 0;
+ BOOL bBrokenLine = FALSE;
+ bLineBreak = FALSE;
+
+ while ( ( nTmpWidth <= nXWidth ) && !bEOL && ( nTmpPortion < pTEParaPortion->GetTextPortions().Count() ) )
+ {
+ nPortionStart = nTmpPos;
+ pPortion = pTEParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ DBG_ASSERT( pPortion->GetLen(), "Leere Portion in CreateLines ?!" );
+ if ( pNode->GetText().GetChar( nTmpPos ) == '\t' )
+ {
+ long nCurPos = nTmpWidth-mpDoc->GetLeftMargin();
+ nTmpWidth = ((nCurPos/mnDefTab)+1)*mnDefTab+mpDoc->GetLeftMargin();
+ pPortion->GetWidth() = nTmpWidth - nCurPos - mpDoc->GetLeftMargin();
+ // Wenn dies das erste Token in der Zeile ist, und
+ // nTmpWidth > aPaperSize.Width, habe ich eine Endlos-Schleife!
+ if ( ( nTmpWidth >= nXWidth ) && ( nTmpPortion == pLine->GetStartPortion() ) )
+ {
+ // Aber was jetzt ? Tab passend machen!
+ pPortion->GetWidth() = nXWidth-1;
+ nTmpWidth = pPortion->GetWidth();
+ bEOL = TRUE;
+ bBrokenLine = TRUE;
+ }
+ pPortion->GetKind() = PORTIONKIND_TAB;
+ }
+ else
+ {
+
+ if ( bCalcPortion || !pPortion->HasValidSize() )
+ pPortion->GetWidth() = (long)CalcTextWidth( nPara, nTmpPos, pPortion->GetLen() );
+ nTmpWidth += pPortion->GetWidth();
+
+ pPortion->GetRightToLeft() = ImpGetRightToLeft( nPara, nTmpPos+1 );
+ pPortion->GetKind() = PORTIONKIND_TEXT;
+ }
+
+ nTmpPos = nTmpPos + pPortion->GetLen();
+ nPortionEnd = nTmpPos;
+ nTmpPortion++;
+ }
+
+ // das war evtl. eine Portion zu weit:
+ BOOL bFixedEnd = FALSE;
+ if ( nTmpWidth > nXWidth )
+ {
+ nPortionEnd = nTmpPos;
+ nTmpPos = nTmpPos - pPortion->GetLen();
+ nPortionStart = nTmpPos;
+ nTmpPortion--;
+ bEOL = FALSE;
+ bEOC = FALSE;
+
+ nTmpWidth -= pPortion->GetWidth();
+ if ( pPortion->GetKind() == PORTIONKIND_TAB )
+ {
+ bEOL = TRUE;
+ bFixedEnd = TRUE;
+ }
+ }
+ else
+ {
+ bEOL = TRUE;
+ bEOC = TRUE;
+ pLine->SetEnd( nPortionEnd );
+ DBG_ASSERT( pTEParaPortion->GetTextPortions().Count(), "Keine TextPortions?" );
+ pLine->SetEndPortion( (USHORT)pTEParaPortion->GetTextPortions().Count() - 1 );
+ }
+
+ if ( bFixedEnd )
+ {
+ pLine->SetEnd( nPortionStart );
+ pLine->SetEndPortion( nTmpPortion-1 );
+ }
+ else if ( bLineBreak || bBrokenLine )
+ {
+ pLine->SetEnd( nPortionStart+1 );
+ pLine->SetEndPortion( nTmpPortion-1 );
+ bEOC = FALSE; // wurde oben gesetzt, vielleich mal die if's umstellen?
+ }
+ else if ( !bEOL )
+ {
+ DBG_ASSERT( (nPortionEnd-nPortionStart) == pPortion->GetLen(), "Doch eine andere Portion?!" );
+ long nRemainingWidth = mnMaxTextWidth - nTmpWidth;
+ ImpBreakLine( nPara, pLine, pPortion, nPortionStart, nRemainingWidth );
+ }
+
+ if ( ( ImpGetAlign() == TXTALIGN_CENTER ) || ( ImpGetAlign() == TXTALIGN_RIGHT ) )
+ {
+ // Ausrichten...
+ long nTextWidth = 0;
+ for ( USHORT nTP = pLine->GetStartPortion(); nTP <= pLine->GetEndPortion(); nTP++ )
+ {
+ TETextPortion* pTextPortion = pTEParaPortion->GetTextPortions().GetObject( nTP );
+ nTextWidth += pTextPortion->GetWidth();
+ }
+ long nSpace = mnMaxTextWidth - nTextWidth;
+ if ( nSpace > 0 )
+ {
+ if ( ImpGetAlign() == TXTALIGN_CENTER )
+ pLine->SetStartX( (USHORT)(nSpace / 2) );
+ else // TXTALIGN_RIGHT
+ pLine->SetStartX( (USHORT)nSpace );
+ }
+ }
+ else
+ {
+ pLine->SetStartX( mpDoc->GetLeftMargin() );
+ }
+
+ // -----------------------------------------------------------------
+ // pruefen, ob die Zeile neu ausgegeben werden muss...
+ // -----------------------------------------------------------------
+ pLine->SetInvalid();
+
+ if ( pTEParaPortion->IsSimpleInvalid() )
+ {
+ // Aenderung durch einfache Textaenderung...
+ // Formatierung nicht abbrechen, da Portions evtl. wieder
+ // gesplittet werden muessen!
+ // Wenn irgendwann mal abbrechbar, dann fogende Zeilen Validieren!
+ // Aber ggf. als Valid markieren, damit weniger Ausgabe...
+ if ( pLine->GetEnd() < nInvalidStart )
+ {
+ if ( *pLine == aSaveLine )
+ {
+ pLine->SetValid();
+ }
+ }
+ else
+ {
+ USHORT nStart = pLine->GetStart();
+ USHORT nEnd = pLine->GetEnd();
+
+ if ( nStart > nInvalidEnd )
+ {
+ if ( ( ( nStart-nInvalidDiff ) == aSaveLine.GetStart() ) &&
+ ( ( nEnd-nInvalidDiff ) == aSaveLine.GetEnd() ) )
+ {
+ pLine->SetValid();
+ if ( bCalcPortion && bQuickFormat )
+ {
+ bCalcPortion = FALSE;
+ pTEParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
+ break;
+ }
+ }
+ }
+ else if ( bQuickFormat && ( nEnd > nInvalidEnd) )
+ {
+ // Wenn die ungueltige Zeile so endet, dass die naechste an
+ // der 'gleichen' Textstelle wie vorher beginnt, also nicht
+ // anders umgebrochen wird, brauche ich dort auch nicht die
+ // textbreiten neu bestimmen:
+ if ( nEnd == ( aSaveLine.GetEnd() + nInvalidDiff ) )
+ {
+ bCalcPortion = FALSE;
+ pTEParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
+ break;
+ }
+ }
+ }
+ }
+
+ nIndex = pLine->GetEnd(); // naechste Zeile Start = letzte Zeile Ende
+ // weil nEnd hinter das letzte Zeichen zeigt!
+
+ USHORT nEndPortion = pLine->GetEndPortion();
+
+ // Naechste Zeile oder ggf. neue Zeile....
+ pLine = 0;
+ if ( nLine < pTEParaPortion->GetLines().Count()-1 )
+ pLine = pTEParaPortion->GetLines().GetObject( ++nLine );
+ if ( pLine && ( nIndex >= pNode->GetText().Len() ) )
+ {
+ nDelFromLine = nLine;
+ break;
+ }
+ if ( !pLine && ( nIndex < pNode->GetText().Len() ) )
+ {
+ pLine = new TextLine;
+ pTEParaPortion->GetLines().Insert( pLine, ++nLine );
+ }
+ if ( pLine )
+ {
+ aSaveLine = *pLine;
+ pLine->SetStart( nIndex );
+ pLine->SetEnd( nIndex );
+ pLine->SetStartPortion( nEndPortion+1 );
+ pLine->SetEndPortion( nEndPortion+1 );
+ }
+ } // while ( Index < Len )
+
+ if ( nDelFromLine != 0xFFFF )
+ pTEParaPortion->GetLines().DeleteAndDestroy( nDelFromLine, pTEParaPortion->GetLines().Count() - nDelFromLine );
+
+ DBG_ASSERT( pTEParaPortion->GetLines().Count(), "Keine Zeile nach CreateLines!" );
+
+ if ( bLineBreak == TRUE )
+ CreateAndInsertEmptyLine( nPara );
+
+ pTEParaPortion->SetValid();
+
+ return nOldLineCount != pTEParaPortion->GetLines().Count();
+}
+
+String TextEngine::GetWord( const TextPaM& rCursorPos, TextPaM* pStartOfWord )
+{
+ String aWord;
+ if ( rCursorPos.GetPara() < mpDoc->GetNodes().Count() )
+ {
+ TextSelection aSel( rCursorPos );
+ TextNode* pNode = mpDoc->GetNodes().GetObject( rCursorPos.GetPara() );
+ uno::Reference < i18n::XBreakIterator > xBI = GetBreakIterator();
+ i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), rCursorPos.GetIndex(), GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ aSel.GetStart().GetIndex() = (USHORT)aBoundary.startPos;
+ aSel.GetEnd().GetIndex() = (USHORT)aBoundary.endPos;
+ aWord = pNode->GetText().Copy( aSel.GetStart().GetIndex(), aSel.GetEnd().GetIndex() - aSel.GetStart().GetIndex() );
+ if ( pStartOfWord )
+ *pStartOfWord = aSel.GetStart();
+ }
+ return aWord;
+}
+
+BOOL TextEngine::Read( SvStream& rInput, const TextSelection* pSel )
+{
+ BOOL bUpdate = GetUpdateMode();
+ SetUpdateMode( FALSE );
+
+ UndoActionStart( TEXTUNDO_READ );
+ TextSelection aSel;
+ if ( pSel )
+ aSel = *pSel;
+ else
+ {
+ ULONG nParas = mpDoc->GetNodes().Count();
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nParas - 1 );
+ aSel = TextPaM( nParas-1 , pNode->GetText().Len() );
+ }
+
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteText( aSel );
+
+ ByteString aLine;
+ BOOL bDone = rInput.ReadLine( aLine );
+ String aTmpStr( aLine, rInput.GetStreamCharSet() ), aStr;
+ while ( bDone )
+ {
+ aSel = ImpInsertText( aSel, aTmpStr );
+ bDone = rInput.ReadLine( aLine );
+ aTmpStr = String( aLine, rInput.GetStreamCharSet() );
+ if ( bDone )
+ aSel = ImpInsertParaBreak( aSel.GetEnd() );
+ }
+
+ UndoActionEnd( TEXTUNDO_READ );
+
+ TextSelection aNewSel( aSel.GetEnd(), aSel.GetEnd() );
+
+ // Damit bei FormatAndUpdate nicht auf die ungueltige Selektion zugegriffen wird.
+ if ( GetActiveView() )
+ GetActiveView()->ImpSetSelection( aNewSel );
+
+ SetUpdateMode( bUpdate );
+ FormatAndUpdate( GetActiveView() );
+
+ return rInput.GetError() ? FALSE : TRUE;
+}
+
+BOOL TextEngine::Write( SvStream& rOutput, const TextSelection* pSel, BOOL bHTML )
+{
+ TextSelection aSel;
+ if ( pSel )
+ aSel = *pSel;
+ else
+ {
+ ULONG nParas = mpDoc->GetNodes().Count();
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nParas - 1 );
+ aSel.GetStart() = TextPaM( 0, 0 );
+ aSel.GetEnd() = TextPaM( nParas-1, pNode->GetText().Len() );
+ }
+
+ if ( bHTML )
+ {
+ rOutput.WriteLine( "<HTML>" );
+ rOutput.WriteLine( "<BODY>" );
+ }
+
+ for ( ULONG nPara = aSel.GetStart().GetPara(); nPara <= aSel.GetEnd().GetPara(); nPara++ )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+
+ USHORT nStartPos = 0;
+ USHORT nEndPos = pNode->GetText().Len();
+ if ( nPara == aSel.GetStart().GetPara() )
+ nStartPos = aSel.GetStart().GetIndex();
+ if ( nPara == aSel.GetEnd().GetPara() )
+ nEndPos = aSel.GetEnd().GetIndex();
+
+ String aText;
+ if ( !bHTML )
+ {
+ aText = pNode->GetText().Copy( nStartPos, nEndPos-nStartPos );
+ }
+ else
+ {
+ aText.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "<P STYLE=\"margin-bottom: 0cm\">" ) );
+
+ if ( nStartPos == nEndPos )
+ {
+ // Leerzeilen werden von Writer wegoptimiert
+ aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "<BR>" ) );
+ }
+ else
+ {
+ USHORT nTmpStart = nStartPos;
+ USHORT nTmpEnd = nEndPos;
+ do
+ {
+ TextCharAttrib* pAttr = pNode->GetCharAttribs().FindNextAttrib( TEXTATTR_HYPERLINK, nTmpStart, nEndPos );
+ nTmpEnd = pAttr ? pAttr->GetStart() : nEndPos;
+
+ // Text vor dem Attribut
+ aText += pNode->GetText().Copy( nTmpStart, nTmpEnd-nTmpStart );
+
+ if ( pAttr )
+ {
+ nTmpEnd = Min( pAttr->GetEnd(), nEndPos );
+
+ // z.B. <A HREF="http://www.mopo.de/">Morgenpost</A>
+ aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "<A HREF=\"" ) );
+ aText += ((const TextAttribHyperLink&) pAttr->GetAttr() ).GetURL();
+ aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\">" ) );
+ nTmpStart = pAttr->GetStart();
+ aText += pNode->GetText().Copy( nTmpStart, nTmpEnd-nTmpStart );
+ aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "</A>" ) );
+
+ nTmpStart = pAttr->GetEnd();
+ }
+ } while ( nTmpEnd < nEndPos );
+ }
+
+ aText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "</P>" ) );
+ }
+ rOutput.WriteLine( ByteString( aText, rOutput.GetStreamCharSet() ) );
+ }
+
+ if ( bHTML )
+ {
+ rOutput.WriteLine( "</BODY>" );
+ rOutput.WriteLine( "</HTML>" );
+ }
+
+ return rOutput.GetError() ? FALSE : TRUE;
+}
+
+void TextEngine::RemoveAttribs( ULONG nPara, BOOL bIdleFormatAndUpdate )
+{
+ if ( nPara < mpDoc->GetNodes().Count() )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ if ( pNode->GetCharAttribs().Count() )
+ {
+ pNode->GetCharAttribs().Clear( TRUE );
+
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ pTEParaPortion->MarkSelectionInvalid( 0, pNode->GetText().Len() );
+
+ mbFormatted = FALSE;
+
+ if ( bIdleFormatAndUpdate )
+ IdleFormatAndUpdate( NULL, 0xFFFF );
+ else
+ FormatAndUpdate( NULL );
+ }
+ }
+}
+void TextEngine::RemoveAttribs( ULONG nPara, USHORT nWhich, BOOL bIdleFormatAndUpdate )
+{
+ if ( nPara < mpDoc->GetNodes().Count() )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ if ( pNode->GetCharAttribs().Count() )
+ {
+ TextCharAttribList& rAttribs = pNode->GetCharAttribs();
+ USHORT nAttrCount = rAttribs.Count();
+ for(USHORT nAttr = nAttrCount; nAttr; --nAttr)
+ {
+ if(rAttribs.GetAttrib( nAttr - 1 )->Which() == nWhich)
+ rAttribs.RemoveAttrib( nAttr -1 );
+ }
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ pTEParaPortion->MarkSelectionInvalid( 0, pNode->GetText().Len() );
+ mbFormatted = FALSE;
+ if(bIdleFormatAndUpdate)
+ IdleFormatAndUpdate( NULL, 0xFFFF );
+ else
+ FormatAndUpdate( NULL );
+ }
+ }
+}
+void TextEngine::RemoveAttrib( ULONG nPara, const TextCharAttrib& rAttrib )
+{
+ if ( nPara < mpDoc->GetNodes().Count() )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ if ( pNode->GetCharAttribs().Count() )
+ {
+ TextCharAttribList& rAttribs = pNode->GetCharAttribs();
+ USHORT nAttrCount = rAttribs.Count();
+ for(USHORT nAttr = nAttrCount; nAttr; --nAttr)
+ {
+ if(rAttribs.GetAttrib( nAttr - 1 ) == &rAttrib)
+ {
+ rAttribs.RemoveAttrib( nAttr -1 );
+ break;
+ }
+ }
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+ pTEParaPortion->MarkSelectionInvalid( 0, pNode->GetText().Len() );
+ mbFormatted = FALSE;
+ FormatAndUpdate( NULL );
+ }
+ }
+}
+
+void TextEngine::SetAttrib( const TextAttrib& rAttr, ULONG nPara, USHORT nStart, USHORT nEnd, BOOL bIdleFormatAndUpdate )
+{
+ // Es wird hier erstmal nicht geprueft, ob sich Attribute ueberlappen!
+ // Diese Methode ist erstmal nur fuer einen Editor, der fuer eine Zeile
+ // _schnell_ das Syntax-Highlight einstellen will.
+
+ // Da die TextEngine z.Zt fuer Editoren gedacht ist gibt es auch kein
+ // Undo fuer Attribute!
+
+ if ( nPara < mpDoc->GetNodes().Count() )
+ {
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ TEParaPortion* pTEParaPortion = mpTEParaPortions->GetObject( nPara );
+
+ USHORT nMax = pNode->GetText().Len();
+ if ( nStart > nMax )
+ nStart = nMax;
+ if ( nEnd > nMax )
+ nEnd = nMax;
+
+ pNode->GetCharAttribs().InsertAttrib( new TextCharAttrib( rAttr, nStart, nEnd ) );
+ pTEParaPortion->MarkSelectionInvalid( nStart, nEnd );
+
+ mbFormatted = FALSE;
+ if ( bIdleFormatAndUpdate )
+ IdleFormatAndUpdate( NULL, 0xFFFF );
+ else
+ FormatAndUpdate( NULL );
+ }
+}
+
+void TextEngine::SetTextAlign( TxtAlign eAlign )
+{
+ if ( eAlign != meAlign )
+ {
+ meAlign = eAlign;
+ FormatFullDoc();
+ UpdateViews();
+ }
+}
+
+
+void TextEngine::ValidateSelection( TextSelection& rSel ) const
+{
+ ValidatePaM( rSel.GetStart() );
+ ValidatePaM( rSel.GetEnd() );
+}
+
+void TextEngine::ValidatePaM( TextPaM& rPaM ) const
+{
+ ULONG nMaxPara = mpDoc->GetNodes().Count() - 1;
+ if ( rPaM.GetPara() > nMaxPara )
+ {
+ rPaM.GetPara() = nMaxPara;
+ rPaM.GetIndex() = 0xFFFF;
+ }
+
+ USHORT nMaxIndex = GetTextLen( rPaM.GetPara() );
+ if ( rPaM.GetIndex() > nMaxIndex )
+ rPaM.GetIndex() = nMaxIndex;
+}
+
+
+// Status & Selektionsanpassung
+
+void TextEngine::ImpParagraphInserted( ULONG nPara )
+{
+ // Die aktive View braucht nicht angepasst werden, aber bei allen
+ // passiven muss die Selektion angepasst werden:
+ if ( mpViews->Count() > 1 )
+ {
+ for ( USHORT nView = mpViews->Count(); nView; )
+ {
+ TextView* pView = mpViews->GetObject( --nView );
+ if ( pView != GetActiveView() )
+ {
+// BOOL bInvers = pView->maSelection.GetEnd() < pView->maSelection.GetStart();
+// TextPaM& rMin = !bInvers ? pView->maSelection.GetStart(): pView->maSelection.GetEnd();
+// TextPaM& rMax = bInvers ? pView->maSelection.GetStart() : pView->maSelection.GetEnd();
+//
+// if ( rMin.GetPara() >= nPara )
+// rMin.GetPara()++;
+// if ( rMax.GetPara() >= nPara )
+// rMax.GetPara()++;
+ for ( int n = 0; n <= 1; n++ )
+ {
+ TextPaM& rPaM = n ? pView->GetSelection().GetStart(): pView->GetSelection().GetEnd();
+ if ( rPaM.GetPara() >= nPara )
+ rPaM.GetPara()++;
+ }
+ }
+ }
+ }
+ Broadcast( TextHint( TEXT_HINT_PARAINSERTED, nPara ) );
+}
+
+void TextEngine::ImpParagraphRemoved( ULONG nPara )
+{
+ if ( mpViews->Count() > 1 )
+ {
+ for ( USHORT nView = mpViews->Count(); nView; )
+ {
+ TextView* pView = mpViews->GetObject( --nView );
+ if ( pView != GetActiveView() )
+ {
+ ULONG nParas = mpDoc->GetNodes().Count();
+ for ( int n = 0; n <= 1; n++ )
+ {
+ TextPaM& rPaM = n ? pView->GetSelection().GetStart(): pView->GetSelection().GetEnd();
+ if ( rPaM.GetPara() > nPara )
+ rPaM.GetPara()--;
+ else if ( rPaM.GetPara() == nPara )
+ {
+ rPaM.GetIndex() = 0;
+ if ( rPaM.GetPara() >= nParas )
+ rPaM.GetPara()--;
+ }
+ }
+ }
+ }
+ }
+ Broadcast( TextHint( TEXT_HINT_PARAREMOVED, nPara ) );
+}
+
+void TextEngine::ImpCharsRemoved( ULONG nPara, USHORT nPos, USHORT nChars )
+{
+ if ( mpViews->Count() > 1 )
+ {
+ for ( USHORT nView = mpViews->Count(); nView; )
+ {
+ TextView* pView = mpViews->GetObject( --nView );
+ if ( pView != GetActiveView() )
+ {
+ USHORT nEnd = nPos+nChars;
+ for ( int n = 0; n <= 1; n++ )
+ {
+ TextPaM& rPaM = n ? pView->GetSelection().GetStart(): pView->GetSelection().GetEnd();
+ if ( rPaM.GetPara() == nPara )
+ {
+ if ( rPaM.GetIndex() > nEnd )
+ rPaM.GetIndex() = rPaM.GetIndex() - nChars;
+ else if ( rPaM.GetIndex() > nPos )
+ rPaM.GetIndex() = nPos;
+ }
+ }
+ }
+ }
+ }
+ Broadcast( TextHint( TEXT_HINT_PARACONTENTCHANGED, nPara ) );
+}
+
+void TextEngine::ImpCharsInserted( ULONG nPara, USHORT nPos, USHORT nChars )
+{
+ if ( mpViews->Count() > 1 )
+ {
+ for ( USHORT nView = mpViews->Count(); nView; )
+ {
+ TextView* pView = mpViews->GetObject( --nView );
+ if ( pView != GetActiveView() )
+ {
+ for ( int n = 0; n <= 1; n++ )
+ {
+ TextPaM& rPaM = n ? pView->GetSelection().GetStart(): pView->GetSelection().GetEnd();
+ if ( rPaM.GetPara() == nPara )
+ {
+ if ( rPaM.GetIndex() >= nPos )
+ rPaM.GetIndex() = rPaM.GetIndex() + nChars;
+ }
+ }
+ }
+ }
+ }
+ Broadcast( TextHint( TEXT_HINT_PARACONTENTCHANGED, nPara ) );
+}
+
+void TextEngine::ImpFormattingParagraph( ULONG nPara )
+{
+ Broadcast( TextHint( TEXT_HINT_FORMATPARA, nPara ) );
+}
+
+void TextEngine::ImpTextHeightChanged()
+{
+ Broadcast( TextHint( TEXT_HINT_TEXTHEIGHTCHANGED ) );
+}
+
+void TextEngine::ImpTextFormatted()
+{
+ Broadcast( TextHint( TEXT_HINT_TEXTFORMATTED ) );
+}
+
+void TextEngine::Draw( OutputDevice* pDev, const Point& rPos )
+{
+ ImpPaint( pDev, rPos, NULL );
+}
+
+void TextEngine::SetLeftMargin( USHORT n )
+{
+ mpDoc->SetLeftMargin( n );
+}
+
+USHORT TextEngine::GetLeftMargin() const
+{
+ return mpDoc->GetLeftMargin();
+}
+
+uno::Reference< i18n::XBreakIterator > TextEngine::GetBreakIterator()
+{
+ if ( !mxBreakIterator.is() )
+ mxBreakIterator = vcl::unohelper::CreateBreakIterator();
+ DBG_ASSERT( mxBreakIterator.is(), "Could not create BreakIterator" );
+ return mxBreakIterator;
+}
+
+void TextEngine::SetLocale( const ::com::sun::star::lang::Locale& rLocale )
+{
+ maLocale = rLocale;
+ delete mpLocaleDataWrapper;
+ mpLocaleDataWrapper = NULL;
+}
+
+::com::sun::star::lang::Locale TextEngine::GetLocale()
+{
+ if ( !maLocale.Language.getLength() )
+ {
+ maLocale = Application::GetSettings().GetUILocale();
+ }
+ return maLocale;
+}
+
+LocaleDataWrapper* TextEngine::ImpGetLocaleDataWrapper()
+{
+ if ( !mpLocaleDataWrapper )
+ mpLocaleDataWrapper = new LocaleDataWrapper( vcl::unohelper::GetMultiServiceFactory(), GetLocale() );
+
+ return mpLocaleDataWrapper;
+}
+
+void TextEngine::SetRightToLeft( BOOL bR2L )
+{
+ if ( mbRightToLeft != bR2L )
+ {
+ mbRightToLeft = bR2L;
+ meAlign = bR2L ? TXTALIGN_RIGHT : TXTALIGN_LEFT;
+ FormatFullDoc();
+ UpdateViews();
+ }
+}
+
+void TextEngine::ImpInitWritingDirections( ULONG nPara )
+{
+ TEParaPortion* pParaPortion = mpTEParaPortions->GetObject( nPara );
+ TEWritingDirectionInfos& rInfos = pParaPortion->GetWritingDirectionInfos();
+ rInfos.Remove( 0, rInfos.Count() );
+
+ if ( pParaPortion->GetNode()->GetText().Len() )
+ {
+ const UBiDiLevel nBidiLevel = IsRightToLeft() ? 1 /*RTL*/ : 0 /*LTR*/;
+ String aText( pParaPortion->GetNode()->GetText() );
+
+ //
+ // Bidi functions from icu 2.0
+ //
+ UErrorCode nError = U_ZERO_ERROR;
+ UBiDi* pBidi = ubidi_openSized( aText.Len(), 0, &nError );
+ nError = U_ZERO_ERROR;
+
+ ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(aText.GetBuffer()), aText.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
+ nError = U_ZERO_ERROR;
+
+ long nCount = ubidi_countRuns( pBidi, &nError );
+
+ int32_t nStart = 0;
+ int32_t nEnd;
+ UBiDiLevel nCurrDir;
+
+ for ( USHORT nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ ubidi_getLogicalRun( pBidi, nStart, &nEnd, &nCurrDir );
+ rInfos.Insert( TEWritingDirectionInfo( nCurrDir, (USHORT)nStart, (USHORT)nEnd ), rInfos.Count() );
+ nStart = nEnd;
+ }
+
+ ubidi_close( pBidi );
+ }
+
+ // No infos mean no CTL and default dir is L2R...
+ if ( !rInfos.Count() )
+ rInfos.Insert( TEWritingDirectionInfo( 0, 0, (USHORT)pParaPortion->GetNode()->GetText().Len() ), rInfos.Count() );
+
+}
+
+BYTE TextEngine::ImpGetRightToLeft( ULONG nPara, USHORT nPos, USHORT* pStart, USHORT* pEnd )
+{
+ BYTE nRightToLeft = 0;
+
+ TextNode* pNode = mpDoc->GetNodes().GetObject( nPara );
+ if ( pNode && pNode->GetText().Len() )
+ {
+ TEParaPortion* pParaPortion = mpTEParaPortions->GetObject( nPara );
+ if ( !pParaPortion->GetWritingDirectionInfos().Count() )
+ ImpInitWritingDirections( nPara );
+
+ TEWritingDirectionInfos& rDirInfos = pParaPortion->GetWritingDirectionInfos();
+ for ( USHORT n = 0; n < rDirInfos.Count(); n++ )
+ {
+ if ( ( rDirInfos[n].nStartPos <= nPos ) && ( rDirInfos[n].nEndPos >= nPos ) )
+ {
+ nRightToLeft = rDirInfos[n].nType;
+ if ( pStart )
+ *pStart = rDirInfos[n].nStartPos;
+ if ( pEnd )
+ *pEnd = rDirInfos[n].nEndPos;
+ break;
+ }
+ }
+ }
+ return nRightToLeft;
+}
+
+long TextEngine::ImpGetPortionXOffset( ULONG nPara, TextLine* pLine, USHORT nTextPortion )
+{
+ long nX = pLine->GetStartX();
+
+ TEParaPortion* pParaPortion = mpTEParaPortions->GetObject( nPara );
+
+ for ( USHORT i = pLine->GetStartPortion(); i < nTextPortion; i++ )
+ {
+ TETextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( i );
+ nX += pPortion->GetWidth();
+ }
+
+ TETextPortion* pDestPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ if ( pDestPortion->GetKind() != PORTIONKIND_TAB )
+ {
+ if ( !IsRightToLeft() && pDestPortion->GetRightToLeft() )
+ {
+ // Portions behind must be added, visual before this portion
+ sal_uInt16 nTmpPortion = nTextPortion+1;
+ while ( nTmpPortion <= pLine->GetEndPortion() )
+ {
+ TETextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( pNextTextPortion->GetRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX += pNextTextPortion->GetWidth();
+ else
+ break;
+ nTmpPortion++;
+ }
+ // Portions before must be removed, visual behind this portion
+ nTmpPortion = nTextPortion;
+ while ( nTmpPortion > pLine->GetStartPortion() )
+ {
+ --nTmpPortion;
+ TETextPortion* pPrevTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( pPrevTextPortion->GetRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX -= pPrevTextPortion->GetWidth();
+ else
+ break;
+ }
+ }
+ else if ( IsRightToLeft() && !pDestPortion->IsRightToLeft() )
+ {
+ // Portions behind must be removed, visual behind this portion
+ sal_uInt16 nTmpPortion = nTextPortion+1;
+ while ( nTmpPortion <= pLine->GetEndPortion() )
+ {
+ TETextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( !pNextTextPortion->IsRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX += pNextTextPortion->GetWidth();
+ else
+ break;
+ nTmpPortion++;
+ }
+ // Portions before must be added, visual before this portion
+ nTmpPortion = nTextPortion;
+ while ( nTmpPortion > pLine->GetStartPortion() )
+ {
+ --nTmpPortion;
+ TETextPortion* pPrevTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( !pPrevTextPortion->IsRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX -= pPrevTextPortion->GetWidth();
+ else
+ break;
+ }
+ }
+ }
+/*
+ if ( IsRightToLeft() )
+ {
+ // Switch X postions...
+ DBG_ASSERT( GetMaxTextWidth(), "GetPortionXOffset - max text width?!" );
+ DBG_ASSERT( nX <= (long)GetMaxTextWidth(), "GetPortionXOffset - position out of paper size!" );
+ nX = GetMaxTextWidth() - nX;
+ nX -= pDestPortion->GetWidth();
+ }
+*/
+
+ return nX;
+}
+
+void TextEngine::ImpInitLayoutMode( OutputDevice* pOutDev, BOOL bDrawingR2LPortion )
+{
+ ULONG nLayoutMode = pOutDev->GetLayoutMode();
+
+ nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_COMPLEX_DISABLED | TEXT_LAYOUT_BIDI_STRONG );
+ if ( bDrawingR2LPortion )
+ nLayoutMode |= TEXT_LAYOUT_BIDI_RTL;
+
+ pOutDev->SetLayoutMode( nLayoutMode );
+}
+
+TxtAlign TextEngine::ImpGetAlign() const
+{
+ TxtAlign eAlign = meAlign;
+ if ( IsRightToLeft() )
+ {
+ if ( eAlign == TXTALIGN_LEFT )
+ eAlign = TXTALIGN_RIGHT;
+ else if ( eAlign == TXTALIGN_RIGHT )
+ eAlign = TXTALIGN_LEFT;
+ }
+ return eAlign;
+}
+
+long TextEngine::ImpGetOutputOffset( ULONG nPara, TextLine* pLine, USHORT nIndex, USHORT nIndex2 )
+{
+ TEParaPortion* pPortion = mpTEParaPortions->GetObject( nPara );
+
+ USHORT nPortionStart;
+ USHORT nPortion = pPortion->GetTextPortions().FindPortion( nIndex, nPortionStart, TRUE );
+
+ TETextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( nPortion );
+
+ long nX;
+
+ if ( ( nIndex == nPortionStart ) && ( nIndex == nIndex2 ) )
+ {
+ // Output of full portion, so we need portion x offset.
+ // Use ImpGetPortionXOffset, because GetXPos may deliver left or right position from portioon, depending on R2L, L2R
+ nX = ImpGetPortionXOffset( nPara, pLine, nPortion );
+ if ( IsRightToLeft() )
+ {
+ nX = -nX -pTextPortion->GetWidth();
+ }
+ }
+ else
+ {
+ nX = ImpGetXPos( nPara, pLine, nIndex, nIndex == nPortionStart );
+ if ( nIndex2 != nIndex )
+ {
+ long nX2 = ImpGetXPos( nPara, pLine, nIndex2, FALSE );
+ if ( ( !IsRightToLeft() && ( nX2 < nX ) ) ||
+ ( IsRightToLeft() && ( nX2 > nX ) ) )
+ {
+ nX = nX2;
+ }
+ }
+ if ( IsRightToLeft() )
+ {
+ nX = -nX;
+ }
+ }
+
+ return nX;
+}
diff --git a/svtools/source/edit/textund2.hxx b/svtools/source/edit/textund2.hxx
new file mode 100644
index 000000000000..18cf9331328e
--- /dev/null
+++ b/svtools/source/edit/textund2.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 _TEXTUND2_HXX
+#define _TEXTUND2_HXX
+
+#include <textundo.hxx>
+
+
+class TextUndoDelPara : public TextUndo
+{
+private:
+ BOOL mbDelObject;
+ ULONG mnPara;
+ TextNode* mpNode; // Zeigt auf das gueltige, nicht zerstoerte Objekt!
+
+public:
+ TYPEINFO();
+ TextUndoDelPara( TextEngine* pTextEngine, TextNode* pNode, ULONG nPara );
+ ~TextUndoDelPara();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+
+class TextUndoConnectParas : public TextUndo
+{
+private:
+ ULONG mnPara;
+ USHORT mnSepPos;
+
+public:
+ TYPEINFO();
+ TextUndoConnectParas( TextEngine* pTextEngine, ULONG nPara, USHORT nSepPos );
+ ~TextUndoConnectParas();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+
+class TextUndoSplitPara : public TextUndo
+{
+private:
+ ULONG mnPara;
+ USHORT mnSepPos;
+
+public:
+ TYPEINFO();
+ TextUndoSplitPara( TextEngine* pTextEngine, ULONG nPara, USHORT nSepPos );
+ ~TextUndoSplitPara();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+
+class TextUndoInsertChars : public TextUndo
+{
+private:
+ TextPaM maTextPaM;
+ String maText;
+
+public:
+ TYPEINFO();
+ TextUndoInsertChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const String& rStr );
+
+// const TextPaM& GetTextPaM() { return aTextPaM; }
+// String& GetStr() { return aText; }
+
+ virtual void Undo();
+ virtual void Redo();
+
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+};
+
+
+class TextUndoRemoveChars : public TextUndo
+{
+private:
+ TextPaM maTextPaM;
+ String maText;
+
+public:
+ TYPEINFO();
+ TextUndoRemoveChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const String& rStr );
+
+// const TextPaM& GetTextPaM() { return aTextPaM; }
+// String& GetStr() { return aText; }
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+
+class TextUndoSetAttribs: public TextUndo
+{
+private:
+ TextSelection maSelection;
+// SfxItemSet aNewAttribs;
+// TextInfoArray aPrevAttribs;
+// BYTE nSpecial;
+// BOOL bSetIsRemove;
+// USHORT nRemoveWhich;
+//
+// void ImpSetSelection( TextView* pView );
+
+
+public:
+ TYPEINFO();
+ TextUndoSetAttribs( TextEngine* pTextEngine, const TextSelection& rESel );
+ ~TextUndoSetAttribs();
+
+// TextInfoArray& GetTextInfos() { return aPrevAttribs; }
+// SfxItemSet& GetNewAttribs() { return aNewAttribs; }
+// void SetSpecial( BYTE n ) { nSpecial = n; }
+// void SetRemoveAttribs( BOOL b ) { bSetIsRemove = b; }
+// void SetRemoveWhich( USHORT n ) { nRemoveWhich = n; }
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+#endif // _TEXTUND2_HXX
diff --git a/svtools/source/edit/textundo.cxx b/svtools/source/edit/textundo.cxx
new file mode 100644
index 000000000000..4c243de16c31
--- /dev/null
+++ b/svtools/source/edit/textundo.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_svtools.hxx"
+
+#include <svtools/texteng.hxx>
+#include <svtools/textview.hxx>
+#include <textundo.hxx>
+#include <textund2.hxx>
+#include <svtools/textdata.hxx>
+#include <textdoc.hxx>
+#include <textdat2.hxx>
+
+TYPEINIT1( TextUndo, SfxUndoAction );
+TYPEINIT1( TextUndoDelPara, TextUndo );
+TYPEINIT1( TextUndoConnectParas, TextUndo );
+TYPEINIT1( TextUndoSplitPara, TextUndo );
+TYPEINIT1( TextUndoInsertChars, TextUndo );
+TYPEINIT1( TextUndoRemoveChars, TextUndo );
+TYPEINIT1( TextUndoSetAttribs, TextUndo );
+
+
+TextUndoManager::TextUndoManager( TextEngine* p )
+{
+ mpTextEngine = p;
+}
+
+TextUndoManager::~TextUndoManager()
+{
+}
+
+BOOL __EXPORT TextUndoManager::Undo( USHORT nCount )
+{
+ if ( GetUndoActionCount() == 0 )
+ return FALSE;
+
+ UndoRedoStart();
+
+ mpTextEngine->SetIsInUndo( TRUE );
+ BOOL bDone = SfxUndoManager::Undo( nCount );
+ mpTextEngine->SetIsInUndo( FALSE );
+
+ UndoRedoEnd();
+
+ return bDone;
+}
+
+BOOL __EXPORT TextUndoManager::Redo( USHORT nCount )
+{
+ if ( GetRedoActionCount() == 0 )
+ return FALSE;
+
+
+ UndoRedoStart();
+
+ mpTextEngine->SetIsInUndo( TRUE );
+ BOOL bDone = SfxUndoManager::Redo( nCount );
+ mpTextEngine->SetIsInUndo( FALSE );
+
+ UndoRedoEnd();
+
+ return bDone;
+}
+
+void TextUndoManager::UndoRedoStart()
+{
+ DBG_ASSERT( GetView(), "Undo/Redo: Active View?" );
+
+// if ( GetView() )
+// GetView()->HideSelection();
+}
+
+void TextUndoManager::UndoRedoEnd()
+{
+ if ( GetView() )
+ {
+ TextSelection aNewSel( GetView()->GetSelection() );
+ aNewSel.GetStart() = aNewSel.GetEnd();
+ GetView()->ImpSetSelection( aNewSel );
+ }
+
+ mpTextEngine->UpdateSelections();
+
+ mpTextEngine->FormatAndUpdate( GetView() );
+}
+
+
+TextUndo::TextUndo( USHORT nI, TextEngine* p )
+{
+ mnId = nI;
+ mpTextEngine = p;
+}
+
+TextUndo::~TextUndo()
+{
+}
+
+USHORT __EXPORT TextUndo::GetId() const
+{
+ //nId sollte mal entfallen => GetId ueberall ueberladen...
+ return mnId;
+}
+
+XubString __EXPORT TextUndo::GetComment() const
+{
+// return mpTextEngine->GetUndoComment( this );
+ return String();
+}
+
+void TextUndo::SetSelection( const TextSelection& rSel )
+{
+ if ( GetView() )
+ GetView()->ImpSetSelection( rSel );
+}
+
+
+TextUndoDelPara::TextUndoDelPara( TextEngine* pTextEngine, TextNode* pNode, ULONG nPara )
+ : TextUndo( TEXTUNDO_DELCONTENT, pTextEngine )
+{
+ mpNode = pNode;
+ mnPara = nPara;
+ mbDelObject = TRUE;
+}
+
+TextUndoDelPara::~TextUndoDelPara()
+{
+ if ( mbDelObject )
+ delete mpNode;
+}
+
+void __EXPORT TextUndoDelPara::Undo()
+{
+ GetTextEngine()->InsertContent( mpNode, mnPara );
+ mbDelObject = FALSE; // gehoert wieder der Engine
+
+ if ( GetView() )
+ {
+ TextSelection aSel( TextPaM( mnPara, 0 ), TextPaM( mnPara, mpNode->GetText().Len() ) );
+ SetSelection( aSel );
+ }
+}
+
+void __EXPORT TextUndoDelPara::Redo()
+{
+ // pNode stimmt nicht mehr, falls zwischendurch Undos, in denen
+ // Absaetze verschmolzen sind.
+ mpNode = GetDoc()->GetNodes().GetObject( mnPara );
+
+ delete GetTEParaPortions()->GetObject( mnPara );
+ GetTEParaPortions()->Remove( mnPara );
+
+ // Node nicht loeschen, haengt im Undo!
+ GetDoc()->GetNodes().Remove( mnPara );
+ GetTextEngine()->ImpParagraphRemoved( mnPara );
+
+ mbDelObject = TRUE; // gehoert wieder dem Undo
+
+ ULONG nParas = GetDoc()->GetNodes().Count();
+ ULONG n = mnPara < nParas ? mnPara : (nParas-1);
+ TextNode* pN = GetDoc()->GetNodes().GetObject( n );
+ TextPaM aPaM( n, pN->GetText().Len() );
+ SetSelection( aPaM );
+}
+
+ // -----------------------------------------------------------------------
+// TextUndoConnectParas
+// ------------------------------------------------------------------------
+TextUndoConnectParas::TextUndoConnectParas( TextEngine* pTextEngine, ULONG nPara, USHORT nPos )
+ : TextUndo( TEXTUNDO_CONNECTPARAS, pTextEngine )
+{
+ mnPara = nPara;
+ mnSepPos = nPos;
+}
+
+TextUndoConnectParas::~TextUndoConnectParas()
+{
+}
+
+void __EXPORT TextUndoConnectParas::Undo()
+{
+ TextPaM aPaM = GetTextEngine()->SplitContent( mnPara, mnSepPos );
+ SetSelection( aPaM );
+}
+
+void __EXPORT TextUndoConnectParas::Redo()
+{
+ TextPaM aPaM = GetTextEngine()->ConnectContents( mnPara );
+ SetSelection( aPaM );
+}
+
+
+TextUndoSplitPara::TextUndoSplitPara( TextEngine* pTextEngine, ULONG nPara, USHORT nPos )
+ : TextUndo( TEXTUNDO_SPLITPARA, pTextEngine )
+{
+ mnPara = nPara;
+ mnSepPos = nPos;
+}
+
+TextUndoSplitPara::~TextUndoSplitPara()
+{
+}
+
+void __EXPORT TextUndoSplitPara::Undo()
+{
+ TextPaM aPaM = GetTextEngine()->ConnectContents( mnPara );
+ SetSelection( aPaM );
+}
+
+void __EXPORT TextUndoSplitPara::Redo()
+{
+ TextPaM aPaM = GetTextEngine()->SplitContent( mnPara, mnSepPos );
+ SetSelection( aPaM );
+}
+
+
+TextUndoInsertChars::TextUndoInsertChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const XubString& rStr )
+ : TextUndo( TEXTUNDO_INSERTCHARS, pTextEngine ),
+ maTextPaM( rTextPaM ), maText( rStr )
+{
+}
+
+void __EXPORT TextUndoInsertChars::Undo()
+{
+ TextSelection aSel( maTextPaM, maTextPaM );
+ aSel.GetEnd().GetIndex() = aSel.GetEnd().GetIndex() + maText.Len();
+ TextPaM aPaM = GetTextEngine()->ImpDeleteText( aSel );
+ SetSelection( aPaM );
+}
+
+void __EXPORT TextUndoInsertChars::Redo()
+{
+ TextSelection aSel( maTextPaM, maTextPaM );
+ GetTextEngine()->ImpInsertText( aSel, maText );
+ TextPaM aNewPaM( maTextPaM );
+ aNewPaM.GetIndex() = aNewPaM.GetIndex() + maText.Len();
+ SetSelection( TextSelection( aSel.GetStart(), aNewPaM ) );
+}
+
+BOOL __EXPORT TextUndoInsertChars::Merge( SfxUndoAction* pNextAction )
+{
+ if ( !pNextAction->ISA( TextUndoInsertChars ) )
+ return FALSE;
+
+ TextUndoInsertChars* pNext = (TextUndoInsertChars*)pNextAction;
+
+ if ( maTextPaM.GetPara() != pNext->maTextPaM.GetPara() )
+ return FALSE;
+
+ if ( ( maTextPaM.GetIndex() + maText.Len() ) == pNext->maTextPaM.GetIndex() )
+ {
+ maText += pNext->maText;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+TextUndoRemoveChars::TextUndoRemoveChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const XubString& rStr )
+ : TextUndo( TEXTUNDO_REMOVECHARS, pTextEngine ),
+ maTextPaM( rTextPaM ), maText( rStr )
+{
+}
+
+void __EXPORT TextUndoRemoveChars::Undo()
+{
+ TextSelection aSel( maTextPaM, maTextPaM );
+ GetTextEngine()->ImpInsertText( aSel, maText );
+ aSel.GetEnd().GetIndex() = aSel.GetEnd().GetIndex() + maText.Len();
+ SetSelection( aSel );
+}
+
+void __EXPORT TextUndoRemoveChars::Redo()
+{
+ TextSelection aSel( maTextPaM, maTextPaM );
+ aSel.GetEnd().GetIndex() = aSel.GetEnd().GetIndex() + maText.Len();
+ TextPaM aPaM = GetTextEngine()->ImpDeleteText( aSel );
+ SetSelection( aPaM );
+}
+
+
+TextUndoSetAttribs::TextUndoSetAttribs( TextEngine* pTextEngine, const TextSelection& rSel )
+ : TextUndo( TEXTUNDO_ATTRIBS, pTextEngine ), maSelection( rSel )
+{
+ maSelection.Justify();
+// aNewAttribs.Set( rNewItems );
+// mbSetIsRemove = FALSE;
+// mnRemoveWhich = 0;
+// mnSpecial = 0;
+}
+
+TextUndoSetAttribs::~TextUndoSetAttribs()
+{
+ // ...............
+}
+
+void __EXPORT TextUndoSetAttribs::Undo()
+{
+ for ( ULONG nPara = maSelection.GetStart().GetPara(); nPara <= maSelection.GetEnd().GetPara(); nPara++ )
+ {
+// ContentAttribsInfo* pInf = aPrevAttribs[ (USHORT)(nPara-aESel.nStartPara) ];
+// GetTextEngine()->RemoveCharAttribs( nPara );
+// TextNode* pNode = GetTextEngine()->GetTextDoc().GetObject( nPara );
+// for ( USHORT nAttr = 0; nAttr < pInf->GetPrevCharAttribs().Count(); nAttr++ )
+// {
+// GetTextEngine()->GetTextDoc().InsertAttrib( pNode, pX->GetStart(), pX->GetEnd(), *pX->GetItem() );
+// }
+ }
+ SetSelection( maSelection );
+}
+
+void __EXPORT TextUndoSetAttribs::Redo()
+{
+// if ( !bSetIsRemove )
+// GetTextEngine()->SetAttribs( aSel, aNewAttribs, nSpecial );
+// else
+// GetTextEngine()->RemoveCharAttribs( aSel, bRemoveParaAttribs, nRemoveWhich );
+ SetSelection( maSelection );
+}
diff --git a/svtools/source/edit/textundo.hxx b/svtools/source/edit/textundo.hxx
new file mode 100644
index 000000000000..cc26c0b51ef6
--- /dev/null
+++ b/svtools/source/edit/textundo.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 _TEXTUNDO_HXX
+#define _TEXTUNDO_HXX
+
+#include <svl/undo.hxx>
+
+class TextEngine;
+
+class TextUndoManager : public SfxUndoManager
+{
+ TextEngine* mpTextEngine;
+
+protected:
+
+ void UndoRedoStart();
+ void UndoRedoEnd();
+
+ TextView* GetView() const { return mpTextEngine->GetActiveView(); }
+
+public:
+ TextUndoManager( TextEngine* pTextEngine );
+ ~TextUndoManager();
+
+ using SfxUndoManager::Undo;
+ virtual BOOL Undo( USHORT nCount=1 );
+ using SfxUndoManager::Redo;
+ virtual BOOL Redo( USHORT nCount=1 );
+
+};
+
+class TextUndo : public SfxUndoAction
+{
+private:
+ USHORT mnId;
+ TextEngine* mpTextEngine;
+
+protected:
+
+ TextView* GetView() const { return mpTextEngine->GetActiveView(); }
+ void SetSelection( const TextSelection& rSel );
+
+ TextDoc* GetDoc() const { return mpTextEngine->mpDoc; }
+ TEParaPortions* GetTEParaPortions() const { return mpTextEngine->mpTEParaPortions; }
+
+public:
+ TYPEINFO();
+ TextUndo( USHORT nId, TextEngine* pTextEngine );
+ virtual ~TextUndo();
+
+ TextEngine* GetTextEngine() const { return mpTextEngine; }
+
+ virtual void Undo() = 0;
+ virtual void Redo() = 0;
+
+ virtual XubString GetComment() const;
+ virtual USHORT GetId() const;
+};
+
+#endif // _TEXTUNDO_HXX
diff --git a/svtools/source/edit/textview.cxx b/svtools/source/edit/textview.cxx
new file mode 100644
index 000000000000..48cd23bdcc6f
--- /dev/null
+++ b/svtools/source/edit/textview.cxx
@@ -0,0 +1,2470 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/textview.hxx>
+#include <svtools/texteng.hxx>
+#include <textdoc.hxx>
+#include <svtools/textdata.hxx>
+#include <textdat2.hxx>
+
+#include <svl/undo.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/sound.hxx>
+#include <tools/stream.hxx>
+
+#include <sot/formats.hxx>
+#include <svl/urlbmk.hxx>
+
+#ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_CHARACTERITERATORMODE_HPP_
+#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
+#include <com/sun/star/i18n/WordType.hpp>
+#endif
+#include <cppuhelper/weak.hxx>
+#include <vcl/unohelp.hxx>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#ifndef _COM_SUN_STAR_DATATRANSFER_DND_DNDCONSTANS_HPP_
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#endif
+#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+
+#include <vcl/edit.hxx>
+
+
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+
+#include <vos/mutex.hxx>
+
+
+using namespace ::com::sun::star;
+
+class TETextDataObject : public ::com::sun::star::datatransfer::XTransferable,
+ public ::cppu::OWeakObject
+
+{
+private:
+ String maText;
+ SvMemoryStream maHTMLStream;
+
+public:
+ TETextDataObject( const String& rText );
+ ~TETextDataObject();
+
+ String& GetText() { return maText; }
+ SvMemoryStream& GetHTMLStream() { return maHTMLStream; }
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ void SAL_CALL release() throw() { OWeakObject::release(); }
+
+ // ::com::sun::star::datatransfer::XTransferable
+ ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) throw(::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+TETextDataObject::TETextDataObject( const String& rText ) : maText( rText )
+{
+}
+
+TETextDataObject::~TETextDataObject()
+{
+}
+
+// uno::XInterface
+uno::Any TETextDataObject::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException)
+{
+ uno::Any aRet = ::cppu::queryInterface( rType, SAL_STATIC_CAST( datatransfer::XTransferable*, this ) );
+ return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
+}
+
+// datatransfer::XTransferable
+uno::Any TETextDataObject::getTransferData( const datatransfer::DataFlavor& rFlavor ) throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException)
+{
+ uno::Any aAny;
+
+ ULONG nT = SotExchange::GetFormat( rFlavor );
+ if ( nT == SOT_FORMAT_STRING )
+ {
+ aAny <<= (::rtl::OUString)GetText();
+ }
+ else if ( nT == SOT_FORMATSTR_ID_HTML )
+ {
+ GetHTMLStream().Seek( STREAM_SEEK_TO_END );
+ ULONG nLen = GetHTMLStream().Tell();
+ GetHTMLStream().Seek(0);
+
+ uno::Sequence< sal_Int8 > aSeq( nLen );
+ memcpy( aSeq.getArray(), GetHTMLStream().GetData(), nLen );
+ aAny <<= aSeq;
+ }
+ else
+ {
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ return aAny;
+}
+
+uno::Sequence< datatransfer::DataFlavor > TETextDataObject::getTransferDataFlavors( ) throw(uno::RuntimeException)
+{
+ GetHTMLStream().Seek( STREAM_SEEK_TO_END );
+ BOOL bHTML = GetHTMLStream().Tell() > 0;
+ uno::Sequence< datatransfer::DataFlavor > aDataFlavors( bHTML ? 2 : 1 );
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aDataFlavors.getArray()[0] );
+ if ( bHTML )
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_HTML, aDataFlavors.getArray()[1] );
+ return aDataFlavors;
+}
+
+sal_Bool TETextDataObject::isDataFlavorSupported( const datatransfer::DataFlavor& rFlavor ) throw(uno::RuntimeException)
+{
+ ULONG nT = SotExchange::GetFormat( rFlavor );
+ return ( nT == SOT_FORMAT_STRING );
+}
+
+/*-- 24.06.2004 13:54:36---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+struct ImpTextView
+{
+ TextEngine* mpTextEngine;
+
+ Window* mpWindow;
+ TextSelection maSelection;
+ Point maStartDocPos;
+// TextPaM maMBDownPaM;
+
+ Cursor* mpCursor;
+
+ TextDDInfo* mpDDInfo;
+
+ VirtualDevice* mpVirtDev;
+
+ SelectionEngine* mpSelEngine;
+ TextSelFunctionSet* mpSelFuncSet;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSourceListener > mxDnDListener;
+
+ USHORT mnTravelXPos;
+
+ BOOL mbAutoScroll : 1;
+ BOOL mbInsertMode : 1;
+ BOOL mbReadOnly : 1;
+ BOOL mbPaintSelection : 1;
+ BOOL mbAutoIndent : 1;
+ BOOL mbHighlightSelection : 1;
+ BOOL mbCursorEnabled : 1;
+ BOOL mbClickedInSelection : 1;
+ BOOL mbSupportProtectAttribute : 1;
+ bool mbCursorAtEndOfLine;
+};
+
+// -------------------------------------------------------------------------
+// (+) class TextView
+// -------------------------------------------------------------------------
+TextView::TextView( TextEngine* pEng, Window* pWindow ) :
+ mpImpl(new ImpTextView)
+{
+ pWindow->EnableRTL( FALSE );
+
+ mpImpl->mpWindow = pWindow;
+ mpImpl->mpTextEngine = pEng;
+ mpImpl->mpVirtDev = NULL;
+
+ mpImpl->mbPaintSelection = TRUE;
+ mpImpl->mbAutoScroll = TRUE;
+ mpImpl->mbInsertMode = TRUE;
+ mpImpl->mbReadOnly = FALSE;
+ mpImpl->mbHighlightSelection = FALSE;
+ mpImpl->mbAutoIndent = FALSE;
+ mpImpl->mbCursorEnabled = TRUE;
+ mpImpl->mbClickedInSelection = FALSE;
+ mpImpl->mbSupportProtectAttribute = FALSE;
+ mpImpl->mbCursorAtEndOfLine = false;
+// mbInSelection = FALSE;
+
+ mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
+
+ mpImpl->mpSelFuncSet = new TextSelFunctionSet( this );
+ mpImpl->mpSelEngine = new SelectionEngine( mpImpl->mpWindow, mpImpl->mpSelFuncSet );
+ mpImpl->mpSelEngine->SetSelectionMode( RANGE_SELECTION );
+ mpImpl->mpSelEngine->EnableDrag( TRUE );
+
+ mpImpl->mpCursor = new Cursor;
+ mpImpl->mpCursor->Show();
+ pWindow->SetCursor( mpImpl->mpCursor );
+ pWindow->SetInputContext( InputContext( pEng->GetFont(), INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT ) );
+
+ if ( pWindow->GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_INVERT )
+ mpImpl->mbHighlightSelection = TRUE;
+
+ pWindow->SetLineColor();
+
+ mpImpl->mpDDInfo = NULL;
+
+ if ( pWindow->GetDragGestureRecognizer().is() )
+ {
+ vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
+ mpImpl->mxDnDListener = pDnDWrapper;
+
+ uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mpImpl->mxDnDListener, uno::UNO_QUERY );
+ pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
+ uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
+ pWindow->GetDropTarget()->addDropTargetListener( xDTL );
+ pWindow->GetDropTarget()->setActive( sal_True );
+ pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
+ }
+}
+
+TextView::~TextView()
+{
+ delete mpImpl->mpSelEngine;
+ delete mpImpl->mpSelFuncSet;
+ delete mpImpl->mpVirtDev;
+
+ if ( mpImpl->mpWindow->GetCursor() == mpImpl->mpCursor )
+ mpImpl->mpWindow->SetCursor( 0 );
+ delete mpImpl->mpCursor;
+ delete mpImpl->mpDDInfo;
+ delete mpImpl;
+}
+
+void TextView::Invalidate()
+{
+ mpImpl->mpWindow->Invalidate();
+}
+
+void TextView::SetSelection( const TextSelection& rTextSel, BOOL bGotoCursor )
+{
+ // Falls jemand gerade ein leeres Attribut hinterlassen hat,
+ // und dann der Outliner die Selektion manipulitert:
+ if ( !mpImpl->maSelection.HasRange() )
+ mpImpl->mpTextEngine->CursorMoved( mpImpl->maSelection.GetStart().GetPara() );
+
+ // Wenn nach einem KeyInput die Selection manipuliert wird:
+ mpImpl->mpTextEngine->CheckIdleFormatter();
+
+ HideSelection();
+ TextSelection aNewSel( rTextSel );
+ mpImpl->mpTextEngine->ValidateSelection( aNewSel );
+ ImpSetSelection( aNewSel );
+ ShowSelection();
+ ShowCursor( bGotoCursor );
+}
+
+void TextView::SetSelection( const TextSelection& rTextSel )
+{
+ SetSelection( rTextSel, mpImpl->mbAutoScroll );
+}
+
+const TextSelection& TextView::GetSelection() const
+{
+ return mpImpl->maSelection;
+}
+TextSelection& TextView::GetSelection()
+{
+ return mpImpl->maSelection;
+}
+
+void TextView::DeleteSelected()
+{
+// HideSelection();
+
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_DELETE );
+ TextPaM aPaM = mpImpl->mpTextEngine->ImpDeleteText( mpImpl->maSelection );
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_DELETE );
+
+ ImpSetSelection( aPaM );
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+ ShowCursor();
+}
+
+void TextView::ImpPaint( OutputDevice* pOut, const Point& rStartPos, Rectangle const* pPaintArea, TextSelection const* pPaintRange, TextSelection const* pSelection )
+{
+ if ( !mpImpl->mbPaintSelection )
+ pSelection = NULL;
+ else
+ {
+ // Richtige Hintergrundfarbe einstellen.
+ // Ich bekomme leider nicht mit, ob sich diese inzwischen geaendert hat.
+ Font aFont = mpImpl->mpTextEngine->GetFont();
+ Color aColor = pOut->GetBackground().GetColor();
+ aColor.SetTransparency( 0 );
+ if ( aColor != aFont.GetFillColor() )
+ {
+ if( aFont.IsTransparent() )
+ aColor = Color( COL_TRANSPARENT );
+ aFont.SetFillColor( aColor );
+ mpImpl->mpTextEngine->maFont = aFont;
+ }
+ }
+
+ mpImpl->mpTextEngine->ImpPaint( pOut, rStartPos, pPaintArea, pPaintRange, pSelection );
+}
+
+void TextView::Paint( const Rectangle& rRect )
+{
+ ImpPaint( rRect, FALSE );
+}
+
+void TextView::ImpPaint( const Rectangle& rRect, BOOL bUseVirtDev )
+{
+ if ( !mpImpl->mpTextEngine->GetUpdateMode() || mpImpl->mpTextEngine->IsInUndo() )
+ return;
+
+ TextSelection *pDrawSelection = NULL;
+ if ( !mpImpl->mbHighlightSelection && mpImpl->maSelection.HasRange() )
+ pDrawSelection = &mpImpl->maSelection;
+
+ if ( bUseVirtDev )
+ {
+ VirtualDevice* pVDev = GetVirtualDevice();
+
+ const Color& rBackgroundColor = mpImpl->mpWindow->GetBackground().GetColor();
+ if ( pVDev->GetFillColor() != rBackgroundColor )
+ pVDev->SetFillColor( rBackgroundColor );
+ if ( pVDev->GetBackground().GetColor() != rBackgroundColor )
+ pVDev->SetBackground( rBackgroundColor );
+
+ BOOL bVDevValid = TRUE;
+ Size aOutSz( pVDev->GetOutputSizePixel() );
+ if ( ( aOutSz.Width() < rRect.GetWidth() ) ||
+ ( aOutSz.Height() < rRect.GetHeight() ) )
+ {
+ bVDevValid = pVDev->SetOutputSizePixel( rRect.GetSize() );
+ }
+ else
+ {
+ // Das VirtDev kann bei einem Resize sehr gross werden =>
+ // irgendwann mal kleiner machen!
+ if ( ( aOutSz.Height() > ( rRect.GetHeight() + 20 ) ) ||
+ ( aOutSz.Width() > ( rRect.GetWidth() + 20 ) ) )
+ {
+ bVDevValid = pVDev->SetOutputSizePixel( rRect.GetSize() );
+ }
+ else
+ {
+ pVDev->Erase();
+ }
+ }
+ if ( !bVDevValid )
+ {
+ ImpPaint( rRect, FALSE /* ohne VDev */ );
+ return;
+ }
+
+ Rectangle aTmpRec( Point( 0, 0 ), rRect.GetSize() );
+
+ Point aDocPos( mpImpl->maStartDocPos.X(), mpImpl->maStartDocPos.Y() + rRect.Top() );
+ Point aStartPos = ImpGetOutputStartPos( aDocPos );
+ ImpPaint( pVDev, aStartPos, &aTmpRec, NULL, pDrawSelection );
+ mpImpl->mpWindow->DrawOutDev( rRect.TopLeft(), rRect.GetSize(),
+ Point(0,0), rRect.GetSize(), *pVDev );
+// ShowSelection();
+ if ( mpImpl->mbHighlightSelection )
+ ImpHighlight( mpImpl->maSelection );
+ }
+ else
+ {
+ Point aStartPos = ImpGetOutputStartPos( mpImpl->maStartDocPos );
+ ImpPaint( mpImpl->mpWindow, aStartPos, &rRect, NULL, pDrawSelection );
+
+// ShowSelection();
+ if ( mpImpl->mbHighlightSelection )
+ ImpHighlight( mpImpl->maSelection );
+ }
+}
+
+void TextView::ImpHighlight( const TextSelection& rSel )
+{
+ TextSelection aSel( rSel );
+ aSel.Justify();
+ if ( aSel.HasRange() && !mpImpl->mpTextEngine->IsInUndo() && mpImpl->mpTextEngine->GetUpdateMode() )
+ {
+ mpImpl->mpCursor->Hide();
+
+ DBG_ASSERT( !mpImpl->mpTextEngine->mpIdleFormatter->IsActive(), "ImpHighlight: Not formatted!" );
+
+ Rectangle aVisArea( mpImpl->maStartDocPos, mpImpl->mpWindow->GetOutputSizePixel() );
+ long nY = 0;
+ ULONG nStartPara = aSel.GetStart().GetPara();
+ ULONG nEndPara = aSel.GetEnd().GetPara();
+ for ( ULONG nPara = 0; nPara <= nEndPara; nPara++ )
+ {
+ long nParaHeight = (long)mpImpl->mpTextEngine->CalcParaHeight( nPara );
+ if ( ( nPara >= nStartPara ) && ( ( nY + nParaHeight ) > aVisArea.Top() ) )
+ {
+ TEParaPortion* pTEParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( nPara );
+ USHORT nStartLine = 0;
+ USHORT nEndLine = pTEParaPortion->GetLines().Count() -1;
+ if ( nPara == nStartPara )
+ nStartLine = pTEParaPortion->GetLineNumber( aSel.GetStart().GetIndex(), FALSE );
+ if ( nPara == nEndPara )
+ nEndLine = pTEParaPortion->GetLineNumber( aSel.GetEnd().GetIndex(), TRUE );
+
+ // ueber die Zeilen iterieren....
+ for ( USHORT nLine = nStartLine; nLine <= nEndLine; nLine++ )
+ {
+ TextLine* pLine = pTEParaPortion->GetLines().GetObject( nLine );
+ USHORT nStartIndex = pLine->GetStart();
+ USHORT nEndIndex = pLine->GetEnd();
+ if ( ( nPara == nStartPara ) && ( nLine == nStartLine ) )
+ nStartIndex = aSel.GetStart().GetIndex();
+ if ( ( nPara == nEndPara ) && ( nLine == nEndLine ) )
+ nEndIndex = aSel.GetEnd().GetIndex();
+
+ // Kann passieren, wenn am Anfang einer umgebrochenen Zeile.
+ if ( nEndIndex < nStartIndex )
+ nEndIndex = nStartIndex;
+
+ Rectangle aTmpRec( mpImpl->mpTextEngine->GetEditCursor( TextPaM( nPara, nStartIndex ), FALSE ) );
+ aTmpRec.Top() += nY;
+ aTmpRec.Bottom() += nY;
+ Point aTopLeft( aTmpRec.TopLeft() );
+
+ aTmpRec = mpImpl->mpTextEngine->GetEditCursor( TextPaM( nPara, nEndIndex ), TRUE );
+ aTmpRec.Top() += nY;
+ aTmpRec.Bottom() += nY;
+ Point aBottomRight( aTmpRec.BottomRight() );
+ aBottomRight.X()--;
+
+ // Nur Painten, wenn im sichtbaren Bereich...
+ if ( ( aTopLeft.X() < aBottomRight.X() ) && ( aBottomRight.Y() >= aVisArea.Top() ) )
+ {
+ Point aPnt1( GetWindowPos( aTopLeft ) );
+ Point aPnt2( GetWindowPos( aBottomRight ) );
+
+ Rectangle aRect( aPnt1, aPnt2 );
+ mpImpl->mpWindow->Invert( aRect );
+ }
+ }
+ }
+ nY += nParaHeight;
+
+ if ( nY >= aVisArea.Bottom() )
+ break;
+ }
+ }
+}
+
+void TextView::ImpSetSelection( const TextSelection& rSelection )
+{
+ if ( rSelection != mpImpl->maSelection )
+ {
+ mpImpl->maSelection = rSelection;
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_VIEWSELECTIONCHANGED ) );
+ }
+}
+
+void TextView::ShowSelection()
+{
+ ImpShowHideSelection( TRUE );
+}
+
+void TextView::HideSelection()
+{
+ ImpShowHideSelection( FALSE );
+}
+
+void TextView::ShowSelection( const TextSelection& rRange )
+{
+ ImpShowHideSelection( TRUE, &rRange );
+}
+
+void TextView::ImpShowHideSelection( BOOL bShow, const TextSelection* pRange )
+{
+ const TextSelection* pRangeOrSelection = pRange ? pRange : &mpImpl->maSelection;
+
+ if ( pRangeOrSelection->HasRange() )
+ {
+ if ( mpImpl->mbHighlightSelection )
+ {
+ ImpHighlight( *pRangeOrSelection );
+ }
+ else
+ {
+ if( mpImpl->mpWindow->IsPaintTransparent() )
+ mpImpl->mpWindow->Invalidate();
+ else
+ {
+ Rectangle aOutArea( Point( 0, 0 ), mpImpl->mpWindow->GetOutputSizePixel() );
+ Point aStartPos( ImpGetOutputStartPos( mpImpl->maStartDocPos ) );
+ TextSelection aRange( *pRangeOrSelection );
+ aRange.Justify();
+ BOOL bVisCursor = mpImpl->mpCursor->IsVisible();
+ mpImpl->mpCursor->Hide();
+ ImpPaint( mpImpl->mpWindow, aStartPos, &aOutArea, &aRange, bShow ? &mpImpl->maSelection : NULL );
+ if ( bVisCursor )
+ mpImpl->mpCursor->Show();
+ }
+ }
+ }
+}
+
+VirtualDevice* TextView::GetVirtualDevice()
+{
+ if ( !mpImpl->mpVirtDev )
+ {
+ mpImpl->mpVirtDev = new VirtualDevice;
+ mpImpl->mpVirtDev->SetLineColor();
+ }
+ return mpImpl->mpVirtDev;
+}
+
+void TextView::EraseVirtualDevice()
+{
+ delete mpImpl->mpVirtDev;
+ mpImpl->mpVirtDev = 0;
+}
+
+BOOL TextView::KeyInput( const KeyEvent& rKeyEvent )
+{
+ BOOL bDone = TRUE;
+ BOOL bModified = FALSE;
+ BOOL bMoved = FALSE;
+ BOOL bEndKey = FALSE; // spezielle CursorPosition
+ BOOL bAllowIdle = TRUE;
+
+ // Um zu pruefen ob durch irgendeine Aktion mModified, das lokale
+ // bModified wird z.B. bei Cut/Paste nicht gesetzt, weil dort an anderen
+ // Stellen das updaten erfolgt.
+ BOOL bWasModified = mpImpl->mpTextEngine->IsModified();
+ mpImpl->mpTextEngine->SetModified( FALSE );
+
+ TextSelection aCurSel( mpImpl->maSelection );
+ TextSelection aOldSel( aCurSel );
+
+ USHORT nCode = rKeyEvent.GetKeyCode().GetCode();
+ KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_CUT:
+ {
+ if ( !mpImpl->mbReadOnly )
+ Cut();
+ }
+ break;
+ case KEYFUNC_COPY:
+ {
+ Copy();
+ }
+ break;
+ case KEYFUNC_PASTE:
+ {
+ if ( !mpImpl->mbReadOnly )
+ Paste();
+ }
+ break;
+ case KEYFUNC_UNDO:
+ {
+ if ( !mpImpl->mbReadOnly )
+ Undo();
+ }
+ break;
+ case KEYFUNC_REDO:
+ {
+ if ( !mpImpl->mbReadOnly )
+ Redo();
+ }
+ break;
+
+ default: // wird dann evtl. unten bearbeitet.
+ eFunc = KEYFUNC_DONTKNOW;
+ }
+ }
+ if ( eFunc == KEYFUNC_DONTKNOW )
+ {
+ switch ( nCode )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_HOME:
+ case KEY_END:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
+ case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
+ case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
+ case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
+ {
+ if ( ( !rKeyEvent.GetKeyCode().IsMod2() || ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) )
+ && !( rKeyEvent.GetKeyCode().IsMod1() && ( nCode == KEY_PAGEUP || nCode == KEY_PAGEDOWN ) ) )
+ {
+ aCurSel = ImpMoveCursor( rKeyEvent );
+ if ( aCurSel.HasRange() ) {
+ uno::Reference<datatransfer::clipboard::XClipboard> aSelection(GetWindow()->GetPrimarySelection());
+ Copy( aSelection );
+ }
+ bMoved = TRUE;
+ if ( nCode == KEY_END )
+ bEndKey = TRUE;
+ }
+ else
+ bDone = FALSE;
+ }
+ break;
+ case KEY_BACKSPACE:
+ case KEY_DELETE:
+ case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
+ case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
+ case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
+ case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
+ {
+ if ( !mpImpl->mbReadOnly && !rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ BYTE nDel = ( nCode == KEY_DELETE ) ? DEL_RIGHT : DEL_LEFT;
+ BYTE nMode = rKeyEvent.GetKeyCode().IsMod1() ? DELMODE_RESTOFWORD : DELMODE_SIMPLE;
+ if ( ( nMode == DELMODE_RESTOFWORD ) && rKeyEvent.GetKeyCode().IsShift() )
+ nMode = DELMODE_RESTOFCONTENT;
+
+ switch( nCode )
+ {
+ case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
+ nDel = DEL_LEFT;
+ nMode = DELMODE_RESTOFWORD;
+ break;
+ case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
+ nDel = DEL_RIGHT;
+ nMode = DELMODE_RESTOFWORD;
+ break;
+ case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
+ nDel = DEL_LEFT;
+ nMode = DELMODE_RESTOFCONTENT;
+ break;
+ case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
+ nDel = DEL_RIGHT;
+ nMode = DELMODE_RESTOFCONTENT;
+ break;
+ default: break;
+ }
+
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_DELETE );
+ if(mpImpl->mbSupportProtectAttribute)
+ {
+ //expand selection to include all protected content - if there is any
+ const TextCharAttrib* pStartAttr = mpImpl->mpTextEngine->FindCharAttrib(
+ TextPaM(mpImpl->maSelection.GetStart().GetPara(),
+ mpImpl->maSelection.GetStart().GetIndex()),
+ TEXTATTR_PROTECTED );
+ const TextCharAttrib* pEndAttr = mpImpl->mpTextEngine->FindCharAttrib(
+ TextPaM(mpImpl->maSelection.GetEnd().GetPara(),
+ mpImpl->maSelection.GetEnd().GetIndex()),
+ TEXTATTR_PROTECTED );
+ if(pStartAttr && pStartAttr->GetStart() < mpImpl->maSelection.GetStart().GetIndex())
+ {
+ mpImpl->maSelection.GetStart().GetIndex() = pStartAttr->GetStart();
+ }
+ if(pEndAttr && pEndAttr->GetEnd() > mpImpl->maSelection.GetEnd().GetIndex())
+ {
+ mpImpl->maSelection.GetEnd().GetIndex() = pEndAttr->GetEnd();
+ }
+ }
+ aCurSel = ImpDelete( nDel, nMode );
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_DELETE );
+ bModified = TRUE;
+ bAllowIdle = FALSE;
+ }
+ else
+ bDone = FALSE;
+ }
+ break;
+ case KEY_TAB:
+ {
+ if ( !mpImpl->mbReadOnly && !rKeyEvent.GetKeyCode().IsShift() &&
+ !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() &&
+ ImplCheckTextLen( 'x' ) )
+ {
+ aCurSel = mpImpl->mpTextEngine->ImpInsertText( aCurSel, '\t', !IsInsertMode() );
+ bModified = TRUE;
+ }
+ else
+ bDone = FALSE;
+ }
+ break;
+ case KEY_RETURN:
+ {
+ // Shift-RETURN darf nicht geschluckt werden, weil dann keine
+ // mehrzeilige Eingabe in Dialogen/Property-Editor moeglich.
+ if ( !mpImpl->mbReadOnly && !rKeyEvent.GetKeyCode().IsMod1() &&
+ !rKeyEvent.GetKeyCode().IsMod2() && ImplCheckTextLen( 'x' ) )
+ {
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_INSERT );
+ aCurSel = mpImpl->mpTextEngine->ImpInsertParaBreak( aCurSel );
+ if ( mpImpl->mbAutoIndent )
+ {
+ TextNode* pPrev = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aCurSel.GetEnd().GetPara() - 1 );
+ USHORT n = 0;
+ while ( ( n < pPrev->GetText().Len() ) && (
+ ( pPrev->GetText().GetChar( n ) == ' ' ) ||
+ ( pPrev->GetText().GetChar( n ) == '\t' ) ) )
+ {
+ n++;
+ }
+ if ( n )
+ aCurSel = mpImpl->mpTextEngine->ImpInsertText( aCurSel, pPrev->GetText().Copy( 0, n ) );
+ }
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_INSERT );
+ bModified = TRUE;
+ }
+ else
+ bDone = FALSE;
+ }
+ break;
+ case KEY_INSERT:
+ {
+ if ( !mpImpl->mbReadOnly )
+ SetInsertMode( !IsInsertMode() );
+ }
+ break;
+ default:
+ {
+ if ( TextEngine::IsSimpleCharInput( rKeyEvent ) )
+ {
+ xub_Unicode nCharCode = rKeyEvent.GetCharCode();
+ if ( !mpImpl->mbReadOnly && ImplCheckTextLen( nCharCode ) ) // sonst trotzdem das Zeichen schlucken...
+ {
+ aCurSel = mpImpl->mpTextEngine->ImpInsertText( nCharCode, aCurSel, !IsInsertMode(), sal_True );
+ bModified = TRUE;
+ }
+ }
+ else
+ bDone = FALSE;
+ }
+ }
+ }
+
+ if ( aCurSel != aOldSel ) // Check if changed, maybe other method already changed mpImpl->maSelection, don't overwrite that!
+ ImpSetSelection( aCurSel );
+
+ mpImpl->mpTextEngine->UpdateSelections();
+
+ if ( ( nCode != KEY_UP ) && ( nCode != KEY_DOWN ) )
+ mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
+
+ if ( bModified )
+ {
+ // Idle-Formatter nur, wenn AnyInput.
+ if ( bAllowIdle && Application::AnyInput( INPUT_KEYBOARD) )
+ mpImpl->mpTextEngine->IdleFormatAndUpdate( this );
+ else
+ mpImpl->mpTextEngine->FormatAndUpdate( this);
+ }
+ else if ( bMoved )
+ {
+ // Selection wird jetzt gezielt in ImpMoveCursor gemalt.
+ ImpShowCursor( mpImpl->mbAutoScroll, TRUE, bEndKey );
+ }
+
+ if ( mpImpl->mpTextEngine->IsModified() )
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ else if ( bWasModified )
+ mpImpl->mpTextEngine->SetModified( TRUE );
+
+ return bDone;
+}
+
+void TextView::MouseButtonUp( const MouseEvent& rMouseEvent )
+{
+ mpImpl->mbClickedInSelection = FALSE;
+ mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
+ mpImpl->mpSelEngine->SelMouseButtonUp( rMouseEvent );
+ if ( rMouseEvent.IsMiddle() && !IsReadOnly() &&
+ ( GetWindow()->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) )
+ {
+ uno::Reference<datatransfer::clipboard::XClipboard> aSelection(GetWindow()->GetPrimarySelection());
+ Paste( aSelection );
+ if ( mpImpl->mpTextEngine->IsModified() )
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ }
+ else if ( rMouseEvent.IsLeft() && GetSelection().HasRange() )
+ {
+ uno::Reference<datatransfer::clipboard::XClipboard> aSelection(GetWindow()->GetPrimarySelection());
+ Copy( aSelection );
+ }
+}
+
+void TextView::MouseButtonDown( const MouseEvent& rMouseEvent )
+{
+ mpImpl->mpTextEngine->CheckIdleFormatter(); // Falls schnelles Tippen und MouseButtonDown
+ mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
+ mpImpl->mbClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
+
+ mpImpl->mpTextEngine->SetActiveView( this );
+
+ mpImpl->mpSelEngine->SelMouseButtonDown( rMouseEvent );
+
+ // mbu 20.01.2005 - SelMouseButtonDown() possibly triggers a 'selection changed'
+ // notification. The appropriate handler could change the current selection,
+ // which is the case in the MailMerge address block control. To enable select'n'drag
+ // we need to reevaluate the selection after the notification has been fired.
+ mpImpl->mbClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
+
+ // Sonderbehandlungen
+ if ( !rMouseEvent.IsShift() && ( rMouseEvent.GetClicks() >= 2 ) )
+ {
+ if ( rMouseEvent.IsMod2() )
+ {
+ HideSelection();
+ ImpSetSelection( mpImpl->maSelection.GetEnd() );
+ SetCursorAtPoint( rMouseEvent.GetPosPixel() ); // Wird von SelectionEngine bei MOD2 nicht gesetzt
+ }
+
+ if ( rMouseEvent.GetClicks() == 2 )
+ {
+ // Wort selektieren
+ if ( mpImpl->maSelection.GetEnd().GetIndex() < mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection.GetEnd().GetPara() ) )
+ {
+ HideSelection();
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( mpImpl->maSelection.GetEnd().GetPara() );
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ TextSelection aNewSel( mpImpl->maSelection );
+ aNewSel.GetStart().GetIndex() = (USHORT)aBoundary.startPos;
+ aNewSel.GetEnd().GetIndex() = (USHORT)aBoundary.endPos;
+ if(mpImpl->mbSupportProtectAttribute)
+ {
+ //expand selection to include all protected content - if there is any
+ const TextCharAttrib* pStartAttr = mpImpl->mpTextEngine->FindCharAttrib(
+ TextPaM(aNewSel.GetStart().GetPara(),
+ (USHORT)aBoundary.startPos),
+ TEXTATTR_PROTECTED );
+ const TextCharAttrib* pEndAttr = mpImpl->mpTextEngine->FindCharAttrib(
+ TextPaM(aNewSel.GetEnd().GetPara(),
+ (USHORT)aBoundary.endPos),
+ TEXTATTR_PROTECTED );
+ if(pStartAttr && pStartAttr->GetStart() < aNewSel.GetStart().GetIndex())
+ {
+ aNewSel.GetStart().GetIndex() = pStartAttr->GetStart();
+ }
+ if(pEndAttr && pEndAttr->GetEnd() > aNewSel.GetEnd().GetIndex())
+ {
+ aNewSel.GetEnd().GetIndex() = pEndAttr->GetEnd();
+ }
+ }
+ ImpSetSelection( aNewSel );
+ ShowSelection();
+ ShowCursor( TRUE, TRUE );
+ }
+ }
+ else if ( rMouseEvent.GetClicks() == 3 )
+ {
+ // Absatz selektieren
+ if ( mpImpl->maSelection.GetStart().GetIndex() || ( mpImpl->maSelection.GetEnd().GetIndex() < mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection.GetEnd().GetPara() ) ) )
+ {
+ HideSelection();
+ TextSelection aNewSel( mpImpl->maSelection );
+ aNewSel.GetStart().GetIndex() = 0;
+ aNewSel.GetEnd().GetIndex() = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( mpImpl->maSelection.GetEnd().GetPara() )->GetText().Len();
+ ImpSetSelection( aNewSel );
+ ShowSelection();
+ ShowCursor( TRUE, TRUE );
+ }
+ }
+ }
+}
+
+
+void TextView::MouseMove( const MouseEvent& rMouseEvent )
+{
+ mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
+ mpImpl->mpSelEngine->SelMouseMove( rMouseEvent );
+}
+
+void TextView::Command( const CommandEvent& rCEvt )
+{
+ mpImpl->mpTextEngine->CheckIdleFormatter(); // Falls schnelles Tippen und MouseButtonDown
+ mpImpl->mpTextEngine->SetActiveView( this );
+
+ if ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT )
+ {
+ DeleteSelected();
+ delete mpImpl->mpTextEngine->mpIMEInfos;
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( GetSelection().GetEnd().GetPara() );
+ mpImpl->mpTextEngine->mpIMEInfos = new TEIMEInfos( GetSelection().GetEnd(), pNode->GetText().Copy( GetSelection().GetEnd().GetIndex() ) );
+ mpImpl->mpTextEngine->mpIMEInfos->bWasCursorOverwrite = !IsInsertMode();
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
+ {
+ DBG_ASSERT( mpImpl->mpTextEngine->mpIMEInfos, "COMMAND_ENDEXTTEXTINPUT => Kein Start ?" );
+ if( mpImpl->mpTextEngine->mpIMEInfos )
+ {
+ TEParaPortion* pPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetPara() );
+ pPortion->MarkSelectionInvalid( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex(), 0 );
+
+ BOOL bInsertMode = !mpImpl->mpTextEngine->mpIMEInfos->bWasCursorOverwrite;
+
+ delete mpImpl->mpTextEngine->mpIMEInfos;
+ mpImpl->mpTextEngine->mpIMEInfos = NULL;
+
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+
+ SetInsertMode( bInsertMode );
+
+ if ( mpImpl->mpTextEngine->IsModified() )
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT )
+ {
+ DBG_ASSERT( mpImpl->mpTextEngine->mpIMEInfos, "COMMAND_EXTTEXTINPUT => Kein Start ?" );
+ if( mpImpl->mpTextEngine->mpIMEInfos )
+ {
+ const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
+
+ if ( !pData->IsOnlyCursorChanged() )
+ {
+ TextSelection aSelect( mpImpl->mpTextEngine->mpIMEInfos->aPos );
+ aSelect.GetEnd().GetIndex() = aSelect.GetEnd().GetIndex() + mpImpl->mpTextEngine->mpIMEInfos->nLen;
+ aSelect = mpImpl->mpTextEngine->ImpDeleteText( aSelect );
+ aSelect = mpImpl->mpTextEngine->ImpInsertText( aSelect, pData->GetText() );
+
+ if ( mpImpl->mpTextEngine->mpIMEInfos->bWasCursorOverwrite )
+ {
+ USHORT nOldIMETextLen = mpImpl->mpTextEngine->mpIMEInfos->nLen;
+ USHORT nNewIMETextLen = pData->GetText().Len();
+
+ if ( ( nOldIMETextLen > nNewIMETextLen ) &&
+ ( nNewIMETextLen < mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.Len() ) )
+ {
+ // restore old characters
+ USHORT nRestore = nOldIMETextLen - nNewIMETextLen;
+ TextPaM aPaM( mpImpl->mpTextEngine->mpIMEInfos->aPos );
+ aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
+ mpImpl->mpTextEngine->ImpInsertText( aPaM, mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.Copy( nNewIMETextLen, nRestore ) );
+ }
+ else if ( ( nOldIMETextLen < nNewIMETextLen ) &&
+ ( nOldIMETextLen < mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.Len() ) )
+ {
+ // overwrite
+ USHORT nOverwrite = nNewIMETextLen - nOldIMETextLen;
+ if ( ( nOldIMETextLen + nOverwrite ) > mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.Len() )
+ nOverwrite = mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.Len() - nOldIMETextLen;
+ DBG_ASSERT( nOverwrite && (nOverwrite < 0xFF00), "IME Overwrite?!" );
+ TextPaM aPaM( mpImpl->mpTextEngine->mpIMEInfos->aPos );
+ aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
+ TextSelection aSel( aPaM );
+ aSel.GetEnd().GetIndex() =
+ aSel.GetEnd().GetIndex() + nOverwrite;
+ mpImpl->mpTextEngine->ImpDeleteText( aSel );
+ }
+ }
+
+ if ( pData->GetTextAttr() )
+ {
+ mpImpl->mpTextEngine->mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().Len() );
+ mpImpl->mpTextEngine->mpIMEInfos->bCursor = pData->IsCursorVisible();
+ }
+ else
+ {
+ mpImpl->mpTextEngine->mpIMEInfos->DestroyAttribs();
+ }
+
+ TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetPara() );
+ pPPortion->MarkSelectionInvalid( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex(), 0 );
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+ }
+
+ TextSelection aNewSel = TextPaM( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetPara(), mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex()+pData->GetCursorPos() );
+ SetSelection( aNewSel );
+ SetInsertMode( !pData->IsCursorOverwrite() );
+
+ if ( pData->IsCursorVisible() )
+ ShowCursor();
+ else
+ HideCursor();
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
+ {
+ if ( mpImpl->mpTextEngine->mpIMEInfos && mpImpl->mpTextEngine->mpIMEInfos->nLen )
+ {
+ TextPaM aPaM( GetSelection().GetEnd() );
+ Rectangle aR1 = mpImpl->mpTextEngine->PaMtoEditCursor( aPaM );
+
+ USHORT nInputEnd = mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex() + mpImpl->mpTextEngine->mpIMEInfos->nLen;
+
+ if ( !mpImpl->mpTextEngine->IsFormatted() )
+ mpImpl->mpTextEngine->FormatDoc();
+
+ TEParaPortion* pParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
+ USHORT nLine = pParaPortion->GetLineNumber( aPaM.GetIndex(), sal_True );
+ TextLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ if ( pLine && ( nInputEnd > pLine->GetEnd() ) )
+ nInputEnd = pLine->GetEnd();
+ Rectangle aR2 = mpImpl->mpTextEngine->PaMtoEditCursor( TextPaM( aPaM.GetPara(), nInputEnd ) );
+
+ long nWidth = aR2.Left()-aR1.Right();
+ aR1.Move( -GetStartDocPos().X(), -GetStartDocPos().Y() );
+ GetWindow()->SetCursorRect( &aR1, nWidth );
+ }
+ else
+ {
+ GetWindow()->SetCursorRect();
+ }
+ }
+ else
+ {
+ mpImpl->mpSelEngine->Command( rCEvt );
+ }
+}
+
+void TextView::ShowCursor( BOOL bGotoCursor, BOOL bForceVisCursor )
+{
+ // Die Einstellung hat mehr Gewicht:
+ if ( !mpImpl->mbAutoScroll )
+ bGotoCursor = FALSE;
+ ImpShowCursor( bGotoCursor, bForceVisCursor, FALSE );
+}
+
+void TextView::HideCursor()
+{
+ mpImpl->mpCursor->Hide();
+}
+
+void TextView::Scroll( long ndX, long ndY )
+{
+ DBG_ASSERT( mpImpl->mpTextEngine->IsFormatted(), "Scroll: Nicht formatiert!" );
+
+ if ( !ndX && !ndY )
+ return;
+
+ Point aNewStartPos( mpImpl->maStartDocPos );
+
+ // Vertical:
+ aNewStartPos.Y() -= ndY;
+ if ( aNewStartPos.Y() < 0 )
+ aNewStartPos.Y() = 0;
+
+ // Horizontal:
+ aNewStartPos.X() -= ndX;
+ if ( aNewStartPos.X() < 0 )
+ aNewStartPos.X() = 0;
+
+ long nDiffX = mpImpl->maStartDocPos.X() - aNewStartPos.X();
+ long nDiffY = mpImpl->maStartDocPos.Y() - aNewStartPos.Y();
+
+ if ( nDiffX || nDiffY )
+ {
+ BOOL bVisCursor = mpImpl->mpCursor->IsVisible();
+ mpImpl->mpCursor->Hide();
+ mpImpl->mpWindow->Update();
+ mpImpl->maStartDocPos = aNewStartPos;
+
+ if ( mpImpl->mpTextEngine->IsRightToLeft() )
+ nDiffX = -nDiffX;
+ mpImpl->mpWindow->Scroll( nDiffX, nDiffY );
+ mpImpl->mpWindow->Update();
+ mpImpl->mpCursor->SetPos( mpImpl->mpCursor->GetPos() + Point( nDiffX, nDiffY ) );
+ if ( bVisCursor && !mpImpl->mbReadOnly )
+ mpImpl->mpCursor->Show();
+ }
+
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_VIEWSCROLLED ) );
+}
+
+void TextView::Undo()
+{
+ mpImpl->mpTextEngine->SetActiveView( this );
+ mpImpl->mpTextEngine->GetUndoManager().Undo( 1 );
+}
+
+void TextView::Redo()
+{
+ mpImpl->mpTextEngine->SetActiveView( this );
+ mpImpl->mpTextEngine->GetUndoManager().Redo( 0 );
+}
+
+void TextView::Cut()
+{
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_CUT );
+ Copy();
+ DeleteSelected();
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_CUT );
+}
+
+void TextView::Copy( uno::Reference< datatransfer::clipboard::XClipboard >& rxClipboard )
+{
+ if ( rxClipboard.is() )
+ {
+ TETextDataObject* pDataObj = new TETextDataObject( GetSelected() );
+
+ if ( mpImpl->mpTextEngine->HasAttrib( TEXTATTR_HYPERLINK ) ) // Dann auch als HTML
+ mpImpl->mpTextEngine->Write( pDataObj->GetHTMLStream(), &mpImpl->maSelection, TRUE );
+
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ rxClipboard->setContents( pDataObj, NULL );
+
+ uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY );
+ if( xFlushableClipboard.is() )
+ xFlushableClipboard->flushClipboard();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ }
+}
+
+void TextView::Copy()
+{
+ uno::Reference<datatransfer::clipboard::XClipboard> aClipboard(GetWindow()->GetClipboard());
+ Copy( aClipboard );
+}
+
+void TextView::Paste( uno::Reference< datatransfer::clipboard::XClipboard >& rxClipboard )
+{
+ if ( rxClipboard.is() )
+ {
+ uno::Reference< datatransfer::XTransferable > xDataObj;
+
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ xDataObj = rxClipboard->getContents();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+
+ if ( xDataObj.is() )
+ {
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
+ if ( xDataObj->isDataFlavorSupported( aFlavor ) )
+ {
+ try
+ {
+ uno::Any aData = xDataObj->getTransferData( aFlavor );
+ ::rtl::OUString aText;
+ aData >>= aText;
+ bool bWasTruncated = false;
+ if( mpImpl->mpTextEngine->GetMaxTextLen() != 0 )
+ bWasTruncated = ImplTruncateNewText( aText );
+ InsertNewText( aText, FALSE );
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+
+ if( bWasTruncated )
+ Edit::ShowTruncationWarning( mpImpl->mpWindow );
+ }
+ catch( const ::com::sun::star::datatransfer::UnsupportedFlavorException& )
+ {
+ }
+ }
+ }
+ }
+}
+
+void TextView::Paste()
+{
+ uno::Reference<datatransfer::clipboard::XClipboard> aClipboard(GetWindow()->GetClipboard());
+ Paste( aClipboard );
+}
+
+String TextView::GetSelected()
+{
+ return GetSelected( GetSystemLineEnd() );
+}
+
+String TextView::GetSelected( LineEnd aSeparator )
+{
+ return mpImpl->mpTextEngine->GetText( mpImpl->maSelection, aSeparator );
+}
+
+void TextView::SetInsertMode( BOOL bInsert )
+{
+ if ( mpImpl->mbInsertMode != bInsert )
+ {
+ mpImpl->mbInsertMode = bInsert;
+ ShowCursor( mpImpl->mbAutoScroll, FALSE );
+ }
+}
+
+void TextView::SetReadOnly( BOOL bReadOnly )
+{
+ if ( mpImpl->mbReadOnly != bReadOnly )
+ {
+ mpImpl->mbReadOnly = bReadOnly;
+ if ( !mpImpl->mbReadOnly )
+ ShowCursor( mpImpl->mbAutoScroll, FALSE );
+ else
+ HideCursor();
+
+ GetWindow()->SetInputContext( InputContext( mpImpl->mpTextEngine->GetFont(), bReadOnly ? INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT : 0 ) );
+ }
+}
+
+TextSelection TextView::ImpMoveCursor( const KeyEvent& rKeyEvent )
+{
+ // Eigentlich nur bei Up/Down noetig, aber was solls.
+ mpImpl->mpTextEngine->CheckIdleFormatter();
+
+ TextPaM aPaM( mpImpl->maSelection.GetEnd() );
+ TextPaM aOldEnd( aPaM );
+
+ TextDirectionality eTextDirection = TextDirectionality_LeftToRight_TopToBottom;
+ if ( mpImpl->mpTextEngine->IsRightToLeft() )
+ eTextDirection = TextDirectionality_RightToLeft_TopToBottom;
+
+ KeyEvent aTranslatedKeyEvent = rKeyEvent.LogicalTextDirectionality( eTextDirection );
+
+ BOOL bCtrl = aTranslatedKeyEvent.GetKeyCode().IsMod1() ? TRUE : FALSE;
+ USHORT nCode = aTranslatedKeyEvent.GetKeyCode().GetCode();
+
+ bool bSelect = aTranslatedKeyEvent.GetKeyCode().IsShift();
+ switch ( nCode )
+ {
+ case KEY_UP: aPaM = CursorUp( aPaM );
+ break;
+ case KEY_DOWN: aPaM = CursorDown( aPaM );
+ break;
+ case KEY_HOME: aPaM = bCtrl ? CursorStartOfDoc() : CursorStartOfLine( aPaM );
+ break;
+ case KEY_END: aPaM = bCtrl ? CursorEndOfDoc() : CursorEndOfLine( aPaM );
+ break;
+ case KEY_PAGEUP: aPaM = bCtrl ? CursorStartOfDoc() : PageUp( aPaM );
+ break;
+ case KEY_PAGEDOWN: aPaM = bCtrl ? CursorEndOfDoc() : PageDown( aPaM );
+ break;
+ case KEY_LEFT: aPaM = bCtrl ? CursorWordLeft( aPaM ) : CursorLeft( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? (USHORT)i18n::CharacterIteratorMode::SKIPCHARACTER : (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+ break;
+ case KEY_RIGHT: aPaM = bCtrl ? CursorWordRight( aPaM ) : CursorRight( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? (USHORT)i18n::CharacterIteratorMode::SKIPCHARACTER : (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+ break;
+ case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
+ bSelect = true; // fallthrough intentional
+ case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
+ aPaM = CursorWordRight( aPaM );
+ break;
+ case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
+ bSelect = true; // fallthrough intentional
+ case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
+ aPaM = CursorWordLeft( aPaM );
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
+ bSelect = true; // fallthrough intentional
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
+ aPaM = CursorStartOfLine( aPaM );
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
+ bSelect = true; // fallthrough intentional
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
+ aPaM = CursorEndOfLine( aPaM );
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
+ bSelect = true; // falltthrough intentional
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
+ aPaM = CursorStartOfParagraph( aPaM );
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
+ bSelect = true; // falltthrough intentional
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
+ aPaM = CursorEndOfParagraph( aPaM );
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
+ bSelect = true; // falltthrough intentional
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
+ aPaM = CursorStartOfDoc();
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
+ bSelect = true; // falltthrough intentional
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
+ aPaM = CursorEndOfDoc();
+ break;
+ }
+
+ // Bewirkt evtl. ein CreateAnchor oder Deselection all
+ mpImpl->mpSelEngine->CursorPosChanging( bSelect, aTranslatedKeyEvent.GetKeyCode().IsMod1() );
+
+ if ( aOldEnd != aPaM )
+ {
+ mpImpl->mpTextEngine->CursorMoved( aOldEnd.GetPara() );
+
+
+ TextSelection aOldSelection( mpImpl->maSelection );
+ TextSelection aNewSelection( mpImpl->maSelection );
+ aNewSelection.GetEnd() = aPaM;
+ if ( bSelect )
+ {
+ // Dann wird die Selektion erweitert...
+ ImpSetSelection( aNewSelection );
+ ShowSelection( TextSelection( aOldEnd, aPaM ) );
+ }
+ else
+ {
+ aNewSelection.GetStart() = aPaM;
+ ImpSetSelection( aNewSelection );
+ }
+ }
+
+ return mpImpl->maSelection;
+}
+
+void TextView::InsertText( const XubString& rStr, BOOL bSelect )
+{
+ InsertNewText( rStr, bSelect );
+}
+
+void TextView::InsertNewText( const rtl::OUString& rStr, BOOL bSelect )
+{
+// HideSelection();
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_INSERT );
+
+ /* #i87633#
+ break inserted text into chunks that fit into the underlying String
+ based API (which has a maximum length of 65534 elements
+
+ note: this will of course still cause problems for lines longer than those
+ 65534 elements, but those cases will hopefully be few.
+ In the long run someone should switch the TextEngine to OUString instead of String
+ */
+ sal_Int32 nLen = rStr.getLength();
+ sal_Int32 nPos = 0;
+ while( nLen )
+ {
+ sal_Int32 nChunkLen = nLen > 65534 ? 65534 : nLen;
+ String aChunk( rStr.copy( nPos, nChunkLen ) );
+
+ TextSelection aNewSel( mpImpl->maSelection );
+
+ TextPaM aPaM = mpImpl->mpTextEngine->ImpInsertText( mpImpl->maSelection, aChunk );
+
+ if ( bSelect )
+ {
+ aNewSel.Justify();
+ aNewSel.GetEnd() = aPaM;
+ }
+ else
+ {
+ aNewSel = aPaM;
+ }
+
+ ImpSetSelection( aNewSel );
+ nLen -= nChunkLen;
+ nPos += nChunkLen;
+ }
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_INSERT );
+
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+}
+
+/*
+void TextView::InsertText( const XubString& rStr, BOOL bSelect )
+{
+// HideSelection();
+
+ TextSelection aNewSel( mpImpl->maSelection );
+
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_INSERT );
+ TextPaM aPaM = mpImpl->mpTextEngine->ImpInsertText( mpImpl->maSelection, rStr );
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_INSERT );
+
+ if ( bSelect )
+ {
+ aNewSel.Justify();
+ aNewSel.GetEnd() = aPaM;
+ }
+ else
+ {
+ aNewSel = aPaM;
+ }
+
+ ImpSetSelection( aNewSel );
+
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+}
+*/
+
+// OLD
+TextPaM TextView::CursorLeft( const TextPaM& rPaM, BOOL bWordMode )
+{
+ return bWordMode ? CursorWordLeft( rPaM ) : CursorLeft( rPaM, (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+
+ // Remove (USHORT) typecasts in this file when removing this method!
+}
+
+// OLD
+TextPaM TextView::CursorRight( const TextPaM& rPaM, BOOL bWordMode )
+{
+ return bWordMode ? CursorWordRight( rPaM ) : CursorRight( rPaM, (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+
+ // Remove (USHORT) typecasts in this file when removing this method!
+}
+
+TextPaM TextView::CursorLeft( const TextPaM& rPaM, USHORT nCharacterIteratorMode )
+{
+ TextPaM aPaM( rPaM );
+
+ if ( aPaM.GetIndex() )
+ {
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ sal_Int32 nCount = 1;
+ aPaM.GetIndex() = (USHORT)xBI->previousCharacters( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), nCharacterIteratorMode, nCount, nCount );
+ }
+ else if ( aPaM.GetPara() )
+ {
+ aPaM.GetPara()--;
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ aPaM.GetIndex() = pNode->GetText().Len();
+ }
+ return aPaM;
+}
+
+TextPaM TextView::CursorRight( const TextPaM& rPaM, USHORT nCharacterIteratorMode )
+{
+ TextPaM aPaM( rPaM );
+
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ if ( aPaM.GetIndex() < pNode->GetText().Len() )
+ {
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ sal_Int32 nCount = 1;
+ aPaM.GetIndex() = (USHORT)xBI->nextCharacters( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), nCharacterIteratorMode, nCount, nCount );
+ }
+ else if ( aPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().Count()-1) )
+ {
+ aPaM.GetPara()++;
+ aPaM.GetIndex() = 0;
+ }
+
+ return aPaM;
+}
+
+
+TextPaM TextView::CursorWordLeft( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+
+ if ( aPaM.GetIndex() )
+ {
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ if ( aBoundary.startPos >= rPaM.GetIndex() )
+ aBoundary = xBI->previousWord( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ aPaM.GetIndex() = ( aBoundary.startPos != -1 ) ? (USHORT)aBoundary.startPos : 0;
+ }
+ else if ( aPaM.GetPara() )
+ {
+ aPaM.GetPara()--;
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ aPaM.GetIndex() = pNode->GetText().Len();
+ }
+ return aPaM;
+}
+
+
+TextPaM TextView::CursorWordRight( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ if ( aPaM.GetIndex() < pNode->GetText().Len() )
+ {
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ i18n::Boundary aBoundary = xBI->nextWord( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ aPaM.GetIndex() = (USHORT)aBoundary.startPos;
+ }
+ else if ( aPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().Count()-1) )
+ {
+ aPaM.GetPara()++;
+ aPaM.GetIndex() = 0;
+ }
+
+ return aPaM;
+}
+
+TextPaM TextView::ImpDelete( BYTE nMode, BYTE nDelMode )
+{
+ if ( mpImpl->maSelection.HasRange() ) // dann nur Sel. loeschen
+ return mpImpl->mpTextEngine->ImpDeleteText( mpImpl->maSelection );
+
+ TextPaM aStartPaM = mpImpl->maSelection.GetStart();
+ TextPaM aEndPaM = aStartPaM;
+ if ( nMode == DEL_LEFT )
+ {
+ if ( nDelMode == DELMODE_SIMPLE )
+ {
+ aEndPaM = CursorLeft( aEndPaM, (USHORT)i18n::CharacterIteratorMode::SKIPCHARACTER );
+ }
+ else if ( nDelMode == DELMODE_RESTOFWORD )
+ {
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aEndPaM.GetPara() );
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ if ( aBoundary.startPos == mpImpl->maSelection.GetEnd().GetIndex() )
+ aBoundary = xBI->previousWord( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ // #i63506# startPos is -1 when the paragraph starts with a tab
+ aEndPaM.GetIndex() = (aBoundary.startPos >= 0) ? (USHORT)aBoundary.startPos : 0;
+ }
+ else // DELMODE_RESTOFCONTENT
+ {
+ if ( aEndPaM.GetIndex() != 0 )
+ aEndPaM.GetIndex() = 0;
+ else if ( aEndPaM.GetPara() )
+ {
+ // Absatz davor
+ aEndPaM.GetPara()--;
+ aEndPaM.GetIndex() = 0;
+ }
+ }
+ }
+ else
+ {
+ if ( nDelMode == DELMODE_SIMPLE )
+ {
+ aEndPaM = CursorRight( aEndPaM, (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+ }
+ else if ( nDelMode == DELMODE_RESTOFWORD )
+ {
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aEndPaM.GetPara() );
+ uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
+ i18n::Boundary aBoundary = xBI->nextWord( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ aEndPaM.GetIndex() = (USHORT)aBoundary.startPos;
+ }
+ else // DELMODE_RESTOFCONTENT
+ {
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aEndPaM.GetPara() );
+ if ( aEndPaM.GetIndex() < pNode->GetText().Len() )
+ aEndPaM.GetIndex() = pNode->GetText().Len();
+ else if ( aEndPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().Count() - 1 ) )
+ {
+ // Absatz danach
+ aEndPaM.GetPara()++;
+ TextNode* pNextNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aEndPaM.GetPara() );
+ aEndPaM.GetIndex() = pNextNode->GetText().Len();
+ }
+ }
+ }
+
+ return mpImpl->mpTextEngine->ImpDeleteText( TextSelection( aStartPaM, aEndPaM ) );
+}
+
+
+
+TextPaM TextView::CursorUp( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+
+ long nX;
+ if ( mpImpl->mnTravelXPos == TRAVEL_X_DONTKNOW )
+ {
+ nX = mpImpl->mpTextEngine->GetEditCursor( rPaM, FALSE ).Left();
+ mpImpl->mnTravelXPos = (USHORT)nX+1;
+ }
+ else
+ nX = mpImpl->mnTravelXPos;
+
+ TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
+ USHORT nLine = pPPortion->GetLineNumber( rPaM.GetIndex(), FALSE );
+ if ( nLine ) // gleicher Absatz
+ {
+ USHORT nCharPos = mpImpl->mpTextEngine->GetCharPos( rPaM.GetPara(), nLine-1, nX );
+ aPaM.GetIndex() = nCharPos;
+ // Wenn davor eine autom.Umgebrochene Zeile, und ich muss genau an das
+ // Ende dieser Zeile, landet der Cursor in der aktuellen Zeile am Anfang
+ // Siehe Problem: Letztes Zeichen einer autom.umgebr. Zeile = Cursor
+ TextLine* pLine = pPPortion->GetLines().GetObject( nLine - 1 );
+ if ( aPaM.GetIndex() && ( aPaM.GetIndex() == pLine->GetEnd() ) )
+ aPaM.GetIndex()--;
+ }
+ else if ( rPaM.GetPara() ) // vorheriger Absatz
+ {
+ aPaM.GetPara()--;
+ pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
+ USHORT nL = pPPortion->GetLines().Count() - 1;
+ USHORT nCharPos = mpImpl->mpTextEngine->GetCharPos( aPaM.GetPara(), nL, nX+1 );
+ aPaM.GetIndex() = nCharPos;
+ }
+
+ return aPaM;
+}
+
+TextPaM TextView::CursorDown( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+
+ long nX;
+ if ( mpImpl->mnTravelXPos == TRAVEL_X_DONTKNOW )
+ {
+ nX = mpImpl->mpTextEngine->GetEditCursor( rPaM, FALSE ).Left();
+ mpImpl->mnTravelXPos = (USHORT)nX+1;
+ }
+ else
+ nX = mpImpl->mnTravelXPos;
+
+ TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
+ USHORT nLine = pPPortion->GetLineNumber( rPaM.GetIndex(), FALSE );
+ if ( nLine < ( pPPortion->GetLines().Count() - 1 ) )
+ {
+ USHORT nCharPos = mpImpl->mpTextEngine->GetCharPos( rPaM.GetPara(), nLine+1, nX );
+ aPaM.GetIndex() = nCharPos;
+
+ // Sonderbehandlung siehe CursorUp...
+ TextLine* pLine = pPPortion->GetLines().GetObject( nLine + 1 );
+ if ( ( aPaM.GetIndex() == pLine->GetEnd() ) && ( aPaM.GetIndex() > pLine->GetStart() ) && aPaM.GetIndex() < pPPortion->GetNode()->GetText().Len() )
+ aPaM.GetIndex()--;
+ }
+ else if ( rPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().Count() - 1 ) ) // naechster Absatz
+ {
+ aPaM.GetPara()++;
+ pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
+ USHORT nCharPos = mpImpl->mpTextEngine->GetCharPos( aPaM.GetPara(), 0, nX+1 );
+ aPaM.GetIndex() = nCharPos;
+ TextLine* pLine = pPPortion->GetLines().GetObject( 0 );
+ if ( ( aPaM.GetIndex() == pLine->GetEnd() ) && ( aPaM.GetIndex() > pLine->GetStart() ) && ( pPPortion->GetLines().Count() > 1 ) )
+ aPaM.GetIndex()--;
+ }
+
+ return aPaM;
+}
+
+TextPaM TextView::CursorStartOfLine( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+
+ TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
+ USHORT nLine = pPPortion->GetLineNumber( aPaM.GetIndex(), FALSE );
+ TextLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ aPaM.GetIndex() = pLine->GetStart();
+
+ return aPaM;
+}
+
+TextPaM TextView::CursorEndOfLine( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+
+ TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
+ USHORT nLine = pPPortion->GetLineNumber( aPaM.GetIndex(), FALSE );
+ TextLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ aPaM.GetIndex() = pLine->GetEnd();
+
+ if ( pLine->GetEnd() > pLine->GetStart() ) // Leerzeile
+ {
+ xub_Unicode cLastChar = pPPortion->GetNode()->GetText().GetChar((USHORT)(aPaM.GetIndex()-1) );
+ if ( ( cLastChar == ' ' ) && ( aPaM.GetIndex() != pPPortion->GetNode()->GetText().Len() ) )
+ {
+ // Bei einem Blank in einer autom. umgebrochenen Zeile macht es Sinn,
+ // davor zu stehen, da der Anwender hinter das Wort will.
+ // Wenn diese geaendert wird, Sonderbehandlung fuer Pos1 nach End!
+ aPaM.GetIndex()--;
+ }
+ }
+ return aPaM;
+}
+
+TextPaM TextView::CursorStartOfParagraph( const TextPaM& rPaM )
+{
+ TextPaM aPaM( rPaM );
+ aPaM.GetIndex() = 0;
+ return aPaM;
+}
+
+TextPaM TextView::CursorEndOfParagraph( const TextPaM& rPaM )
+{
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( rPaM.GetPara() );
+ TextPaM aPaM( rPaM );
+ aPaM.GetIndex() = pNode->GetText().Len();
+ return aPaM;
+}
+
+TextPaM TextView::CursorStartOfDoc()
+{
+ TextPaM aPaM( 0, 0 );
+ return aPaM;
+}
+
+TextPaM TextView::CursorEndOfDoc()
+{
+ ULONG nNode = mpImpl->mpTextEngine->mpDoc->GetNodes().Count() - 1;
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( nNode );
+ TextPaM aPaM( nNode, pNode->GetText().Len() );
+ return aPaM;
+}
+
+TextPaM TextView::PageUp( const TextPaM& rPaM )
+{
+ Rectangle aRec = mpImpl->mpTextEngine->PaMtoEditCursor( rPaM );
+ Point aTopLeft = aRec.TopLeft();
+ aTopLeft.Y() -= mpImpl->mpWindow->GetOutputSizePixel().Height() * 9/10;
+ aTopLeft.X() += 1;
+ if ( aTopLeft.Y() < 0 )
+ aTopLeft.Y() = 0;
+
+ TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aTopLeft );
+ return aPaM;
+}
+
+TextPaM TextView::PageDown( const TextPaM& rPaM )
+{
+ Rectangle aRec = mpImpl->mpTextEngine->PaMtoEditCursor( rPaM );
+ Point aBottomRight = aRec.BottomRight();
+ aBottomRight.Y() += mpImpl->mpWindow->GetOutputSizePixel().Height() * 9/10;
+ aBottomRight.X() += 1;
+ long nHeight = mpImpl->mpTextEngine->GetTextHeight();
+ if ( aBottomRight.Y() > nHeight )
+ aBottomRight.Y() = nHeight-1;
+
+ TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aBottomRight );
+ return aPaM;
+}
+
+void TextView::ImpShowCursor( BOOL bGotoCursor, BOOL bForceVisCursor, BOOL bSpecial )
+{
+ if ( mpImpl->mpTextEngine->IsFormatting() )
+ return;
+ if ( mpImpl->mpTextEngine->GetUpdateMode() == FALSE )
+ return;
+ if ( mpImpl->mpTextEngine->IsInUndo() )
+ return;
+
+ mpImpl->mpTextEngine->CheckIdleFormatter();
+ if ( !mpImpl->mpTextEngine->IsFormatted() )
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+
+
+ TextPaM aPaM( mpImpl->maSelection.GetEnd() );
+ Rectangle aEditCursor = mpImpl->mpTextEngine->PaMtoEditCursor( aPaM, bSpecial );
+
+ // Remember that we placed the cursor behind the last character of a line
+ mpImpl->mbCursorAtEndOfLine = false;
+ if( bSpecial )
+ {
+ TEParaPortion* pParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
+ mpImpl->mbCursorAtEndOfLine =
+ pParaPortion->GetLineNumber( aPaM.GetIndex(), TRUE ) != pParaPortion->GetLineNumber( aPaM.GetIndex(), FALSE );
+ }
+
+ if ( !IsInsertMode() && !mpImpl->maSelection.HasRange() )
+ {
+ TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes().GetObject( aPaM.GetPara() );
+ if ( pNode->GetText().Len() && ( aPaM.GetIndex() < pNode->GetText().Len() ) )
+ {
+ // If we are behind a portion, and the next portion has other direction, we must change position...
+ aEditCursor.Left() = aEditCursor.Right() = mpImpl->mpTextEngine->GetEditCursor( aPaM, FALSE, TRUE ).Left();
+
+ TEParaPortion* pParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
+
+ USHORT nTextPortionStart = 0;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, TRUE );
+ TETextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ if ( pTextPortion->GetKind() == PORTIONKIND_TAB )
+ {
+ if ( mpImpl->mpTextEngine->IsRightToLeft() )
+ {
+
+ }
+ aEditCursor.Right() += pTextPortion->GetWidth();
+ }
+ else
+ {
+ TextPaM aNext = CursorRight( TextPaM( aPaM.GetPara(), aPaM.GetIndex() ), (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+ aEditCursor.Right() = mpImpl->mpTextEngine->GetEditCursor( aNext, TRUE ).Left();
+ }
+ }
+ }
+
+ Size aOutSz = mpImpl->mpWindow->GetOutputSizePixel();
+ if ( aEditCursor.GetHeight() > aOutSz.Height() )
+ aEditCursor.Bottom() = aEditCursor.Top() + aOutSz.Height() - 1;
+
+ aEditCursor.Left() -= 1;
+
+ if ( bGotoCursor
+ // #i81283# protext maStartDocPos against initialization problems
+ && aOutSz.Width() && aOutSz.Height()
+ )
+ {
+ long nVisStartY = mpImpl->maStartDocPos.Y();
+ long nVisEndY = mpImpl->maStartDocPos.Y() + aOutSz.Height();
+ long nVisStartX = mpImpl->maStartDocPos.X();
+ long nVisEndX = mpImpl->maStartDocPos.X() + aOutSz.Width();
+ long nMoreX = aOutSz.Width() / 4;
+
+ Point aNewStartPos( mpImpl->maStartDocPos );
+
+ if ( aEditCursor.Bottom() > nVisEndY )
+ {
+ aNewStartPos.Y() += ( aEditCursor.Bottom() - nVisEndY );
+ }
+ else if ( aEditCursor.Top() < nVisStartY )
+ {
+ aNewStartPos.Y() -= ( nVisStartY - aEditCursor.Top() );
+ }
+
+ if ( aEditCursor.Right() >= nVisEndX )
+ {
+ aNewStartPos.X() += ( aEditCursor.Right() - nVisEndX );
+
+ // Darfs ein bischen mehr sein?
+ aNewStartPos.X() += nMoreX;
+ }
+ else if ( aEditCursor.Left() <= nVisStartX )
+ {
+ aNewStartPos.X() -= ( nVisStartX - aEditCursor.Left() );
+
+ // Darfs ein bischen mehr sein?
+ aNewStartPos.X() -= nMoreX;
+ }
+
+ // X kann durch das 'bischen mehr' falsch sein:
+// ULONG nMaxTextWidth = mpImpl->mpTextEngine->GetMaxTextWidth();
+// if ( !nMaxTextWidth || ( nMaxTextWidth > 0x7FFFFFFF ) )
+// nMaxTextWidth = 0x7FFFFFFF;
+// long nMaxX = (long)nMaxTextWidth - aOutSz.Width();
+ long nMaxX = mpImpl->mpTextEngine->CalcTextWidth() - aOutSz.Width();
+ if ( nMaxX < 0 )
+ nMaxX = 0;
+
+ if ( aNewStartPos.X() < 0 )
+ aNewStartPos.X() = 0;
+ else if ( aNewStartPos.X() > nMaxX )
+ aNewStartPos.X() = nMaxX;
+
+ // Y sollte nicht weiter unten als noetig liegen:
+ long nYMax = mpImpl->mpTextEngine->GetTextHeight() - aOutSz.Height();
+ if ( nYMax < 0 )
+ nYMax = 0;
+ if ( aNewStartPos.Y() > nYMax )
+ aNewStartPos.Y() = nYMax;
+
+ if ( aNewStartPos != mpImpl->maStartDocPos )
+ Scroll( -(aNewStartPos.X() - mpImpl->maStartDocPos.X()), -(aNewStartPos.Y() - mpImpl->maStartDocPos.Y()) );
+ }
+
+ if ( aEditCursor.Right() < aEditCursor.Left() )
+ {
+ long n = aEditCursor.Left();
+ aEditCursor.Left() = aEditCursor.Right();
+ aEditCursor.Right() = n;
+ }
+
+ Point aPoint( GetWindowPos( !mpImpl->mpTextEngine->IsRightToLeft() ? aEditCursor.TopLeft() : aEditCursor.TopRight() ) );
+ mpImpl->mpCursor->SetPos( aPoint );
+ mpImpl->mpCursor->SetSize( aEditCursor.GetSize() );
+ if ( bForceVisCursor && mpImpl->mbCursorEnabled )
+ mpImpl->mpCursor->Show();
+}
+
+BOOL TextView::SetCursorAtPoint( const Point& rPosPixel )
+{
+ mpImpl->mpTextEngine->CheckIdleFormatter();
+
+ Point aDocPos = GetDocPos( rPosPixel );
+
+ TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aDocPos );
+
+ // aTmpNewSel: Diff zwischen alt und neu, nicht die neue Selektion
+ TextSelection aTmpNewSel( mpImpl->maSelection.GetEnd(), aPaM );
+ TextSelection aNewSel( mpImpl->maSelection );
+ aNewSel.GetEnd() = aPaM;
+
+ if ( !mpImpl->mpSelEngine->HasAnchor() )
+ {
+ if ( mpImpl->maSelection.GetStart() != aPaM )
+ mpImpl->mpTextEngine->CursorMoved( mpImpl->maSelection.GetStart().GetPara() );
+ aNewSel.GetStart() = aPaM;
+ ImpSetSelection( aNewSel );
+ }
+ else
+ {
+ ImpSetSelection( aNewSel );
+ ShowSelection( aTmpNewSel );
+ }
+
+ BOOL bForceCursor = mpImpl->mpDDInfo ? FALSE : TRUE; // && !mbInSelection
+ ImpShowCursor( mpImpl->mbAutoScroll, bForceCursor, FALSE );
+ return TRUE;
+}
+
+BOOL TextView::IsSelectionAtPoint( const Point& rPosPixel )
+{
+// if ( !Rectangle( Point(), mpImpl->mpWindow->GetOutputSizePixel() ).IsInside( rPosPixel ) && !mbInSelection )
+// return FALSE;
+
+ Point aDocPos = GetDocPos( rPosPixel );
+ TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aDocPos, FALSE );
+ // Bei Hyperlinks D&D auch ohne Selektion starten.
+ // BeginDrag wird aber nur gerufen, wenn IsSelectionAtPoint()
+ // Problem: IsSelectionAtPoint wird bei Command() nicht gerufen,
+ // wenn vorher im MBDown schon FALSE returnt wurde.
+ return ( IsInSelection( aPaM ) ||
+ ( /* mpImpl->mpSelEngine->IsInCommand() && */ mpImpl->mpTextEngine->FindAttrib( aPaM, TEXTATTR_HYPERLINK ) ) );
+}
+
+BOOL TextView::IsInSelection( const TextPaM& rPaM )
+{
+ TextSelection aSel = mpImpl->maSelection;
+ aSel.Justify();
+
+ ULONG nStartNode = aSel.GetStart().GetPara();
+ ULONG nEndNode = aSel.GetEnd().GetPara();
+ ULONG nCurNode = rPaM.GetPara();
+
+ if ( ( nCurNode > nStartNode ) && ( nCurNode < nEndNode ) )
+ return TRUE;
+
+ if ( nStartNode == nEndNode )
+ {
+ if ( nCurNode == nStartNode )
+ if ( ( rPaM.GetIndex() >= aSel.GetStart().GetIndex() ) && ( rPaM.GetIndex() < aSel.GetEnd().GetIndex() ) )
+ return TRUE;
+ }
+ else if ( ( nCurNode == nStartNode ) && ( rPaM.GetIndex() >= aSel.GetStart().GetIndex() ) )
+ return TRUE;
+ else if ( ( nCurNode == nEndNode ) && ( rPaM.GetIndex() < aSel.GetEnd().GetIndex() ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+void TextView::ImpHideDDCursor()
+{
+ if ( mpImpl->mpDDInfo && mpImpl->mpDDInfo->mbVisCursor )
+ {
+ mpImpl->mpDDInfo->maCursor.Hide();
+ mpImpl->mpDDInfo->mbVisCursor = FALSE;
+ }
+}
+
+void TextView::ImpShowDDCursor()
+{
+ if ( !mpImpl->mpDDInfo->mbVisCursor )
+ {
+ Rectangle aCursor = mpImpl->mpTextEngine->PaMtoEditCursor( mpImpl->mpDDInfo->maDropPos, TRUE );
+ aCursor.Right()++;
+ aCursor.SetPos( GetWindowPos( aCursor.TopLeft() ) );
+
+ mpImpl->mpDDInfo->maCursor.SetWindow( mpImpl->mpWindow );
+ mpImpl->mpDDInfo->maCursor.SetPos( aCursor.TopLeft() );
+ mpImpl->mpDDInfo->maCursor.SetSize( aCursor.GetSize() );
+ mpImpl->mpDDInfo->maCursor.Show();
+ mpImpl->mpDDInfo->mbVisCursor = TRUE;
+ }
+}
+
+void TextView::SetPaintSelection( BOOL bPaint )
+{
+ if ( bPaint != mpImpl->mbPaintSelection )
+ {
+ mpImpl->mbPaintSelection = bPaint;
+ ShowSelection( mpImpl->maSelection );
+ }
+}
+
+void TextView::SetHighlightSelection( BOOL bSelectByHighlight )
+{
+ if ( bSelectByHighlight != mpImpl->mbHighlightSelection )
+ {
+ // Falls umschalten zwischendurch moeglich...
+ mpImpl->mbHighlightSelection = bSelectByHighlight;
+ }
+}
+
+BOOL TextView::Read( SvStream& rInput )
+{
+ BOOL bDone = mpImpl->mpTextEngine->Read( rInput, &mpImpl->maSelection );
+ ShowCursor();
+ return bDone;
+}
+
+BOOL TextView::Write( SvStream& rOutput )
+{
+ return mpImpl->mpTextEngine->Read( rOutput, &mpImpl->maSelection );
+}
+
+bool TextView::ImplTruncateNewText( rtl::OUString& rNewText ) const
+{
+ bool bTruncated = false;
+
+ if( rNewText.getLength() > 65534 ) // limit to String API
+ {
+ rNewText = rNewText.copy( 0, 65534 );
+ bTruncated = true;
+ }
+
+ ULONG nMaxLen = mpImpl->mpTextEngine->GetMaxTextLen();
+ // 0 means unlimited, there is just the String API limit handled above
+ if( nMaxLen != 0 )
+ {
+ ULONG nCurLen = mpImpl->mpTextEngine->GetTextLen();
+
+ sal_uInt32 nNewLen = rNewText.getLength();
+ if ( nCurLen + nNewLen > nMaxLen )
+ {
+ // see how much text will be replaced
+ ULONG nSelLen = mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection );
+ if ( nCurLen + nNewLen - nSelLen > nMaxLen )
+ {
+ sal_uInt32 nTruncatedLen = static_cast<sal_uInt32>(nMaxLen - (nCurLen - nSelLen));
+ rNewText = rNewText.copy( 0, nTruncatedLen );
+ bTruncated = true;
+ }
+ }
+ }
+ return bTruncated;
+}
+
+BOOL TextView::ImplCheckTextLen( const String& rNewText )
+{
+ BOOL bOK = TRUE;
+ if ( mpImpl->mpTextEngine->GetMaxTextLen() )
+ {
+ ULONG n = mpImpl->mpTextEngine->GetTextLen();
+ n += rNewText.Len();
+ if ( n > mpImpl->mpTextEngine->GetMaxTextLen() )
+ {
+ // nur dann noch ermitteln, wie viel Text geloescht wird
+ n -= mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection );
+ if ( n > mpImpl->mpTextEngine->GetMaxTextLen() )
+ {
+ // Beep hat hier eigentlich nichts verloren, sondern lieber ein Hdl,
+ // aber so funktioniert es wenigstens in ME, BasicIDE, SourceView
+ Sound::Beep();
+ bOK = FALSE;
+ }
+ }
+ }
+ return bOK;
+}
+
+void TextView::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( mpImpl->mbClickedInSelection )
+ {
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT( mpImpl->maSelection.HasRange(), "TextView::dragGestureRecognized: mpImpl->mbClickedInSelection, but no selection?" );
+
+ delete mpImpl->mpDDInfo;
+ mpImpl->mpDDInfo = new TextDDInfo;
+ mpImpl->mpDDInfo->mbStarterOfDD = TRUE;
+
+ TETextDataObject* pDataObj = new TETextDataObject( GetSelected() );
+
+ if ( mpImpl->mpTextEngine->HasAttrib( TEXTATTR_HYPERLINK ) ) // Dann auch als HTML
+ mpImpl->mpTextEngine->Write( pDataObj->GetHTMLStream(), &mpImpl->maSelection, TRUE );
+
+
+ /*
+ // D&D eines Hyperlinks.
+ // Besser waere es im MBDown sich den MBDownPaM zu merken,
+ // ist dann aber inkompatibel => spaeter mal umstellen.
+ TextPaM aPaM( mpImpl->mpTextEngine->GetPaM( GetDocPos( GetWindow()->GetPointerPosPixel() ) ) );
+ const TextCharAttrib* pAttr = mpImpl->mpTextEngine->FindCharAttrib( aPaM, TEXTATTR_HYPERLINK );
+ if ( pAttr )
+ {
+ aSel = aPaM;
+ aSel.GetStart().GetIndex() = pAttr->GetStart();
+ aSel.GetEnd().GetIndex() = pAttr->GetEnd();
+
+ const TextAttribHyperLink& rLink = (const TextAttribHyperLink&)pAttr->GetAttr();
+ String aText( rLink.GetDescription() );
+ if ( !aText.Len() )
+ aText = mpImpl->mpTextEngine->GetText( aSel );
+ INetBookmark aBookmark( rLink.GetURL(), aText );
+ aBookmark.CopyDragServer();
+ }
+ */
+
+ mpImpl->mpCursor->Hide();
+
+ sal_Int8 nActions = datatransfer::dnd::DNDConstants::ACTION_COPY;
+ if ( !IsReadOnly() )
+ nActions |= datatransfer::dnd::DNDConstants::ACTION_MOVE;
+ rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, pDataObj, mpImpl->mxDnDListener );
+ }
+}
+
+void TextView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ImpHideDDCursor();
+ delete mpImpl->mpDDInfo;
+ mpImpl->mpDDInfo = NULL;
+}
+
+void TextView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ BOOL bChanges = FALSE;
+ if ( !mpImpl->mbReadOnly && mpImpl->mpDDInfo )
+ {
+ ImpHideDDCursor();
+
+ // Daten fuer das loeschen nach einem DROP_MOVE:
+ TextSelection aPrevSel( mpImpl->maSelection );
+ aPrevSel.Justify();
+ ULONG nPrevParaCount = mpImpl->mpTextEngine->GetParagraphCount();
+ USHORT nPrevStartParaLen = mpImpl->mpTextEngine->GetTextLen( aPrevSel.GetStart().GetPara() );
+
+ BOOL bStarterOfDD = FALSE;
+ for ( USHORT nView = mpImpl->mpTextEngine->GetViewCount(); nView && !bStarterOfDD; )
+ bStarterOfDD = mpImpl->mpTextEngine->GetView( --nView )->mpImpl->mpDDInfo ? mpImpl->mpTextEngine->GetView( nView )->mpImpl->mpDDInfo->mbStarterOfDD : FALSE;
+
+ HideSelection();
+ ImpSetSelection( mpImpl->mpDDInfo->maDropPos );
+
+ mpImpl->mpTextEngine->UndoActionStart( TEXTUNDO_DRAGANDDROP );
+
+ String aText;
+ uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
+ if ( xDataObj.is() )
+ {
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
+ if ( xDataObj->isDataFlavorSupported( aFlavor ) )
+ {
+ uno::Any aData = xDataObj->getTransferData( aFlavor );
+ ::rtl::OUString aOUString;
+ aData >>= aOUString;
+ aText = aOUString;
+ aText.ConvertLineEnd( LINEEND_LF );
+ }
+ }
+
+ if ( aText.Len() && ( aText.GetChar( aText.Len()-1 ) == LINE_SEP ) )
+ aText.Erase( aText.Len()-1 );
+
+ TextPaM aTempStart = mpImpl->maSelection.GetStart();
+ if ( ImplCheckTextLen( aText ) )
+ ImpSetSelection( mpImpl->mpTextEngine->ImpInsertText( mpImpl->mpDDInfo->maDropPos, aText ) );
+ if(mpImpl->mbSupportProtectAttribute)
+ {
+ mpImpl->mpTextEngine->SetAttrib( TextAttribProtect(),
+ aTempStart.GetPara(),
+ aTempStart.GetIndex(),
+ mpImpl->maSelection.GetEnd().GetIndex(), FALSE );
+ }
+
+ if ( aPrevSel.HasRange() &&
+ !mpImpl->mbSupportProtectAttribute && // don't remove currently selected element
+ (( rDTDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) || !bStarterOfDD) )
+ {
+ // ggf. Selection anpasssen:
+ if ( ( mpImpl->mpDDInfo->maDropPos.GetPara() < aPrevSel.GetStart().GetPara() ) ||
+ ( ( mpImpl->mpDDInfo->maDropPos.GetPara() == aPrevSel.GetStart().GetPara() )
+ && ( mpImpl->mpDDInfo->maDropPos.GetIndex() < aPrevSel.GetStart().GetIndex() ) ) )
+ {
+ ULONG nNewParasBeforeSelection =
+ mpImpl->mpTextEngine->GetParagraphCount() - nPrevParaCount;
+
+ aPrevSel.GetStart().GetPara() += nNewParasBeforeSelection;
+ aPrevSel.GetEnd().GetPara() += nNewParasBeforeSelection;
+
+ if ( mpImpl->mpDDInfo->maDropPos.GetPara() == aPrevSel.GetStart().GetPara() )
+ {
+ USHORT nNewChars =
+ mpImpl->mpTextEngine->GetTextLen( aPrevSel.GetStart().GetPara() ) - nPrevStartParaLen;
+
+ aPrevSel.GetStart().GetIndex() =
+ aPrevSel.GetStart().GetIndex() + nNewChars;
+ if ( aPrevSel.GetStart().GetPara() == aPrevSel.GetEnd().GetPara() )
+ aPrevSel.GetEnd().GetIndex() =
+ aPrevSel.GetEnd().GetIndex() + nNewChars;
+ }
+ }
+ else
+ {
+ // aktuelle Selektion anpassen
+ TextPaM aPaM = mpImpl->maSelection.GetStart();
+ aPaM.GetPara() -= ( aPrevSel.GetEnd().GetPara() - aPrevSel.GetStart().GetPara() );
+ if ( aPrevSel.GetEnd().GetPara() == mpImpl->mpDDInfo->maDropPos.GetPara() )
+ {
+ aPaM.GetIndex() =
+ aPaM.GetIndex() - aPrevSel.GetEnd().GetIndex();
+ if ( aPrevSel.GetStart().GetPara() == mpImpl->mpDDInfo->maDropPos.GetPara() )
+ aPaM.GetIndex() =
+ aPaM.GetIndex() + aPrevSel.GetStart().GetIndex();
+ }
+ ImpSetSelection( aPaM );
+
+ }
+ mpImpl->mpTextEngine->ImpDeleteText( aPrevSel );
+ }
+
+ mpImpl->mpTextEngine->UndoActionEnd( TEXTUNDO_DRAGANDDROP );
+
+ delete mpImpl->mpDDInfo;
+ mpImpl->mpDDInfo = 0;
+
+ mpImpl->mpTextEngine->FormatAndUpdate( this );
+
+ mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
+ }
+ rDTDE.Context->dropComplete( bChanges );
+}
+
+void TextView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void TextView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+ ImpHideDDCursor();
+}
+
+void TextView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ if ( !mpImpl->mpDDInfo )
+ mpImpl->mpDDInfo = new TextDDInfo;
+
+ TextPaM aPrevDropPos = mpImpl->mpDDInfo->maDropPos;
+ Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
+ Point aDocPos = GetDocPos( aMousePos );
+ mpImpl->mpDDInfo->maDropPos = mpImpl->mpTextEngine->GetPaM( aDocPos );
+
+/*
+ Size aOutSize = mpImpl->mpWindow->GetOutputSizePixel();
+ if ( ( aMousePos.X() < 0 ) || ( aMousePos.X() > aOutSize.Width() ) ||
+ ( aMousePos.Y() < 0 ) || ( aMousePos.Y() > aOutSize.Height() ) )
+ {
+ // Scroll?
+ // No, I will not receive events for this...
+ }
+*/
+
+ sal_Bool bProtected = sal_False;
+ if(mpImpl->mbSupportProtectAttribute)
+ {
+ const TextCharAttrib* pStartAttr = mpImpl->mpTextEngine->FindCharAttrib(
+ mpImpl->mpDDInfo->maDropPos,
+ TEXTATTR_PROTECTED );
+ bProtected = pStartAttr != 0 &&
+ pStartAttr->GetStart() != mpImpl->mpDDInfo->maDropPos.GetIndex() &&
+ pStartAttr->GetEnd() != mpImpl->mpDDInfo->maDropPos.GetIndex();
+ }
+ // Don't drop in selection or in read only engine
+ if ( IsReadOnly() || IsInSelection( mpImpl->mpDDInfo->maDropPos ) || bProtected)
+ {
+ ImpHideDDCursor();
+ rDTDE.Context->rejectDrag();
+ }
+ else
+ {
+ // Alten Cursor wegzeichnen...
+ if ( !mpImpl->mpDDInfo->mbVisCursor || ( aPrevDropPos != mpImpl->mpDDInfo->maDropPos ) )
+ {
+ ImpHideDDCursor();
+ ImpShowDDCursor();
+ }
+ rDTDE.Context->acceptDrag( rDTDE.DropAction );
+ }
+}
+
+Point TextView::ImpGetOutputStartPos( const Point& rStartDocPos ) const
+{
+ Point aStartPos( -rStartDocPos.X(), -rStartDocPos.Y() );
+ if ( mpImpl->mpTextEngine->IsRightToLeft() )
+ {
+ Size aSz = mpImpl->mpWindow->GetOutputSizePixel();
+ aStartPos.X() = rStartDocPos.X() + aSz.Width() - 1; // -1: Start is 0
+ }
+ return aStartPos;
+}
+
+Point TextView::GetDocPos( const Point& rWindowPos ) const
+{
+ // Fensterposition => Dokumentposition
+
+ Point aPoint;
+
+ aPoint.Y() = rWindowPos.Y() + mpImpl->maStartDocPos.Y();
+
+ if ( !mpImpl->mpTextEngine->IsRightToLeft() )
+ {
+ aPoint.X() = rWindowPos.X() + mpImpl->maStartDocPos.X();
+ }
+ else
+ {
+ Size aSz = mpImpl->mpWindow->GetOutputSizePixel();
+ aPoint.X() = ( aSz.Width() - 1 ) - rWindowPos.X() + mpImpl->maStartDocPos.X();
+ }
+
+ return aPoint;
+}
+
+Point TextView::GetWindowPos( const Point& rDocPos ) const
+{
+ // Dokumentposition => Fensterposition
+
+ Point aPoint;
+
+ aPoint.Y() = rDocPos.Y() - mpImpl->maStartDocPos.Y();
+
+ if ( !mpImpl->mpTextEngine->IsRightToLeft() )
+ {
+ aPoint.X() = rDocPos.X() - mpImpl->maStartDocPos.X();
+ }
+ else
+ {
+ Size aSz = mpImpl->mpWindow->GetOutputSizePixel();
+ aPoint.X() = ( aSz.Width() - 1 ) - ( rDocPos.X() - mpImpl->maStartDocPos.X() );
+ }
+
+ return aPoint;
+}
+
+sal_Int32 TextView::GetLineNumberOfCursorInSelection() const
+{
+ // PROGRESS
+ sal_Int32 nLineNo = -1;
+ if( mpImpl->mbCursorEnabled )
+ {
+ TextPaM aPaM = GetSelection().GetEnd();
+ TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
+ nLineNo = pPPortion->GetLineNumber( aPaM.GetIndex(), FALSE );
+ if( mpImpl->mbCursorAtEndOfLine )
+ --nLineNo;
+ }
+ return nLineNo;
+}
+
+
+// -------------------------------------------------------------------------
+// (+) class TextSelFunctionSet
+// -------------------------------------------------------------------------
+TextSelFunctionSet::TextSelFunctionSet( TextView* pView )
+{
+ mpView = pView;
+}
+
+void __EXPORT TextSelFunctionSet::BeginDrag()
+{
+}
+
+void __EXPORT TextSelFunctionSet::CreateAnchor()
+{
+// TextSelection aSel( mpView->GetSelection() );
+// aSel.GetStart() = aSel.GetEnd();
+// mpView->SetSelection( aSel );
+
+ // Es darf kein ShowCursor folgen:
+ mpView->HideSelection();
+ mpView->ImpSetSelection( mpView->mpImpl->maSelection.GetEnd() );
+}
+
+BOOL __EXPORT TextSelFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOOL )
+{
+ return mpView->SetCursorAtPoint( rPointPixel );
+}
+
+BOOL __EXPORT TextSelFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
+{
+ return mpView->IsSelectionAtPoint( rPointPixel );
+}
+
+void __EXPORT TextSelFunctionSet::DeselectAll()
+{
+ CreateAnchor();
+}
+
+void __EXPORT TextSelFunctionSet::DeselectAtPoint( const Point& )
+{
+ // Nur bei Mehrfachselektion
+}
+
+void __EXPORT TextSelFunctionSet::DestroyAnchor()
+{
+ // Nur bei Mehrfachselektion
+}
+TextEngine* TextView::GetTextEngine() const
+{ return mpImpl->mpTextEngine; }
+Window* TextView::GetWindow() const
+{ return mpImpl->mpWindow; }
+void TextView::EnableCursor( BOOL bEnable )
+{ mpImpl->mbCursorEnabled = bEnable; }
+BOOL TextView::IsCursorEnabled() const
+{ return mpImpl->mbCursorEnabled; }
+void TextView::SetStartDocPos( const Point& rPos )
+{ mpImpl->maStartDocPos = rPos; }
+const Point& TextView::GetStartDocPos() const
+{ return mpImpl->maStartDocPos; }
+void TextView::SetAutoIndentMode( BOOL bAutoIndent )
+{ mpImpl->mbAutoIndent = bAutoIndent; }
+BOOL TextView::IsAutoIndentMode() const
+{ return mpImpl->mbAutoIndent; }
+BOOL TextView::IsReadOnly() const
+{ return mpImpl->mbReadOnly; }
+void TextView::SetAutoScroll( BOOL bAutoScroll )
+{ mpImpl->mbAutoScroll = bAutoScroll; }
+BOOL TextView::IsAutoScroll() const
+{ return mpImpl->mbAutoScroll; }
+BOOL TextView::IsPaintSelection() const
+{ return mpImpl->mbPaintSelection; }
+BOOL TextView::IsHighlightSelection() const
+{ return mpImpl->mbHighlightSelection; }
+BOOL TextView::HasSelection() const
+{ return mpImpl->maSelection.HasRange(); }
+BOOL TextView::IsInsertMode() const
+{ return mpImpl->mbInsertMode; }
+void TextView::SupportProtectAttribute(sal_Bool bSupport)
+{ mpImpl->mbSupportProtectAttribute = bSupport;}
+
diff --git a/svtools/source/edit/textwindowpeer.cxx b/svtools/source/edit/textwindowpeer.cxx
new file mode 100644
index 000000000000..7f31e95c75a7
--- /dev/null
+++ b/svtools/source/edit/textwindowpeer.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/textwindowpeer.hxx>
+#include <svtools/textview.hxx>
+#include "svtaccessiblefactory.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace svt
+{
+ TextWindowPeer::TextWindowPeer(::TextView & rView, bool bCompoundControlChild):
+ m_rEngine(*rView.GetTextEngine()), m_rView(rView), m_bCompoundControlChild(bCompoundControlChild)
+ {
+ SetWindow(rView.GetWindow());
+ m_pFactoryAccess.reset( new AccessibleFactoryAccess );
+ }
+
+ // virtual
+ TextWindowPeer::~TextWindowPeer()
+ {
+ }
+
+ ::css::uno::Reference< ::css::accessibility::XAccessibleContext > TextWindowPeer::CreateAccessibleContext()
+ {
+ return m_pFactoryAccess->getFactory().createAccessibleTextWindowContext(
+ this, m_rEngine, m_rView, m_bCompoundControlChild
+ );
+ }
+}
diff --git a/svtools/source/edit/txtattr.cxx b/svtools/source/edit/txtattr.cxx
new file mode 100644
index 000000000000..e7466cbe1d85
--- /dev/null
+++ b/svtools/source/edit/txtattr.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_svtools.hxx"
+
+#include <txtattr.hxx>
+#include <vcl/font.hxx>
+
+
+
+
+TextAttrib::~TextAttrib()
+{
+}
+
+void TextAttrib::SetFont( Font& ) const
+{
+}
+
+TextAttrib* TextAttrib::Clone() const
+{
+ return NULL;
+}
+
+int TextAttrib::operator==( const TextAttrib& rAttr ) const
+{
+ return mnWhich == rAttr.mnWhich;
+}
+
+
+TextAttribFontColor::TextAttribFontColor( const Color& rColor )
+ : TextAttrib( TEXTATTR_FONTCOLOR ), maColor( rColor )
+{
+}
+
+TextAttribFontColor::TextAttribFontColor( const TextAttribFontColor& rAttr )
+ : TextAttrib( rAttr ), maColor( rAttr.maColor )
+{
+}
+
+TextAttribFontColor::~TextAttribFontColor()
+{
+}
+
+void TextAttribFontColor::SetFont( Font& rFont ) const
+{
+ rFont.SetColor( maColor );
+}
+
+TextAttrib* TextAttribFontColor::Clone() const
+{
+ return new TextAttribFontColor( *this );
+}
+
+int TextAttribFontColor::operator==( const TextAttrib& rAttr ) const
+{
+ return ( ( TextAttrib::operator==(rAttr ) ) &&
+ ( maColor == ((const TextAttribFontColor&)rAttr).maColor ) );
+}
+
+TextAttribFontWeight::TextAttribFontWeight( FontWeight eWeight )
+ : TextAttrib( TEXTATTR_FONTWEIGHT ), meWeight( eWeight )
+{
+}
+
+TextAttribFontWeight::TextAttribFontWeight( const TextAttribFontWeight& rAttr )
+ : TextAttrib( rAttr ), meWeight( rAttr.meWeight )
+{
+}
+
+TextAttribFontWeight::~TextAttribFontWeight()
+{
+}
+
+void TextAttribFontWeight::SetFont( Font& rFont ) const
+{
+ rFont.SetWeight( meWeight );
+}
+
+TextAttrib* TextAttribFontWeight::Clone() const
+{
+ return new TextAttribFontWeight( *this );
+}
+
+int TextAttribFontWeight::operator==( const TextAttrib& rAttr ) const
+{
+ return ( ( TextAttrib::operator==(rAttr ) ) &&
+ ( meWeight == ((const TextAttribFontWeight&)rAttr).meWeight ) );
+}
+
+
+TextAttribHyperLink::TextAttribHyperLink( const XubString& rURL )
+ : TextAttrib( TEXTATTR_HYPERLINK ), maURL( rURL )
+{
+ maColor = COL_BLUE;
+}
+
+TextAttribHyperLink::TextAttribHyperLink( const XubString& rURL, const XubString& rDescription )
+ : TextAttrib( TEXTATTR_HYPERLINK ), maURL( rURL ), maDescription( rDescription )
+{
+ maColor = COL_BLUE;
+}
+
+TextAttribHyperLink::TextAttribHyperLink( const TextAttribHyperLink& rAttr )
+ : TextAttrib( rAttr ), maURL( rAttr.maURL ), maDescription( rAttr.maDescription )
+{
+ maColor = rAttr.maColor;
+}
+
+TextAttribHyperLink::~TextAttribHyperLink()
+{
+}
+
+void TextAttribHyperLink::SetFont( Font& rFont ) const
+{
+ rFont.SetColor( maColor );
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+}
+
+TextAttrib* TextAttribHyperLink::Clone() const
+{
+ return new TextAttribHyperLink( *this );
+}
+
+int TextAttribHyperLink::operator==( const TextAttrib& rAttr ) const
+{
+ return ( ( TextAttrib::operator==(rAttr ) ) &&
+ ( maURL == ((const TextAttribHyperLink&)rAttr).maURL ) &&
+ ( maDescription == ((const TextAttribHyperLink&)rAttr).maDescription ) &&
+ ( maColor == ((const TextAttribHyperLink&)rAttr).maColor ) );
+}
+
+/*-- 24.06.2004 14:49:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+TextAttribProtect::TextAttribProtect() :
+ TextAttrib( TEXTATTR_PROTECTED )
+{
+}
+/*-- 24.06.2004 14:49:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+TextAttribProtect::TextAttribProtect( const TextAttribProtect&) :
+ TextAttrib( TEXTATTR_PROTECTED )
+{
+}
+/*-- 24.06.2004 14:49:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+TextAttribProtect::~TextAttribProtect()
+{
+}
+/*-- 24.06.2004 14:49:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void TextAttribProtect::SetFont( Font& ) const
+{
+}
+/*-- 24.06.2004 14:49:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+TextAttrib* TextAttribProtect::Clone() const
+{
+ return new TextAttribProtect();
+}
+/*-- 24.06.2004 14:49:45---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+int TextAttribProtect::operator==( const TextAttrib& rAttr ) const
+{
+ return ( TextAttrib::operator==(rAttr ) );
+}
diff --git a/svtools/source/edit/xtextedt.cxx b/svtools/source/edit/xtextedt.cxx
new file mode 100644
index 000000000000..0a4907edcadd
--- /dev/null
+++ b/svtools/source/edit/xtextedt.cxx
@@ -0,0 +1,421 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/xtextedt.hxx>
+#include <vcl/svapp.hxx> // International
+#include <unotools/textsearch.hxx>
+#include <com/sun/star/util/SearchOptions.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+
+using namespace ::com::sun::star;
+
+
+
+ // -------------------------------------------------------------------------
+// class ExtTextEngine
+// -------------------------------------------------------------------------
+ExtTextEngine::ExtTextEngine() : maGroupChars( String::CreateFromAscii( "(){}[]", 6 ) )
+{
+}
+
+ExtTextEngine::~ExtTextEngine()
+{
+}
+
+TextSelection ExtTextEngine::MatchGroup( const TextPaM& rCursor ) const
+{
+ TextSelection aSel( rCursor );
+ USHORT nPos = rCursor.GetIndex();
+ ULONG nPara = rCursor.GetPara();
+ ULONG nParas = GetParagraphCount();
+ if ( ( nPara < nParas ) && ( nPos < GetTextLen( nPara ) ) )
+ {
+ USHORT nMatchChar = maGroupChars.Search( GetText( rCursor.GetPara() ).GetChar( nPos ) );
+ if ( nMatchChar != STRING_NOTFOUND )
+ {
+ if ( ( nMatchChar % 2 ) == 0 )
+ {
+ // Vorwaerts suchen...
+ sal_Unicode nSC = maGroupChars.GetChar( nMatchChar );
+ sal_Unicode nEC = maGroupChars.GetChar( nMatchChar+1 );
+
+ USHORT nCur = nPos+1;
+ USHORT nLevel = 1;
+ while ( nLevel && ( nPara < nParas ) )
+ {
+ XubString aStr = GetText( nPara );
+ while ( nCur < aStr.Len() )
+ {
+ if ( aStr.GetChar( nCur ) == nSC )
+ nLevel++;
+ else if ( aStr.GetChar( nCur ) == nEC )
+ {
+ nLevel--;
+ if ( !nLevel )
+ break; // while nCur...
+ }
+ nCur++;
+ }
+
+ if ( nLevel )
+ {
+ nPara++;
+ nCur = 0;
+ }
+ }
+ if ( nLevel == 0 ) // gefunden
+ {
+ aSel.GetStart() = rCursor;
+ aSel.GetEnd() = TextPaM( nPara, nCur+1 );
+ }
+ }
+ else
+ {
+ // Rueckwaerts suchen...
+ xub_Unicode nEC = maGroupChars.GetChar( nMatchChar );
+ xub_Unicode nSC = maGroupChars.GetChar( nMatchChar-1 );
+
+ USHORT nCur = rCursor.GetIndex()-1;
+ USHORT nLevel = 1;
+ while ( nLevel )
+ {
+ if ( GetTextLen( nPara ) )
+ {
+ XubString aStr = GetText( nPara );
+ while ( nCur )
+ {
+ if ( aStr.GetChar( nCur ) == nSC )
+ {
+ nLevel--;
+ if ( !nLevel )
+ break; // while nCur...
+ }
+ else if ( aStr.GetChar( nCur ) == nEC )
+ nLevel++;
+
+ nCur--;
+ }
+ }
+
+ if ( nLevel )
+ {
+ if ( nPara )
+ {
+ nPara--;
+ nCur = GetTextLen( nPara )-1; // egal ob negativ, weil if Len()
+ }
+ else
+ break;
+ }
+ }
+
+ if ( nLevel == 0 ) // gefunden
+ {
+ aSel.GetStart() = rCursor;
+ aSel.GetStart().GetIndex()++; // hinter das Zeichen
+ aSel.GetEnd() = TextPaM( nPara, nCur );
+ }
+ }
+ }
+ }
+ return aSel;
+}
+
+BOOL ExtTextEngine::Search( TextSelection& rSel, const util::SearchOptions& rSearchOptions, BOOL bForward )
+{
+ TextSelection aSel( rSel );
+ aSel.Justify();
+
+ BOOL bSearchInSelection = (0 != (rSearchOptions.searchFlag & util::SearchFlags::REG_NOT_BEGINOFLINE) );
+
+ TextPaM aStartPaM( aSel.GetEnd() );
+ if ( aSel.HasRange() && ( ( bSearchInSelection && bForward ) || ( !bSearchInSelection && !bForward ) ) )
+ {
+ aStartPaM = aSel.GetStart();
+ }
+
+ bool bFound = false;
+ ULONG nStartNode, nEndNode;
+
+ if ( bSearchInSelection )
+ nEndNode = bForward ? aSel.GetEnd().GetPara() : aSel.GetStart().GetPara();
+ else
+ nEndNode = bForward ? (GetParagraphCount()-1) : 0;
+
+ nStartNode = aStartPaM.GetPara();
+
+ util::SearchOptions aOptions( rSearchOptions );
+ aOptions.Locale = Application::GetSettings().GetLocale();
+ utl::TextSearch aSearcher( rSearchOptions );
+
+ // ueber die Absaetze iterieren...
+ for ( ULONG nNode = nStartNode;
+ bForward ? ( nNode <= nEndNode) : ( nNode >= nEndNode );
+ bForward ? nNode++ : nNode-- )
+ {
+ String aText = GetText( nNode );
+ USHORT nStartPos = 0;
+ USHORT nEndPos = aText.Len();
+ if ( nNode == nStartNode )
+ {
+ if ( bForward )
+ nStartPos = aStartPaM.GetIndex();
+ else
+ nEndPos = aStartPaM.GetIndex();
+ }
+ if ( ( nNode == nEndNode ) && bSearchInSelection )
+ {
+ if ( bForward )
+ nEndPos = aSel.GetEnd().GetIndex();
+ else
+ nStartPos = aSel.GetStart().GetIndex();
+ }
+
+ if ( bForward )
+ bFound = aSearcher.SearchFrwrd( aText, &nStartPos, &nEndPos );
+ else
+ bFound = aSearcher.SearchBkwrd( aText, &nEndPos, &nStartPos );
+
+ if ( bFound )
+ {
+ rSel.GetStart().GetPara() = nNode;
+ rSel.GetStart().GetIndex() = nStartPos;
+ rSel.GetEnd().GetPara() = nNode;
+ rSel.GetEnd().GetIndex() = nEndPos;
+ // Ueber den Absatz selektieren?
+ // Select over the paragraph?
+ // FIXME This should be max long...
+ if( nEndPos == sal::static_int_cast<USHORT>(-1) ) // USHORT for 0 and -1 !
+ {
+ if ( (rSel.GetEnd().GetPara()+1) < GetParagraphCount() )
+ {
+ rSel.GetEnd().GetPara()++;
+ rSel.GetEnd().GetIndex() = 0;
+ }
+ else
+ {
+ rSel.GetEnd().GetIndex() = nStartPos;
+ bFound = false;
+ }
+ }
+
+ break;
+ }
+
+ if ( !bForward && !nNode ) // Bei rueckwaertsuche, wenn nEndNode = 0:
+ break;
+ }
+
+ return bFound;
+}
+
+
+ // -------------------------------------------------------------------------
+// class ExtTextView
+// -------------------------------------------------------------------------
+ExtTextView::ExtTextView( ExtTextEngine* pEng, Window* pWindow )
+ : TextView( pEng, pWindow )
+{
+}
+
+ExtTextView::~ExtTextView()
+{
+}
+
+BOOL ExtTextView::MatchGroup()
+{
+ TextSelection aTmpSel( GetSelection() );
+ aTmpSel.Justify();
+ if ( ( aTmpSel.GetStart().GetPara() != aTmpSel.GetEnd().GetPara() ) ||
+ ( ( aTmpSel.GetEnd().GetIndex() - aTmpSel.GetStart().GetIndex() ) > 1 ) )
+ {
+ return FALSE;
+ }
+
+ TextSelection aMatchSel = ((ExtTextEngine*)GetTextEngine())->MatchGroup( aTmpSel.GetStart() );
+ if ( aMatchSel.HasRange() )
+ SetSelection( aMatchSel );
+
+ return aMatchSel.HasRange() ? TRUE : FALSE;
+}
+
+BOOL ExtTextView::Search( const util::SearchOptions& rSearchOptions, BOOL bForward )
+{
+ BOOL bFound = FALSE;
+ TextSelection aSel( GetSelection() );
+ if ( ((ExtTextEngine*)GetTextEngine())->Search( aSel, rSearchOptions, bForward ) )
+ {
+ bFound = TRUE;
+ // Erstmal den Anfang des Wortes als Selektion einstellen,
+ // damit das ganze Wort in den sichtbaren Bereich kommt.
+ SetSelection( aSel.GetStart() );
+ ShowCursor( TRUE, FALSE );
+ }
+ else
+ {
+ aSel = GetSelection().GetEnd();
+ }
+
+ SetSelection( aSel );
+ ShowCursor();
+
+ return bFound;
+}
+
+USHORT ExtTextView::Replace( const util::SearchOptions& rSearchOptions, BOOL bAll, BOOL bForward )
+{
+ USHORT nFound = 0;
+
+ if ( !bAll )
+ {
+ if ( GetSelection().HasRange() )
+ {
+ InsertText( rSearchOptions.replaceString );
+ nFound = 1;
+ Search( rSearchOptions, bForward ); // gleich zum naechsten
+ }
+ else
+ {
+ if( Search( rSearchOptions, bForward ) )
+ nFound = 1;
+ }
+ }
+ else
+ {
+ // Der Writer ersetzt alle, vom Anfang bis Ende...
+
+ ExtTextEngine* pTextEngine = (ExtTextEngine*)GetTextEngine();
+
+ // HideSelection();
+ TextSelection aSel;
+
+ BOOL bSearchInSelection = (0 != (rSearchOptions.searchFlag & util::SearchFlags::REG_NOT_BEGINOFLINE) );
+ if ( bSearchInSelection )
+ {
+ aSel = GetSelection();
+ aSel.Justify();
+ }
+
+ TextSelection aSearchSel( aSel );
+
+ BOOL bFound = pTextEngine->Search( aSel, rSearchOptions, TRUE );
+ if ( bFound )
+ pTextEngine->UndoActionStart( XTEXTUNDO_REPLACEALL );
+ while ( bFound )
+ {
+ nFound++;
+
+ TextPaM aNewStart = pTextEngine->ImpInsertText( aSel, rSearchOptions.replaceString );
+ aSel = aSearchSel;
+ aSel.GetStart() = aNewStart;
+ bFound = pTextEngine->Search( aSel, rSearchOptions, TRUE );
+ }
+ if ( nFound )
+ {
+ SetSelection( aSel.GetStart() );
+ pTextEngine->FormatAndUpdate( this );
+ pTextEngine->UndoActionEnd( XTEXTUNDO_REPLACEALL );
+ }
+ }
+ return nFound;
+}
+
+BOOL ExtTextView::ImpIndentBlock( BOOL bRight )
+{
+ BOOL bDone = FALSE;
+
+ TextSelection aSel = GetSelection();
+ aSel.Justify();
+
+ HideSelection();
+ GetTextEngine()->UndoActionStart( bRight ? XTEXTUNDO_INDENTBLOCK : XTEXTUNDO_UNINDENTBLOCK );
+
+ ULONG nStartPara = aSel.GetStart().GetPara();
+ ULONG nEndPara = aSel.GetEnd().GetPara();
+ if ( aSel.HasRange() && !aSel.GetEnd().GetIndex() )
+ {
+ nEndPara--; // den dann nicht einruecken...
+ }
+
+ for ( ULONG nPara = nStartPara; nPara <= nEndPara; nPara++ )
+ {
+ if ( bRight )
+ {
+ // Tabs hinzufuegen
+ GetTextEngine()->ImpInsertText( TextPaM( nPara, 0 ), '\t' );
+ bDone = TRUE;
+ }
+ else
+ {
+ // Tabs/Blanks entfernen
+ String aText = GetTextEngine()->GetText( nPara );
+ if ( aText.Len() && (
+ ( aText.GetChar( 0 ) == '\t' ) ||
+ ( aText.GetChar( 0 ) == ' ' ) ) )
+ {
+ GetTextEngine()->ImpDeleteText( TextSelection( TextPaM( nPara, 0 ), TextPaM( nPara, 1 ) ) );
+ bDone = TRUE;
+ }
+ }
+ }
+
+ GetTextEngine()->UndoActionEnd( bRight ? XTEXTUNDO_INDENTBLOCK : XTEXTUNDO_UNINDENTBLOCK );
+
+ BOOL bRange = aSel.HasRange();
+ if ( bRight )
+ {
+ aSel.GetStart().GetIndex()++;
+ if ( bRange && ( aSel.GetEnd().GetPara() == nEndPara ) )
+ aSel.GetEnd().GetIndex()++;
+ }
+ else
+ {
+ if ( aSel.GetStart().GetIndex() )
+ aSel.GetStart().GetIndex()--;
+ if ( bRange && aSel.GetEnd().GetIndex() )
+ aSel.GetEnd().GetIndex()--;
+ }
+
+ ImpSetSelection( aSel );
+ GetTextEngine()->FormatAndUpdate( this );
+
+ return bDone;
+}
+
+BOOL ExtTextView::IndentBlock()
+{
+ return ImpIndentBlock( TRUE );
+}
+
+BOOL ExtTextView::UnindentBlock()
+{
+ return ImpIndentBlock( FALSE );
+}
+
diff --git a/svtools/source/filter.vcl/filter/FilterConfigCache.cxx b/svtools/source/filter.vcl/filter/FilterConfigCache.cxx
new file mode 100644
index 000000000000..4c8023bed883
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/FilterConfigCache.cxx
@@ -0,0 +1,596 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "FilterConfigCache.hxx"
+#include <svtools/filter.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <unotools/processfactory.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#define TOKEN_COUNT_FOR_OWN_FILTER 3
+// #define TOKEN_INDEX_FOR_IDENT 0
+#define TOKEN_INDEX_FOR_FILTER 1
+// #define TOKEN_INDEX_FOR_HASDIALOG 2
+
+using namespace ::com::sun::star::lang ; // XMultiServiceFactory
+using namespace ::com::sun::star::container ; // XNameAccess
+using namespace ::com::sun::star::uno ; // Reference
+using namespace ::com::sun::star::beans ; // PropertyValue
+using namespace ::utl ; // getProcessServiceFactory();
+using namespace ::rtl ;
+
+const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList[] =
+{
+ IMP_BMP, IMP_GIF, IMP_PNG,IMP_JPEG, IMP_XBM, IMP_XPM,
+ EXP_BMP, EXP_JPEG, EXP_PNG, NULL
+};
+
+const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList[] =
+{
+ IMP_SVMETAFILE, IMP_WMF, IMP_EMF, IMP_SVSGF, IMP_SVSGV,
+ EXP_SVMETAFILE, EXP_WMF, EXP_EMF, EXP_SVG, NULL
+};
+
+const char* FilterConfigCache::FilterConfigCacheEntry::ExternalPixelFilterNameList[] =
+{
+ "egi", "icd", "ipd", "ipx", "ipb", "epb", "epg",
+ "epp", "ira", "era", "itg", "iti", "eti", "exp", NULL
+};
+
+sal_Bool FilterConfigCache::FilterConfigCacheEntry::IsValid()
+{
+ return sFilterName.Len() != 0;
+}
+
+sal_Bool FilterConfigCache::bInitialized = sal_False;
+sal_Int32 FilterConfigCache::nIndType = -1;
+sal_Int32 FilterConfigCache::nIndUIName = -1;
+sal_Int32 FilterConfigCache::nIndDocumentService = -1;
+sal_Int32 FilterConfigCache::nIndFilterService = -1;
+sal_Int32 FilterConfigCache::nIndFlags = -1;
+sal_Int32 FilterConfigCache::nIndUserData = -1;
+sal_Int32 FilterConfigCache::nIndFileFormatVersion = -1;
+sal_Int32 FilterConfigCache::nIndTemplateName = -1;
+
+sal_Bool FilterConfigCache::FilterConfigCacheEntry::CreateFilterName( const OUString& rUserDataEntry )
+{
+ bIsPixelFormat = bIsInternalFilter = sal_False;
+ sFilterName = String( rUserDataEntry );
+ const char** pPtr;
+ for ( pPtr = InternalPixelFilterNameList; *pPtr && ( bIsInternalFilter == sal_False ); pPtr++ )
+ {
+ if ( sFilterName.EqualsIgnoreCaseAscii( *pPtr ) )
+ {
+ bIsInternalFilter = sal_True;
+ bIsPixelFormat = sal_True;
+ }
+ }
+ for ( pPtr = InternalVectorFilterNameList; *pPtr && ( bIsInternalFilter == sal_False ); pPtr++ )
+ {
+ if ( sFilterName.EqualsIgnoreCaseAscii( *pPtr ) )
+ bIsInternalFilter = sal_True;
+ }
+ if ( !bIsInternalFilter )
+ {
+ for ( pPtr = ExternalPixelFilterNameList; *pPtr && ( bIsPixelFormat == sal_False ); pPtr++ )
+ {
+ if ( sFilterName.EqualsIgnoreCaseAscii( *pPtr ) )
+ bIsPixelFormat = sal_True;
+ }
+ String aTemp( OUString::createFromAscii( SVLIBRARY( "?" ) ) );
+ xub_StrLen nIndex = aTemp.Search( (sal_Unicode)'?' );
+ aTemp.Replace( nIndex, 1, sFilterName );
+ sFilterName = aTemp;
+ }
+ return sFilterName.Len() != 0;
+}
+
+String FilterConfigCache::FilterConfigCacheEntry::GetShortName()
+{
+ String aShortName;
+ if ( lExtensionList.getLength() )
+ {
+ aShortName = lExtensionList[ 0 ];
+ if ( aShortName.SearchAscii( "*.", 0 ) == 0 )
+ aShortName.Erase( 0, 2 );
+ }
+ return aShortName;
+}
+
+/** helper to open the configuration root of the underlying
+ config package
+
+ @param sPackage
+ specify, which config package should be opened.
+ Must be one of the defined static values TYPEPKG or FILTERPKG.
+
+ @return A valid object if open was successfull. The access on opened
+ data will be readonly. It returns NULL in case open failed.
+
+ @throws It let pass RuntimeExceptions only.
+ */
+Reference< XInterface > openConfig(const char* sPackage)
+ throw(RuntimeException)
+{
+ static OUString TYPEPKG( RTL_CONSTASCII_USTRINGPARAM( "types" ) );
+ static OUString FILTERPKG( RTL_CONSTASCII_USTRINGPARAM( "filters" ) );
+
+ Reference< XMultiServiceFactory > xSMGR = getProcessServiceFactory();
+ Reference< XInterface > xCfg;
+ try
+ {
+ // get access to config API (not to file!)
+ Reference< XMultiServiceFactory > xConfigProvider( xSMGR->createInstance(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), UNO_QUERY);
+
+ if (xConfigProvider.is())
+ {
+ Sequence< Any > lParams(1);
+ PropertyValue aParam ;
+
+ // define cfg path for open
+ aParam.Name = OUString::createFromAscii("nodepath");
+ if (TYPEPKG.equalsIgnoreAsciiCaseAscii(sPackage))
+ aParam.Value <<= OUString::createFromAscii("/org.openoffice.TypeDetection.Types/Types");
+ if (FILTERPKG.equalsIgnoreAsciiCaseAscii(sPackage))
+ aParam.Value <<= OUString::createFromAscii("/org.openoffice.TypeDetection.GraphicFilter/Filters");
+ lParams[0] = makeAny(aParam);
+
+ // get access to file
+ xCfg = xConfigProvider->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), lParams);
+ }
+ }
+ catch(const RuntimeException&)
+ { throw; }
+ catch(const Exception&)
+ { xCfg.clear(); }
+
+ return xCfg;
+}
+
+void FilterConfigCache::ImplInit()
+{
+ static OUString STYPE ( RTL_CONSTASCII_USTRINGPARAM( "Type" ) );
+ static OUString SUINAME ( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) );
+ static OUString SDOCUMENTSERVICE ( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ) );
+ static OUString SFILTERSERVICE ( RTL_CONSTASCII_USTRINGPARAM( "FilterService" ) );
+ static OUString STEMPLATENAME ( RTL_CONSTASCII_USTRINGPARAM( "TemplateName" ) );
+ static OUString SFILEFORMATVERSION ( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" ) );
+ static OUString SUICOMPONENT ( RTL_CONSTASCII_USTRINGPARAM( "UIComponent" ) );
+ static OUString SFLAGS ( RTL_CONSTASCII_USTRINGPARAM( "Flags" ) );
+ static OUString SUSERDATA ( RTL_CONSTASCII_USTRINGPARAM( "UserData" ) );
+ static OUString SMEDIATYPE ( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ static OUString SEXTENSIONS ( RTL_CONSTASCII_USTRINGPARAM( "Extensions" ) );
+ static OUString SFORMATNAME ( RTL_CONSTASCII_USTRINGPARAM( "FormatName" ) );
+ static OUString SREALFILTERNAME ( RTL_CONSTASCII_USTRINGPARAM( "RealFilterName" ) );
+
+ // get access to config
+ Reference< XNameAccess > xTypeAccess ( openConfig("types" ), UNO_QUERY );
+ Reference< XNameAccess > xFilterAccess( openConfig("filters"), UNO_QUERY );
+
+ if ( xTypeAccess.is() && xFilterAccess.is() )
+ {
+ Sequence< OUString > lAllFilter = xFilterAccess->getElementNames();
+ sal_Int32 nAllFilterCount = lAllFilter.getLength();
+
+ for ( sal_Int32 i = 0; i < nAllFilterCount; i++ )
+ {
+ OUString sInternalFilterName = lAllFilter[ i ];
+ Reference< XPropertySet > xFilterSet;
+ xFilterAccess->getByName( sInternalFilterName ) >>= xFilterSet;
+ if (!xFilterSet.is())
+ continue;
+
+ FilterConfigCacheEntry aEntry;
+
+ aEntry.sInternalFilterName = sInternalFilterName;
+ xFilterSet->getPropertyValue(STYPE) >>= aEntry.sType;
+ xFilterSet->getPropertyValue(SUINAME) >>= aEntry.sUIName;
+ xFilterSet->getPropertyValue(SREALFILTERNAME) >>= aEntry.sFilterType;
+ Sequence< OUString > lFlags;
+ xFilterSet->getPropertyValue(SFLAGS) >>= lFlags;
+ if (lFlags.getLength()!=1 || !lFlags[0].getLength())
+ continue;
+ if (lFlags[0].equalsIgnoreAsciiCaseAscii("import"))
+ aEntry.nFlags = 1;
+ else
+ if (lFlags[0].equalsIgnoreAsciiCaseAscii("export"))
+ aEntry.nFlags = 2;
+
+ OUString sUIComponent;
+ xFilterSet->getPropertyValue(SUICOMPONENT) >>= sUIComponent;
+ aEntry.bHasDialog = sUIComponent.getLength();
+
+ ::rtl::OUString sFormatName;
+ xFilterSet->getPropertyValue(SFORMATNAME) >>= sFormatName;
+ aEntry.CreateFilterName( sFormatName );
+
+ Reference< XPropertySet > xTypeSet;
+ xTypeAccess->getByName( aEntry.sType ) >>= xTypeSet;
+ if (!xTypeSet.is())
+ continue;
+
+ xTypeSet->getPropertyValue(SMEDIATYPE) >>= aEntry.sMediaType;
+ xTypeSet->getPropertyValue(SEXTENSIONS) >>= aEntry.lExtensionList;
+
+ // The first extension will be used
+ // to generate our internal FilterType ( BMP, WMF ... )
+ String aExtension( aEntry.GetShortName() );
+ if (aExtension.Len() != 3)
+ continue;
+
+ if ( aEntry.nFlags & 1 )
+ aImport.push_back( aEntry );
+ if ( aEntry.nFlags & 2 )
+ aExport.push_back( aEntry );
+
+ // bFilterEntryCreated!?
+ if (!( aEntry.nFlags & 3 ))
+ continue; //? Entry was already inserted ... but following code will be supressed?!
+ }
+ }
+};
+
+const char* FilterConfigCache::InternalFilterListForSvxLight[] =
+{
+ "bmp","1","SVBMP",
+ "bmp","2","SVBMP",
+ "dxf","1","idx",
+ "eps","1","ips",
+ "eps","2","eps",
+ "gif","1","SVIGIF",
+ "gif","2","egi",
+ "jpg","1","SVIJPEG",
+ "jpg","2","SVEJPEG",
+ "sgv","1","SVSGV",
+ "sgf","1","SVSGF",
+ "met","1","ime",
+ "met","2","eme",
+ "png","1","SVIPNG",
+ "png","2","SVEPNG",
+ "pct","1","ipt",
+ "pct","2","ept",
+ "pcd","1","icd",
+ "psd","1","ipd",
+ "pcx","1","ipx",
+ "pbm","1","ipb",
+ "pbm","2","epb",
+ "pgm","1","ipb",
+ "pgm","2","epg",
+ "ppm","1","ipb",
+ "ppm","2","epp",
+ "ras","1","ira",
+ "ras","2","era",
+ "svm","1","SVMETAFILE",
+ "svm","2","SVMETAFILE",
+ "tga","1","itg",
+ "tif","1","iti",
+ "tif","2","eti",
+ "emf","1","SVEMF",
+ "emf","2","SVEMF",
+ "wmf","1","SVWMF",
+ "wmf","2","SVWMF",
+ "xbm","1","SVIXBM",
+ "xpm","1","SVIXPM",
+ "xpm","2","exp",
+ "svg","2","SVESVG",
+ NULL
+};
+
+void FilterConfigCache::ImplInitSmart()
+{
+ const char** pPtr;
+ for ( pPtr = InternalFilterListForSvxLight; *pPtr; pPtr++ )
+ {
+ FilterConfigCacheEntry aEntry;
+
+ OUString sExtension( OUString::createFromAscii( *pPtr++ ) );
+
+ aEntry.lExtensionList.realloc( 1 );
+ aEntry.lExtensionList[ 0 ] = sExtension;
+
+ aEntry.sType = sExtension;
+ aEntry.sUIName = sExtension;
+
+ ByteString sFlags( *pPtr++ );
+ aEntry.nFlags = sFlags.ToInt32();
+
+ OUString sUserData( OUString::createFromAscii( *pPtr ) );
+ aEntry.CreateFilterName( sUserData );
+
+ if ( aEntry.nFlags & 1 )
+ aImport.push_back( aEntry );
+ if ( aEntry.nFlags & 2 )
+ aExport.push_back( aEntry );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+FilterConfigCache::FilterConfigCache( sal_Bool bConfig ) :
+ bUseConfig ( bConfig )
+{
+ if ( bUseConfig )
+ ImplInit();
+ else
+ ImplInitSmart();
+}
+
+FilterConfigCache::~FilterConfigCache()
+{
+
+}
+
+String FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sFilterName;
+ return String::EmptyString();
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumber( const String& rFormatName )
+{
+ CacheVector::iterator aIter( aImport.begin() );
+ while ( aIter != aImport.end() )
+ {
+ if ( aIter->sUIName.equalsIgnoreAsciiCase( rFormatName ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin());
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumberForMediaType( const String& rMediaType )
+{
+ CacheVector::iterator aIter( aImport.begin() );
+ while ( aIter != aImport.end() )
+ {
+ if ( aIter->sMediaType.equalsIgnoreAsciiCase( rMediaType ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin());
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumberForShortName( const String& rShortName )
+{
+ CacheVector::iterator aIter( aImport.begin() );
+ while ( aIter != aImport.end() )
+ {
+ if ( aIter->GetShortName().EqualsIgnoreCaseAscii( rShortName ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin());
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumberForTypeName( const String& rType )
+{
+ CacheVector::iterator aIter( aImport.begin() );
+ while ( aIter != aImport.end() )
+ {
+ if ( aIter->sType.equalsIgnoreAsciiCase( rType ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin());
+}
+
+String FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sUIName;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sMediaType;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].GetShortName();
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ if ( (nFormat < aImport.size()) && (nEntry < aImport[ nFormat ].lExtensionList.getLength()) )
+ return aImport[ nFormat ].lExtensionList[ nEntry ];
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sType;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sFilterType;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ String aWildcard( GetImportFormatExtension( nFormat, nEntry ) );
+ if ( aWildcard.Len() )
+ aWildcard.Insert( UniString::CreateFromAscii( "*.", 2 ), 0 );
+ return aWildcard;
+}
+
+sal_Bool FilterConfigCache::IsImportInternalFilter( sal_uInt16 nFormat )
+{
+ return (nFormat < aImport.size()) && aImport[ nFormat ].bIsInternalFilter;
+}
+
+sal_Bool FilterConfigCache::IsImportPixelFormat( sal_uInt16 nFormat )
+{
+ return (nFormat < aImport.size()) && aImport[ nFormat ].bIsPixelFormat;
+}
+
+sal_Bool FilterConfigCache::IsImportDialog( sal_uInt16 nFormat )
+{
+ return (nFormat < aImport.size()) && aImport[ nFormat ].bHasDialog;
+}
+
+// ------------------------------------------------------------------------
+
+String FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sFilterName;
+ return String::EmptyString();
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumber( const String& rFormatName )
+{
+ CacheVector::iterator aIter( aExport.begin() );
+ while ( aIter != aExport.end() )
+ {
+ if ( aIter->sUIName.equalsIgnoreAsciiCase( rFormatName ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin());
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumberForMediaType( const String& rMediaType )
+{
+ CacheVector::iterator aIter( aExport.begin() );
+ while ( aIter != aExport.end() )
+ {
+ if ( aIter->sMediaType.equalsIgnoreAsciiCase( rMediaType ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin());
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumberForShortName( const String& rShortName )
+{
+ CacheVector::iterator aIter( aExport.begin() );
+ while ( aIter != aExport.end() )
+ {
+ if ( aIter->GetShortName().EqualsIgnoreCaseAscii( rShortName ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin());
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumberForTypeName( const String& rType )
+{
+ CacheVector::iterator aIter( aExport.begin() );
+ while ( aIter != aExport.end() )
+ {
+ if ( aIter->sType.equalsIgnoreAsciiCase( rType ) )
+ break;
+ aIter++;
+ }
+ return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin());
+}
+
+String FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sUIName;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sMediaType;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].GetShortName();
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ if ( (nFormat < aExport.size()) && (nEntry < aExport[ nFormat ].lExtensionList.getLength()) )
+ return aExport[ nFormat ].lExtensionList[ nEntry ];
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetExportFilterTypeName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sFilterType;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetExportInternalFilterName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sInternalFilterName;
+ return String::EmptyString();
+}
+
+String FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ String aWildcard( GetExportFormatExtension( nFormat, nEntry ) );
+ if ( aWildcard.Len() )
+ aWildcard.Insert( UniString::CreateFromAscii( "*.", 2 ), 0 );
+ return aWildcard;
+}
+
+sal_Bool FilterConfigCache::IsExportInternalFilter( sal_uInt16 nFormat )
+{
+ return (nFormat < aExport.size()) && aExport[ nFormat ].bIsInternalFilter;
+}
+
+sal_Bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat )
+{
+ return (nFormat < aExport.size()) && aExport[ nFormat ].bIsPixelFormat;
+}
+
+sal_Bool FilterConfigCache::IsExportDialog( sal_uInt16 nFormat )
+{
+ return (nFormat < aExport.size()) && aExport[ nFormat ].bHasDialog;
+}
+
+// ------------------------------------------------------------------------
diff --git a/svtools/source/filter.vcl/filter/FilterConfigCache.hxx b/svtools/source/filter.vcl/filter/FilterConfigCache.hxx
new file mode 100644
index 000000000000..2c6b7361e540
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/FilterConfigCache.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 _FILTER_CONFIG_CACHE_HXX_
+#define _FILTER_CONFIG_CACHE_HXX_
+
+#include "svtools/svtdllapi.h"
+#include <tools/string.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+class SVT_DLLPUBLIC FilterConfigCache
+{
+ struct FilterConfigCacheEntry
+ {
+ ::rtl::OUString sInternalFilterName;
+ ::rtl::OUString sType;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > lExtensionList;
+ ::rtl::OUString sUIName;
+ ::rtl::OUString sDocumentService;
+ ::rtl::OUString sFilterService;
+ ::rtl::OUString sTemplateName;
+
+ ::rtl::OUString sMediaType;
+ ::rtl::OUString sFilterType;
+
+ sal_Int32 nFlags;
+ sal_Int32 nFileFormatVersion;
+
+ // user data
+ String sFilterName;
+ sal_Bool bHasDialog : 1;
+ sal_Bool bIsInternalFilter : 1;
+ sal_Bool bIsPixelFormat : 1;
+
+ sal_Bool IsValid();
+ sal_Bool CreateFilterName( const ::rtl::OUString& rUserDataEntry );
+ String GetShortName( );
+
+ static const char* InternalPixelFilterNameList[];
+ static const char* InternalVectorFilterNameList[];
+ static const char* ExternalPixelFilterNameList[];
+ };
+
+ typedef std::vector< FilterConfigCacheEntry > CacheVector;
+
+
+ CacheVector aImport;
+ CacheVector aExport;
+ sal_Bool bUseConfig;
+
+ static sal_Bool bInitialized;
+ static sal_Int32 nIndType;
+ static sal_Int32 nIndUIName;
+ static sal_Int32 nIndDocumentService;
+ static sal_Int32 nIndFilterService;
+ static sal_Int32 nIndFlags;
+ static sal_Int32 nIndUserData;
+ static sal_Int32 nIndFileFormatVersion;
+ static sal_Int32 nIndTemplateName;
+
+ static const char* InternalFilterListForSvxLight[];
+
+ SVT_DLLPRIVATE void ImplInit();
+ SVT_DLLPRIVATE void ImplInitSmart();
+
+ public :
+
+ sal_uInt16 GetImportFormatCount() const
+ { return sal::static_int_cast< sal_uInt16 >(aImport.size()); };
+ sal_uInt16 GetImportFormatNumber( const String& rFormatName );
+ sal_uInt16 GetImportFormatNumberForMediaType( const String& rMediaType );
+ sal_uInt16 GetImportFormatNumberForShortName( const String& rShortName );
+ sal_uInt16 GetImportFormatNumberForTypeName( const String& rType );
+ String GetImportFilterName( sal_uInt16 nFormat );
+ String GetImportFormatName( sal_uInt16 nFormat );
+ String GetImportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry = 0);
+ String GetImportFormatMediaType( sal_uInt16 nFormat );
+ String GetImportFormatShortName( sal_uInt16 nFormat );
+ String GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry );
+ String GetImportFilterType( sal_uInt16 nFormat );
+ String GetImportFilterTypeName( sal_uInt16 nFormat );
+
+ sal_Bool IsImportInternalFilter( sal_uInt16 nFormat );
+ sal_Bool IsImportPixelFormat( sal_uInt16 nFormat );
+ sal_Bool IsImportDialog( sal_uInt16 nFormat );
+
+ sal_uInt16 GetExportFormatCount() const
+ { return sal::static_int_cast< sal_uInt16 >(aExport.size()); };
+ sal_uInt16 GetExportFormatNumber( const String& rFormatName );
+ sal_uInt16 GetExportFormatNumberForMediaType( const String& rMediaType );
+ sal_uInt16 GetExportFormatNumberForShortName( const String& rShortName );
+ sal_uInt16 GetExportFormatNumberForTypeName( const String& rType );
+ String GetExportFilterName( sal_uInt16 nFormat );
+ String GetExportFormatName( sal_uInt16 nFormat );
+ String GetExportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry = 0 );
+ String GetExportFormatMediaType( sal_uInt16 nFormat );
+ String GetExportFormatShortName( sal_uInt16 nFormat );
+ String GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry );
+ String GetExportFilterTypeName( sal_uInt16 nFormat );
+ String GetExportInternalFilterName( sal_uInt16 nFormat );
+
+ sal_Bool IsExportInternalFilter( sal_uInt16 nFormat );
+ sal_Bool IsExportPixelFormat( sal_uInt16 nFormat );
+ sal_Bool IsExportDialog( sal_uInt16 nFormat );
+
+ FilterConfigCache( sal_Bool bUseConfig );
+ ~FilterConfigCache();
+
+};
+
+#endif // _FILTER_CONFIG_CACHE_HXX_
+
diff --git a/svtools/source/filter.vcl/filter/FilterConfigItem.cxx b/svtools/source/filter.vcl/filter/FilterConfigItem.cxx
new file mode 100644
index 000000000000..765711ad8d4a
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/FilterConfigItem.cxx
@@ -0,0 +1,623 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/FilterConfigItem.hxx>
+
+#include <tools/debug.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/processfactory.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+using namespace ::rtl;
+using namespace ::utl ; // getProcessServiceFactory
+using namespace ::com::sun::star::lang ; // XMultiServiceFactory
+using namespace ::com::sun::star::beans ; // PropertyValue
+using namespace ::com::sun::star::uno ; // Reference
+using namespace ::com::sun::star::util ; // XChangesBatch
+using namespace ::com::sun::star::awt ; // Size
+using namespace ::com::sun::star::container ; //
+using namespace ::com::sun::star::task ; // XStatusIndicator
+
+static sal_Bool ImpIsTreeAvailable( Reference< XMultiServiceFactory >& rXCfgProv, const String& rTree )
+{
+ sal_Bool bAvailable = rTree.Len() != 0;
+ if ( bAvailable )
+ {
+ xub_StrLen nTokenCount = rTree.GetTokenCount( (sal_Unicode)'/' );
+ xub_StrLen i = 0;
+
+ if ( rTree.GetChar( 0 ) == (sal_Unicode)'/' )
+ i++;
+ if ( rTree.GetChar( rTree.Len() - 1 ) == (sal_Unicode)'/' )
+ nTokenCount--;
+
+ Any aAny;
+ aAny <<= (OUString)rTree.GetToken( i++, (sal_Unicode)'/' );
+
+ // creation arguments: nodepath
+ PropertyValue aPathArgument;
+ aPathArgument.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aPathArgument.Value = aAny;
+
+ Sequence< Any > aArguments( 1 );
+ aArguments[ 0 ] <<= aPathArgument;
+
+ Reference< XInterface > xReadAccess;
+ try
+ {
+ xReadAccess = rXCfgProv->createInstanceWithArguments(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
+ aArguments );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ bAvailable = sal_False;
+ }
+ if ( xReadAccess.is() )
+ {
+ for ( ; bAvailable && ( i < nTokenCount ); i++ )
+ {
+ Reference< XHierarchicalNameAccess > xHierarchicalNameAccess
+ ( xReadAccess, UNO_QUERY );
+
+ if ( !xHierarchicalNameAccess.is() )
+ bAvailable = sal_False;
+ else
+ {
+ String aNode( rTree.GetToken( i, (sal_Unicode)'/' ) );
+ if ( !xHierarchicalNameAccess->hasByHierarchicalName( aNode ) )
+ bAvailable = sal_False;
+ else
+ {
+ Any a( xHierarchicalNameAccess->getByHierarchicalName( aNode ) );
+ try
+ {
+ a >>= xReadAccess;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ bAvailable = sal_False;
+ }
+ }
+ }
+ }
+ }
+ }
+ return bAvailable;
+}
+
+void FilterConfigItem::ImpInitTree( const String& rSubTree )
+{
+ bModified = sal_False;
+
+ OUString sTree( ConfigManager::GetConfigBaseURL() );
+ sTree += rSubTree;
+ Reference< XMultiServiceFactory > xSMGR = getProcessServiceFactory(); // get global uno service manager
+
+ Reference< XMultiServiceFactory > xCfgProv(
+ xSMGR->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ) ),
+ UNO_QUERY );
+
+ if ( xCfgProv.is() )
+ {
+ if ( ImpIsTreeAvailable( xCfgProv, String( sTree ) ) )
+ {
+ Any aAny;
+ // creation arguments: nodepath
+ PropertyValue aPathArgument;
+ aAny <<= sTree;
+ aPathArgument.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aPathArgument.Value = aAny;
+
+ // creation arguments: commit mode
+ PropertyValue aModeArgument;
+ sal_Bool bAsyncron = sal_True;
+ aAny <<= bAsyncron;
+ aModeArgument.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "lazywrite" ) );
+ aModeArgument.Value = aAny;
+
+ Sequence< Any > aArguments( 2 );
+ aArguments[ 0 ] <<= aPathArgument;
+ aArguments[ 1 ] <<= aModeArgument;
+
+ try
+ {
+ xUpdatableView = xCfgProv->createInstanceWithArguments(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ),
+ aArguments );
+ if ( xUpdatableView.is() )
+ xPropSet = Reference< XPropertySet >( xUpdatableView, UNO_QUERY );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::FilterConfigItem - Could not access configuration Key" );
+ }
+ }
+ }
+}
+
+FilterConfigItem::FilterConfigItem( const OUString& rSubTree )
+{
+ ImpInitTree( rSubTree );
+}
+
+FilterConfigItem::FilterConfigItem( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData )
+{
+ if ( pFilterData )
+ aFilterData = *pFilterData;
+}
+
+FilterConfigItem::FilterConfigItem( const OUString& rSubTree,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData )
+{
+ ImpInitTree( rSubTree );
+
+ if ( pFilterData )
+ aFilterData = *pFilterData;
+};
+
+FilterConfigItem::~FilterConfigItem()
+{
+ if ( xUpdatableView.is() )
+ {
+ if ( xPropSet.is() && bModified )
+ {
+ Reference< XChangesBatch > xUpdateControl( xUpdatableView, UNO_QUERY );
+ if ( xUpdateControl.is() )
+ {
+ try
+ {
+ xUpdateControl->commitChanges();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::FilterConfigItem - Could not update configuration data" );
+ }
+ }
+ }
+ }
+}
+
+sal_Bool FilterConfigItem::ImplGetPropertyValue( Any& rAny, const Reference< XPropertySet >& rXPropSet, const OUString& rString, sal_Bool bTestPropertyAvailability )
+{
+ sal_Bool bRetValue = sal_True;
+
+ if ( rXPropSet.is() )
+ {
+ if ( bTestPropertyAvailability )
+ {
+ bRetValue = sal_False;
+ try
+ {
+ Reference< XPropertySetInfo >
+ aXPropSetInfo( rXPropSet->getPropertySetInfo() );
+ if ( aXPropSetInfo.is() )
+ bRetValue = aXPropSetInfo->hasPropertyByName( rString );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ //
+ }
+ }
+ if ( bRetValue )
+ {
+ try
+ {
+ rAny = rXPropSet->getPropertyValue( rString );
+ if ( !rAny.hasValue() )
+ bRetValue = sal_False;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ bRetValue = sal_False;
+ }
+ }
+ }
+ else
+ bRetValue = sal_False;
+ return bRetValue;
+}
+
+
+// if property is available it returns a pointer,
+// otherwise the result is null
+PropertyValue* FilterConfigItem::GetPropertyValue( Sequence< PropertyValue >& rPropSeq, const OUString& rName )
+{
+ PropertyValue* pPropValue = NULL;
+
+ sal_Int32 i, nCount;
+ for ( i = 0, nCount = rPropSeq.getLength(); i < nCount; i++ )
+ {
+ if ( rPropSeq[ i ].Name == rName )
+ {
+ pPropValue = &rPropSeq[ i ];
+ break;
+ }
+ }
+ return pPropValue;
+}
+
+/* if PropertySequence already includes a PropertyValue using the same name, the
+ corresponding PropertyValue is replaced, otherwise the given PropertyValue
+ will be appended */
+
+sal_Bool FilterConfigItem::WritePropertyValue( Sequence< PropertyValue >& rPropSeq, const PropertyValue& rPropValue )
+{
+ sal_Bool bRet = sal_False;
+ if ( rPropValue.Name.getLength() )
+ {
+ sal_Int32 i, nCount;
+ for ( i = 0, nCount = rPropSeq.getLength(); i < nCount; i++ )
+ {
+ if ( rPropSeq[ i ].Name == rPropValue.Name )
+ break;
+ }
+ if ( i == nCount )
+ rPropSeq.realloc( ++nCount );
+
+ rPropSeq[ i ] = rPropValue;
+
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+sal_Bool FilterConfigItem::ReadBool( const OUString& rKey, sal_Bool bDefault )
+{
+ Any aAny;
+ sal_Bool bRetValue = bDefault;
+ PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
+ if ( pPropVal )
+ {
+ pPropVal->Value >>= bRetValue;
+ }
+ else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ aAny >>= bRetValue;
+ }
+ PropertyValue aBool;
+ aBool.Name = rKey;
+ aBool.Value <<= bRetValue;
+ WritePropertyValue( aFilterData, aBool );
+ return bRetValue;
+}
+
+sal_Int32 FilterConfigItem::ReadInt32( const OUString& rKey, sal_Int32 nDefault )
+{
+ Any aAny;
+ sal_Int32 nRetValue = nDefault;
+ PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
+ if ( pPropVal )
+ {
+ pPropVal->Value >>= nRetValue;
+ }
+ else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ aAny >>= nRetValue;
+ }
+ PropertyValue aInt32;
+ aInt32.Name = rKey;
+ aInt32.Value <<= nRetValue;
+ WritePropertyValue( aFilterData, aInt32 );
+ return nRetValue;
+}
+
+
+Size FilterConfigItem::ReadSize( const OUString& rKey, const Size& rDefault )
+{
+ Any aAny;
+ Size aRetValue( rDefault );
+
+ const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) );
+ const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) );
+
+ Reference< XPropertySet > aXPropSet;
+ try
+ {
+ PropertyValue* pPropWidth = GetPropertyValue( aFilterData, sWidth );
+ PropertyValue* pPropHeight= GetPropertyValue( aFilterData, sHeight );
+ if ( pPropWidth && pPropHeight )
+ {
+ pPropWidth->Value >>= aRetValue.Width;
+ pPropHeight->Value >>= aRetValue.Height;
+ }
+ else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ if ( aAny >>= aXPropSet )
+ {
+ if ( ImplGetPropertyValue( aAny, aXPropSet, sWidth, sal_True ) )
+ aAny >>= aRetValue.Width;
+ if ( ImplGetPropertyValue( aAny, aXPropSet, sHeight, sal_True ) )
+ aAny >>= aRetValue.Height;
+ }
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::ReadSize - could not read PropertyValue" );
+ }
+ PropertyValue aWidth;
+ aWidth.Name = sWidth;
+ aWidth.Value <<= aRetValue.Width;
+ WritePropertyValue( aFilterData, aWidth );
+ PropertyValue aHeight;
+ aHeight.Name = sHeight;
+ aHeight.Value <<= aRetValue.Height;
+ WritePropertyValue( aFilterData, aHeight );
+ return aRetValue;
+}
+
+OUString FilterConfigItem::ReadString( const OUString& rKey, const OUString& rDefault )
+{
+ Any aAny;
+ OUString aRetValue( rDefault );
+ PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
+ if ( pPropVal )
+ {
+ pPropVal->Value >>= aRetValue;
+ }
+ else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ aAny >>= aRetValue;
+ }
+ PropertyValue aString;
+ aString.Name = rKey;
+ aString.Value <<= aRetValue;
+ WritePropertyValue( aFilterData, aString );
+ return aRetValue;
+}
+
+Any FilterConfigItem::ReadAny( const ::rtl::OUString& rKey, const Any& rDefault )
+{
+ Any aAny, aRetValue( rDefault );
+ PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
+ if ( pPropVal )
+ {
+ aRetValue = pPropVal->Value;
+ }
+ else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ aRetValue = aAny;
+ }
+ PropertyValue aPropValue;
+ aPropValue.Name = rKey;
+ aPropValue.Value = aRetValue;
+ WritePropertyValue( aFilterData, aPropValue );
+ return aRetValue;
+}
+
+void FilterConfigItem::WriteBool( const OUString& rKey, sal_Bool bNewValue )
+{
+ PropertyValue aBool;
+ aBool.Name = rKey;
+ aBool.Value <<= bNewValue;
+ WritePropertyValue( aFilterData, aBool );
+
+ if ( xPropSet.is() )
+ {
+ Any aAny;
+ if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ sal_Bool bOldValue;
+ if ( aAny >>= bOldValue )
+ {
+ if ( bOldValue != bNewValue )
+ {
+ aAny <<= bNewValue;
+ try
+ {
+ xPropSet->setPropertyValue( rKey, aAny );
+ bModified = sal_True;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::WriteBool - could not set PropertyValue" );
+ }
+ }
+ }
+ }
+ }
+}
+
+void FilterConfigItem::WriteInt32( const OUString& rKey, sal_Int32 nNewValue )
+{
+ PropertyValue aInt32;
+ aInt32.Name = rKey;
+ aInt32.Value <<= nNewValue;
+ WritePropertyValue( aFilterData, aInt32 );
+
+ if ( xPropSet.is() )
+ {
+ Any aAny;
+
+ if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ sal_Int32 nOldValue;
+ if ( aAny >>= nOldValue )
+ {
+ if ( nOldValue != nNewValue )
+ {
+ aAny <<= nNewValue;
+ try
+ {
+ xPropSet->setPropertyValue( rKey, aAny );
+ bModified = sal_True;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::WriteInt32 - could not set PropertyValue" );
+ }
+ }
+ }
+ }
+ }
+}
+
+void FilterConfigItem::WriteSize( const OUString& rKey, const Size& rNewValue )
+{
+ const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) );
+ const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) );
+
+ PropertyValue aWidth;
+ aWidth.Name = sWidth;
+ aWidth.Value <<= rNewValue.Width;
+ WritePropertyValue( aFilterData, aWidth );
+
+ PropertyValue aHeight;
+ aHeight.Name = sHeight;
+ aHeight.Value <<= rNewValue.Height;
+ WritePropertyValue( aFilterData, aHeight );
+
+ if ( xPropSet.is() )
+ {
+ Any aAny;
+ sal_Int32 nOldWidth = rNewValue.Width;
+ sal_Int32 nOldHeight = rNewValue.Height;
+
+ if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ try
+ {
+ Reference< XPropertySet > aXPropSet;
+ if ( aAny >>= aXPropSet )
+ {
+ if ( ImplGetPropertyValue( aAny, aXPropSet, sWidth, sal_True ) )
+ aAny >>= nOldWidth;
+ if ( ImplGetPropertyValue( aAny, aXPropSet, sHeight, sal_True ) )
+ aAny >>= nOldHeight;
+ }
+ if ( ( nOldWidth != rNewValue.Width ) || ( nOldHeight != rNewValue.Height ) )
+ {
+ aAny <<= rNewValue.Width;
+ aXPropSet->setPropertyValue( sWidth, aAny );
+ aAny <<= rNewValue.Height;
+ aXPropSet->setPropertyValue( sHeight, aAny );
+ bModified = sal_True;
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::WriteSize - could not read PropertyValue" );
+ }
+ }
+ }
+}
+
+void FilterConfigItem::WriteString( const OUString& rKey, const OUString& rNewValue )
+{
+ PropertyValue aString;
+ aString.Name = rKey;
+ aString.Value <<= rNewValue;
+ WritePropertyValue( aFilterData, aString );
+
+ if ( xPropSet.is() )
+ {
+ Any aAny;
+
+ if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ OUString aOldValue;
+ if ( aAny >>= aOldValue )
+ {
+ if ( aOldValue != rNewValue )
+ {
+ aAny <<= rNewValue;
+ try
+ {
+ xPropSet->setPropertyValue( rKey, aAny );
+ bModified = sal_True;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::WriteInt32 - could not set PropertyValue" );
+ }
+ }
+ }
+ }
+ }
+}
+
+void FilterConfigItem::WriteAny( const OUString& rKey, const Any& rNewAny )
+{
+ PropertyValue aPropValue;
+ aPropValue.Name = rKey;
+ aPropValue.Value = rNewAny;
+ WritePropertyValue( aFilterData, aPropValue );
+ if ( xPropSet.is() )
+ {
+ Any aAny;
+ if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
+ {
+ if ( aAny != rNewAny )
+ {
+ try
+ {
+ xPropSet->setPropertyValue( rKey, rNewAny );
+ bModified = sal_True;
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "FilterConfigItem::WriteAny - could not set PropertyValue" );
+
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+Sequence< PropertyValue > FilterConfigItem::GetFilterData() const
+{
+ return aFilterData;
+}
+
+// ------------------------------------------------------------------------
+
+Reference< XStatusIndicator > FilterConfigItem::GetStatusIndicator() const
+{
+ Reference< XStatusIndicator > xStatusIndicator;
+ const rtl::OUString sStatusIndicator( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) );
+
+ sal_Int32 i, nCount = aFilterData.getLength();
+ for ( i = 0; i < nCount; i++ )
+ {
+ if ( aFilterData[ i ].Name == sStatusIndicator )
+ {
+ aFilterData[ i ].Value >>= xStatusIndicator;
+ break;
+ }
+ }
+ return xStatusIndicator;
+}
+
diff --git a/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx b/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx
new file mode 100644
index 000000000000..038930ef80ee
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.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_svtools.hxx"
+
+#include "SvFilterOptionsDialog.hxx"
+#include <svtools/FilterConfigItem.hxx>
+#include <svtools/filter.hxx>
+#include "FilterConfigCache.hxx"
+#include <osl/file.hxx>
+#include <osl/module.hxx>
+#include <svl/solar.hrc>
+#include <svtools/fltcall.hxx>
+#include "dlgexpor.hxx"
+#include "dlgejpg.hxx"
+#include "dlgepng.hxx"
+#include <uno/mapping.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/document/XViewDataSupplier.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Any.h>
+#include <unotools/syslocale.hxx>
+#include "vcl/svapp.hxx"
+
+#if defined WIN || (defined OS2 && !defined ICC)
+#define EXPDLG_FUNCTION_NAME "_DoExportDialog"
+#else
+#define EXPDLG_FUNCTION_NAME "DoExportDialog"
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+// -------------------------
+// - SvFilterOptionsDialog -
+// -------------------------
+
+uno::Reference< uno::XInterface >
+ SAL_CALL SvFilterOptionsDialog_CreateInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & _rxFactory )
+{
+ return static_cast< ::cppu::OWeakObject* > ( new SvFilterOptionsDialog( _rxFactory ) );
+}
+
+OUString SvFilterOptionsDialog_getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.SvFilterOptionsDialog" ) );
+}
+#define SERVICE_NAME "com.sun.star.ui.dialog.FilterOptionsDialog"
+sal_Bool SAL_CALL SvFilterOptionsDialog_supportsService( const OUString& ServiceName )
+ throw( uno::RuntimeException )
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SERVICE_NAME ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog_getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
+ return aRet;
+}
+#undef SERVICE_NAME
+
+// -----------------------------------------------------------------------------
+
+SvFilterOptionsDialog::SvFilterOptionsDialog( const uno::Reference< lang::XMultiServiceFactory > & xMgr ) :
+ rxMgr ( xMgr ),
+ eFieldUnit ( FUNIT_CM )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SvFilterOptionsDialog::~SvFilterOptionsDialog()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SvFilterOptionsDialog::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SvFilterOptionsDialog::release() throw()
+{
+ OWeakObject::release();
+}
+
+// XInitialization
+void SAL_CALL SvFilterOptionsDialog::initialize( const uno::Sequence< uno::Any > & )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+}
+
+// XServiceInfo
+OUString SAL_CALL SvFilterOptionsDialog::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return SvFilterOptionsDialog_getImplementationName();
+}
+sal_Bool SAL_CALL SvFilterOptionsDialog::supportsService( const OUString& rServiceName )
+ throw( uno::RuntimeException )
+{
+ return SvFilterOptionsDialog_supportsService( rServiceName );
+}
+uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return SvFilterOptionsDialog_getSupportedServiceNames();
+}
+
+
+// XPropertyAccess
+uno::Sequence< beans::PropertyValue > SvFilterOptionsDialog::getPropertyValues()
+ throw ( uno::RuntimeException )
+{
+ sal_Int32 i, nCount;
+ for ( i = 0, nCount = aMediaDescriptor.getLength(); i < nCount; i++ )
+ {
+ if ( aMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) )
+ break;
+ }
+ if ( i == nCount )
+ aMediaDescriptor.realloc( ++nCount );
+
+ // the "FilterData" Property is an Any that will contain our PropertySequence of Values
+ aMediaDescriptor[ i ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterData" ) );
+ aMediaDescriptor[ i ].Value <<= aFilterDataSequence;
+ return aMediaDescriptor;
+}
+
+void SvFilterOptionsDialog::setPropertyValues( const uno::Sequence< beans::PropertyValue > & aProps )
+ throw ( beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ aMediaDescriptor = aProps;
+
+ sal_Int32 i, nCount;
+ for ( i = 0, nCount = aMediaDescriptor.getLength(); i < nCount; i++ )
+ {
+ if ( aMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) )
+ {
+ aMediaDescriptor[ i ].Value >>= aFilterDataSequence;
+ break;
+ }
+ }
+}
+
+// XExecutableDialog
+void SvFilterOptionsDialog::setTitle( const OUString& aTitle )
+ throw ( uno::RuntimeException )
+{
+ aDialogTitle = aTitle;
+}
+
+sal_Int16 SvFilterOptionsDialog::execute()
+ throw ( uno::RuntimeException )
+{
+ sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;
+
+ String aFilterNameStr( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ String aInternalFilterName;
+ sal_Int32 j, nCount = aMediaDescriptor.getLength();
+ for ( j = 0; j < nCount; j++ )
+ {
+ if ( aMediaDescriptor[ j ].Name.equals( aFilterNameStr ) )
+ {
+ OUString aStr;
+ aMediaDescriptor[ j ].Value >>= aStr;
+ aInternalFilterName = aStr;
+ aInternalFilterName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "draw_" ) ), String(), 0 );
+ aInternalFilterName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "impress_" ) ), String(), 0 );
+ break;
+ }
+ }
+ if ( aInternalFilterName.Len() )
+ {
+ GraphicFilter aGraphicFilter( sal_True );
+
+ sal_uInt16 nFormat, nFilterCount = aGraphicFilter.pConfig->GetExportFormatCount();
+ for ( nFormat = 0; nFormat < nFilterCount; nFormat++ )
+ {
+ if ( aGraphicFilter.pConfig->GetExportInternalFilterName( nFormat ) == aInternalFilterName )
+ break;
+ }
+ if ( nFormat < nFilterCount )
+ {
+ FltCallDialogParameter aFltCallDlgPara( Application::GetDefDialogParent(), NULL, eFieldUnit );
+ aFltCallDlgPara.aFilterData = aFilterDataSequence;
+
+ String aFilterName( aGraphicFilter.pConfig->GetExportFilterName( nFormat ) );
+ if ( aGraphicFilter.pConfig->IsExportInternalFilter( nFormat ) )
+ {
+ // Export-Dialog fuer Bitmap's, SVM's und WMF's
+ if( ( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) ) ||
+ ( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) ) ||
+ ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) ) ||
+ ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) ) ||
+ ( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )||
+ ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) ) )
+ {
+ ByteString aResMgrName( "svt", 3 );
+ ResMgr* pResMgr;
+
+ pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+ aFltCallDlgPara.pResMgr = pResMgr;
+ // JPEG-Dialog
+ if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
+ {
+ if ( DlgExportEJPG( aFltCallDlgPara ).Execute() == RET_OK )
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
+ {
+ if ( DlgExportEPNG( aFltCallDlgPara ).Execute() == RET_OK )
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
+ {
+ // Fuer Vektorformate nehmen wir den Vektor-Dialog
+ aFltCallDlgPara.aFilterExt = aGraphicFilter.pConfig->GetExportFormatShortName( nFormat );
+ if ( DlgExportPix( aFltCallDlgPara ).Execute() == RET_OK )
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ else
+ {
+ aFltCallDlgPara.aFilterExt = aGraphicFilter.pConfig->GetExportFormatShortName( nFormat );
+ if ( DlgExportVec( aFltCallDlgPara ).Execute() == RET_OK )
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ delete pResMgr;
+ }
+ }
+ else // ladbare Filter
+ {
+ xub_StrLen i, nTokenCount = aGraphicFilter.aFilterPath.GetTokenCount( ';' );
+ for ( i = 0; i < nTokenCount; i++ )
+ {
+
+ OUString aPathURL;
+
+ ::osl::FileBase::getFileURLFromSystemPath( aGraphicFilter.aFilterPath.GetToken( i ), aPathURL );
+ aPathURL += String( '/' );
+
+ OUString aSystemPath;
+ ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
+ aSystemPath += OUString( aFilterName );
+
+ osl::Module aLibrary( aSystemPath );
+ PFilterDlgCall pFunc = (PFilterDlgCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) );
+ // Dialog in DLL ausfuehren
+ if( pFunc )
+ {
+ if ( (*pFunc)( aFltCallDlgPara ) )
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ }
+ }
+ // taking the out parameter from the dialog
+ aFilterDataSequence = aFltCallDlgPara.aFilterData;
+ }
+ }
+ return nRet;
+}
+
+// XEmporter
+void SvFilterOptionsDialog::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
+ throw ( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ // try to set the corresponding metric unit
+ String aConfigPath;
+ uno::Reference< lang::XServiceInfo > xServiceInfo
+ ( xDoc, uno::UNO_QUERY );
+ if ( xServiceInfo.is() )
+ {
+ if ( xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) ) )
+ aConfigPath = String( RTL_CONSTASCII_USTRINGPARAM( "Office.Impress/Layout/Other/MeasureUnit" ) );
+ else if ( xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) ) )
+ aConfigPath = String( RTL_CONSTASCII_USTRINGPARAM( "Office.Draw/Layout/Other/MeasureUnit" ) );
+ if ( aConfigPath.Len() )
+ {
+ FilterConfigItem aConfigItem( aConfigPath );
+ String aPropertyName;
+ SvtSysLocale aSysLocale;
+ if ( aSysLocale.GetLocaleDataPtr()->getMeasurementSystemEnum() == MEASURE_METRIC )
+ aPropertyName = String( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
+ else
+ aPropertyName = String( RTL_CONSTASCII_USTRINGPARAM( "NonMetric" ) );
+ eFieldUnit = (FieldUnit)aConfigItem.ReadInt32( aPropertyName, FUNIT_CM );
+ }
+ }
+}
+
diff --git a/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.hxx b/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.hxx
new file mode 100644
index 000000000000..a55fc4c84520
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.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 _SV_FILTER_OPTIONS_DIALOG_HXX_
+#define _SV_FILTER_OPTIONS_DIALOG_HXX_
+
+#include <vcl/fldunit.hxx>
+#include <cppuhelper/implbase5.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+
+class SvFilterOptionsDialog : public cppu::WeakImplHelper5
+<
+ com::sun::star::document::XExporter,
+ com::sun::star::ui::dialogs::XExecutableDialog,
+ com::sun::star::beans::XPropertyAccess,
+ com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo
+>
+{
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &
+ rxMgr;
+ com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
+ aMediaDescriptor;
+ com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
+ aFilterDataSequence;
+ rtl::OUString aDialogTitle;
+ FieldUnit eFieldUnit;
+
+public:
+
+ SvFilterOptionsDialog( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB );
+ ~SvFilterOptionsDialog();
+
+ // XInterface
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // 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 );
+
+ // XPropertyAccess
+ virtual com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > & aProps )
+ throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XExecuteDialog
+ virtual sal_Int16 SAL_CALL execute()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ // 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 );
+
+};
+
+
+#endif // _SV_FILTER_OPTIONS_DIALOG_HXX_
+
diff --git a/svtools/source/filter.vcl/filter/dlgejpg.cxx b/svtools/source/filter.vcl/filter/dlgejpg.cxx
new file mode 100644
index 000000000000..377697023de3
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgejpg.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "dlgejpg.hxx"
+#include "dlgejpg.hrc"
+#include "strings.hrc"
+#include <svtools/FilterConfigItem.hxx>
+
+#define KEY_QUALITY "Quality"
+#define KEY_GRAYSCALES "ColorMode"
+
+/*************************************************************************
+|*
+|* Ctor
+|*
+\************************************************************************/
+
+DlgExportEJPG::DlgExportEJPG( FltCallDialogParameter& rPara ) :
+ ModalDialog ( rPara.pWindow, ResId( DLG_EXPORT_JPG, *rPara.pResMgr ) ),
+ rFltCallPara ( rPara ),
+ aFiDescr ( this, ResId( FI_DESCR, *rPara.pResMgr ) ),
+ aNumFldQuality ( this, ResId( NUM_FLD_QUALITY, *rPara.pResMgr ) ),
+ aGrpQuality ( this, ResId( GRP_QUALITY, *rPara.pResMgr ) ),
+ aRbGray ( this, ResId( RB_GRAY, *rPara.pResMgr ) ),
+ aRbRGB ( this, ResId( RB_RGB, *rPara.pResMgr ) ),
+ aGrpColors ( this, ResId( GRP_COLORS, *rPara.pResMgr ) ),
+ aBtnOK ( this, ResId( BTN_OK, *rPara.pResMgr ) ),
+ aBtnCancel ( this, ResId( BTN_CANCEL, *rPara.pResMgr ) ),
+ aBtnHelp ( this, ResId( BTN_HELP, *rPara.pResMgr ) )
+{
+ FreeResource();
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Export/JPG" ) );
+ pConfigItem = new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData );
+
+ // reading filter options
+ sal_Int32 nQuality = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( KEY_QUALITY ) ), 75 );
+ sal_Int32 nColorMode = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( KEY_GRAYSCALES ) ), 0 );
+ aNumFldQuality.SetValue( nQuality );
+
+ if ( nColorMode )
+ aRbGray.Check( sal_True );
+ else
+ aRbRGB.Check( sal_True );
+
+ aBtnOK.SetClickHdl( LINK( this, DlgExportEJPG, OK ) );
+}
+
+
+/*************************************************************************
+|*
+|* Speichert eingestellte Werte in ini-Datei
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportEJPG, OK, void *, EMPTYARG )
+{
+ // Config-Parameter schreiben
+ pConfigItem->WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( KEY_QUALITY ) ), (sal_Int32)aNumFldQuality.GetValue() );
+ pConfigItem->WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( KEY_GRAYSCALES ) ), aRbGray.IsChecked() ? 1 : 0 );
+ rFltCallPara.aFilterData = pConfigItem->GetFilterData();
+ EndDialog( RET_OK );
+ return 0;
+}
+
+DlgExportEJPG::~DlgExportEJPG()
+{
+ delete pConfigItem;
+}
+
+
diff --git a/svtools/source/filter.vcl/filter/dlgejpg.hrc b/svtools/source/filter.vcl/filter/dlgejpg.hrc
new file mode 100644
index 000000000000..90a3c1d162be
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgejpg.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.
+ *
+ ************************************************************************/
+#include <svtools/svtools.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 1
+#define BTN_HELP 1
+#define FI_DESCR 1
+#define NUM_FLD_QUALITY 1
+#define GRP_QUALITY 1
+#define GRP_COLORS 2
+#define RB_GRAY 1
+#define RB_RGB 2
+
+
diff --git a/svtools/source/filter.vcl/filter/dlgejpg.hxx b/svtools/source/filter.vcl/filter/dlgejpg.hxx
new file mode 100644
index 000000000000..d80682574a54
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgejpg.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 _DLGEJPG_HXX_
+#define _DLGEJPG_HXX_
+
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/field.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/msgbox.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svtools/fltcall.hxx>
+
+/*************************************************************************
+|*
+|* Dialog zum Einstellen von Filteroptionen
+|*
+\************************************************************************/
+class FilterConfigItem;
+class DlgExportEJPG : public ModalDialog
+{
+private:
+
+ FltCallDialogParameter& rFltCallPara;
+
+ FixedInfo aFiDescr;
+ NumericField aNumFldQuality;
+ FixedLine aGrpQuality;
+ RadioButton aRbGray;
+ RadioButton aRbRGB;
+ FixedLine aGrpColors;
+ OKButton aBtnOK;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ FilterConfigItem* pConfigItem;
+
+ DECL_LINK( OK, void * );
+
+public:
+ DlgExportEJPG( FltCallDialogParameter& rDlgPara );
+ ~DlgExportEJPG();
+};
+
+#endif // _DLGEJPG_HXX_
+
diff --git a/svtools/source/filter.vcl/filter/dlgejpg.src b/svtools/source/filter.vcl/filter/dlgejpg.src
new file mode 100644
index 000000000000..fd224f22c409
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgejpg.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 "dlgejpg.hrc"
+ModalDialog DLG_EXPORT_JPG
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 159 , 92 ) ;
+ Text [ en-US ] = "JPEG Options" ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 103 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 103 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 103 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedLine GRP_QUALITY
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 90 , 8 ) ;
+ Text [ en-US ] = "Quality" ;
+ };
+ FixedText FI_DESCR
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 81 , 16 ) ;
+ Text [ en-US ] = "1: min. quality\n100: max. quality" ;
+ };
+ NumericField NUM_FLD_QUALITY
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 33 ) ;
+ Size = MAP_APPFONT ( 50 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ Minimum = 1;
+ Maximum = 100 ;
+ StrictFormat = TRUE ;
+ Last = 100 ;
+ Repeat = TRUE ;
+ };
+ FixedLine GRP_COLORS
+ {
+ Pos = MAP_APPFONT ( 6 , 51 ) ;
+ Size = MAP_APPFONT ( 90 , 8 ) ;
+ Text [ en-US ] = "Color resolution" ;
+ };
+ RadioButton RB_GRAY
+ {
+ Pos = MAP_APPFONT ( 12 , 62 ) ;
+ Size = MAP_APPFONT ( 81 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Grayscale" ;
+ };
+ RadioButton RB_RGB
+ {
+ Pos = MAP_APPFONT ( 12 , 76 ) ;
+ Size = MAP_APPFONT ( 81 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "True Colors" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/filter.vcl/filter/dlgepng.cxx b/svtools/source/filter.vcl/filter/dlgepng.cxx
new file mode 100644
index 000000000000..bd551e9a4bda
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgepng.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_svtools.hxx"
+#include <tools/ref.hxx>
+#include <vcl/msgbox.hxx>
+#include "dlgepng.hxx"
+#include "dlgepng.hrc"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+/*************************************************************************
+|*
+|* Ctor
+|*
+\************************************************************************/
+
+DlgExportEPNG::DlgExportEPNG( FltCallDialogParameter& rPara ) :
+ ModalDialog ( rPara.pWindow, ResId( DLG_EXPORT_EPNG, *rPara.pResMgr ) ),
+ FilterConfigItem ( OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Export/PNG" ) ), &rPara.aFilterData ),
+ rFltCallPara ( rPara ),
+ aGrpCompression ( this, ResId( GRP_COMPRESSION, *rPara.pResMgr ) ),
+ aFiCompression ( this, ResId( FI_COMPRESSION, *rPara.pResMgr ) ),
+ aNumCompression ( this, ResId( NUM_COMPRESSION, *rPara.pResMgr ) ),
+ aCbxInterlaced ( this, ResId( CBX_INTERLACED, *rPara.pResMgr ) ),
+ aBtnOK ( this, ResId( BTN_OK, *rPara.pResMgr ) ),
+ aBtnCancel ( this, ResId( BTN_CANCEL, *rPara.pResMgr ) ),
+ aBtnHelp ( this, ResId( BTN_HELP, *rPara.pResMgr ) ),
+ pMgr ( rPara.pResMgr )
+{
+ FreeResource();
+
+ // Config-Parameter lesen
+ sal_Int32 nCompression = ReadInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Compression" ) ), 6 );
+ if ( ( nCompression < 0 ) || ( nCompression > 9 ) )
+ nCompression = 6;
+ aNumCompression.SetValue( nCompression );
+
+ sal_Int32 nInterlaced = ReadInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Interlaced" ) ), 0 );
+ sal_Bool bInterlaced = nInterlaced != 0;
+ aCbxInterlaced.Check( bInterlaced );
+
+ aBtnOK.SetClickHdl( LINK( this, DlgExportEPNG, OK ) );
+}
+
+/*************************************************************************
+|*
+|* Speichert eingestellte Werte in ini-Datei
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportEPNG, OK, void *, EMPTYARG )
+{
+ // Config-Parameter schreiben
+ WriteInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Compression" ) ), static_cast<sal_Int32>(aNumCompression.GetValue()) );
+ sal_Int32 nInterlace = 0;
+ if ( aCbxInterlaced.IsChecked() )
+ nInterlace++;
+ WriteInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Interlaced" ) ), nInterlace );
+ rFltCallPara.aFilterData = GetFilterData();
+ EndDialog( RET_OK );
+
+ return 0;
+}
diff --git a/svtools/source/filter.vcl/filter/dlgepng.hrc b/svtools/source/filter.vcl/filter/dlgepng.hrc
new file mode 100644
index 000000000000..b3ffaab3ab1e
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgepng.hrc
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <svtools/svtools.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 1
+#define BTN_HELP 1
+#define GRP_COMPRESSION 1
+#define FI_COMPRESSION 1
+#define NUM_COMPRESSION 1
+#define CBX_INTERLACED 1
diff --git a/svtools/source/filter.vcl/filter/dlgepng.hxx b/svtools/source/filter.vcl/filter/dlgepng.hxx
new file mode 100644
index 000000000000..469985afee59
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgepng.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 _DLGEPNG_HXX_
+#define _DLGEPNG_HXX_
+#include <svtools/fltcall.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/field.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svtools/FilterConfigItem.hxx>
+
+
+/*************************************************************************
+|*
+|* Dialog zum Einstellen von Filteroptionen
+|*
+\************************************************************************/
+
+class ResMgr;
+
+class DlgExportEPNG : public ModalDialog, FilterConfigItem
+{
+
+ private:
+
+ FltCallDialogParameter& rFltCallPara;
+
+ FixedLine aGrpCompression;
+ FixedInfo aFiCompression;
+ NumericField aNumCompression;
+ CheckBox aCbxInterlaced;
+ OKButton aBtnOK;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ ResMgr* pMgr;
+
+ DECL_LINK( OK, void * );
+
+ public:
+
+ DlgExportEPNG( FltCallDialogParameter& rPara );
+};
+
+#endif // _DLGEPNG_HXX_
diff --git a/svtools/source/filter.vcl/filter/dlgepng.src b/svtools/source/filter.vcl/filter/dlgepng.src
new file mode 100644
index 000000000000..aa778842dc48
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgepng.src
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dlgepng.hrc"
+ModalDialog DLG_EXPORT_EPNG
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 169 , 64 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Text [ en-US ] = "PNG Options" ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 113 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 113 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 113 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedLine GRP_COMPRESSION
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 100 , 8 ) ;
+ Text[ en-US ] = "Mode";
+ };
+ FixedText FI_COMPRESSION
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 80 , 8 ) ;
+ Text[ en-US ] = "~Compression 0..9";
+ };
+ NumericField NUM_COMPRESSION
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 25 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ Minimum = 0 ;
+ Maximum = 9 ;
+ First = 0 ;
+ Last = 9 ;
+ StrictFormat = TRUE ;
+ Repeat = TRUE ;
+ };
+ CheckBox CBX_INTERLACED
+ {
+ Pos = MAP_APPFONT ( 12 , 43 ) ;
+ Size = MAP_APPFONT ( 80 , 12 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Interlaced" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/filter.vcl/filter/dlgexpor.cxx b/svtools/source/filter.vcl/filter/dlgexpor.cxx
new file mode 100644
index 000000000000..b4b7c0fc949d
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgexpor.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_svtools.hxx"
+
+#ifndef GCC
+# pragma hdrstop
+#endif
+
+#include <tools/ref.hxx>
+#include <svtools/FilterConfigItem.hxx>
+#include <com/sun/star/awt/Size.hpp>
+#include <vcl/msgbox.hxx>
+#include "dlgexpor.hxx"
+#include "dlgexpor.hrc"
+#include "strings.hrc"
+
+/*************************************************************************
+|*
+|* Ctor
+|*
+\************************************************************************/
+
+DlgExportPix::DlgExportPix( FltCallDialogParameter& rPara ) :
+ ModalDialog ( rPara.pWindow, ResId( DLG_EXPORT_PIX, *rPara.pResMgr ) ),
+ rFltCallPara ( rPara ),
+ aBtnOK ( this, ResId( BTN_OK_PIX, *rPara.pResMgr ) ),
+ aBtnCancel ( this, ResId( BTN_CANCEL_PIX, *rPara.pResMgr ) ),
+ aBtnHelp ( this, ResId( BTN_HELP_PIX, *rPara.pResMgr ) ),
+ aLbColors ( this, ResId( LB_COLORS, *rPara.pResMgr ) ),
+ aCbxRLE ( this, ResId( CBX_RLE, *rPara.pResMgr ) ),
+ aGrpColors ( this, ResId( GRP_COLORS, *rPara.pResMgr ) ),
+ aRbOriginal ( this, ResId( RB_ORIGINAL_PIX, *rPara.pResMgr ) ),
+ aRbRes ( this, ResId( RB_RES_PIX, *rPara.pResMgr ) ),
+ aRbSize ( this, ResId( RB_SIZE_PIX, *rPara.pResMgr ) ),
+ aFtSizeX ( this, ResId( FT_SIZEX_PIX, *rPara.pResMgr ) ),
+ aMtfSizeX ( this, ResId( MTF_SIZEX_PIX, *rPara.pResMgr ) ),
+ aFtSizeY ( this, ResId( FT_SIZEY_PIX, *rPara.pResMgr ) ),
+ aMtfSizeY ( this, ResId( MTF_SIZEY_PIX, *rPara.pResMgr ) ),
+ aGrpMode ( this, ResId( GRP_MODE_PIX, *rPara.pResMgr ) ),
+ aCbbRes ( this, ResId( CBB_RES_PIX, *rPara.pResMgr ) ),
+ pMgr ( rPara.pResMgr ),
+ aExt ( rPara.aFilterExt )
+{
+ aExt.ToUpperAscii();
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Export/" ) );
+ aFilterConfigPath.Append( aExt );
+ pConfigItem = new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData );
+
+ String aTitle( aExt );
+ FreeResource();
+
+ aBtnOK.SetClickHdl( LINK( this, DlgExportPix, OK ) );
+ aRbOriginal.SetClickHdl( LINK( this, DlgExportPix, ClickRbOriginal ) );
+ aRbRes.SetClickHdl( LINK( this, DlgExportPix, ClickRbRes ) );
+ aRbSize.SetClickHdl( LINK( this, DlgExportPix, ClickRbSize ) );
+ aLbColors.SetSelectHdl( LINK( this, DlgExportPix, SelectLbColors ) );
+
+ aTitle.ToUpperAscii();
+ aTitle += String( ResId( EXPORT_DIALOG_TITLE, *pMgr ) );
+ SetText( aTitle );
+
+ // Config-Parameter lesen
+ sal_Int32 nColors = pConfigItem->ReadInt32( String( ResId( KEY_COLORS, *pMgr ) ), 0 );
+ sal_Int32 nMode = pConfigItem->ReadInt32( String( ResId( KEY_MODE, *pMgr ) ), 0 );
+ sal_Int32 nRes = pConfigItem->ReadInt32( String( ResId( KEY_RES, *pMgr ) ), 75 );
+ sal_Bool bRleCoding = pConfigItem->ReadBool( String( ResId( KEY_RLE_CODING, *pMgr ) ), sal_True );
+
+ aLbColors.SelectEntryPos( Min( (sal_uInt16) 7, (sal_uInt16)nColors ) );
+
+ String aStrRes( String::CreateFromInt32( nRes ) );
+ aStrRes.Append( String( RTL_CONSTASCII_USTRINGPARAM( " DPI" ) ) );
+ aCbbRes.SetText( aStrRes );
+
+ ::com::sun::star::awt::Size aDefault( 10000, 10000 );
+ ::com::sun::star::awt::Size aSize;
+ aSize = pConfigItem->ReadSize( String( ResId( KEY_SIZE, *pMgr ) ), aDefault );
+
+ aCbxRLE.Check( bRleCoding );
+
+ aMtfSizeX.SetDefaultUnit( FUNIT_MM );
+ aMtfSizeY.SetDefaultUnit( FUNIT_MM );
+
+ aMtfSizeX.SetValue( aSize.Width );
+ aMtfSizeY.SetValue( aSize.Height );
+
+ switch ( rPara.eFieldUnit )
+ {
+// case FUNIT_NONE :
+// case FUNIT_KM :
+// case FUNIT_PERCENT :
+// case FUNIT_CUSTOM :
+// case FUNIT_MILE :
+// case FUNIT_FOOT :
+// case FUNIT_M :
+ case FUNIT_MM :
+ case FUNIT_CM :
+ case FUNIT_TWIP :
+ case FUNIT_POINT :
+ case FUNIT_PICA :
+ case FUNIT_INCH :
+ case FUNIT_100TH_MM :
+ {
+ aMtfSizeX.SetUnit( rPara.eFieldUnit );
+ aMtfSizeY.SetUnit( rPara.eFieldUnit );
+ }
+ break;
+
+ default:
+ break; // -Wall multiple values not handled.
+ }
+
+ switch ( nMode )
+ {
+ case 2 :
+ {
+ aRbSize.Check( TRUE );
+ ClickRbSize( NULL );
+ }
+ break;
+ case 1 :
+ {
+ aRbRes.Check( TRUE );
+ ClickRbRes( NULL );
+ }
+ break;
+ default :
+ {
+ aRbOriginal.Check( TRUE );
+ ClickRbOriginal( NULL );
+ }
+ break;
+ }
+ SelectLbColors( &aLbColors );
+}
+
+DlgExportPix::~DlgExportPix()
+{
+ delete pConfigItem;
+}
+
+
+/*************************************************************************
+|*
+|* Speichert eingestellte Werte in ini-Datei
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportPix, OK, void *, EMPTYARG )
+{
+ // Config-Parameter schreiben
+
+ sal_Int32 nRes = Max( Min( aCbbRes.GetText().ToInt32(), sal_Int32( 600 ) ), sal_Int32( 75 ) );
+ ::com::sun::star::awt::Size aSize(
+ static_cast<long>(MetricField::ConvertDoubleValue( static_cast<double>(aMtfSizeX.GetValue()), 2, aMtfSizeX.GetUnit(), MAP_100TH_MM )),
+ static_cast<long>(MetricField::ConvertDoubleValue( static_cast<double>(aMtfSizeY.GetValue()), 2, aMtfSizeY.GetUnit(), MAP_100TH_MM )) );
+
+ sal_Int32 nMode;
+ if ( aRbRes.IsChecked() )
+ nMode = 1;
+ else if ( aRbSize.IsChecked() )
+ nMode = 2;
+ else
+ nMode = 0;
+
+ pConfigItem->WriteInt32( String( ResId( KEY_MODE, *pMgr ) ), nMode );
+ pConfigItem->WriteInt32( String( ResId( KEY_RES, *pMgr ) ), nRes );
+ pConfigItem->WriteSize( String( ResId( KEY_SIZE, *pMgr ) ), aSize );
+ pConfigItem->WriteInt32( String( ResId( KEY_COLORS, *pMgr ) ), (sal_Int32)aLbColors.GetSelectEntryPos() );
+ pConfigItem->WriteBool( String( ResId( KEY_RLE_CODING, *pMgr ) ), aCbxRLE.IsChecked() );
+ rFltCallPara.aFilterData = pConfigItem->GetFilterData();
+ EndDialog( RET_OK );
+
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* Enabled/Disabled Controls
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportPix, ClickRbOriginal, void*, EMPTYARG )
+{
+ aCbbRes.Disable();
+
+ aFtSizeX.Disable();
+ aMtfSizeX.Disable();
+ aFtSizeY.Disable();
+ aMtfSizeY.Disable();
+
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* Enabled/Disabled Controls
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportPix, ClickRbRes, void*, EMPTYARG )
+{
+ aCbbRes.Enable();
+
+ aFtSizeX.Disable();
+ aMtfSizeX.Disable();
+ aFtSizeY.Disable();
+ aMtfSizeY.Disable();
+
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* Enabled/Disabled Controls
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportPix, ClickRbSize, void*, EMPTYARG )
+{
+ aFtSizeX.Enable();
+ aMtfSizeX.Enable();
+ aFtSizeY.Enable();
+ aMtfSizeY.Enable();
+
+ aCbbRes.Disable();
+
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* Enabled/Disabled Controls
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportPix, SelectLbColors, void*, EMPTYARG )
+{
+ const USHORT nLbPos = aLbColors.GetSelectEntryPos();
+
+ if ( ( nLbPos >= 3 ) && ( nLbPos <= 6 ) )
+ aCbxRLE.Enable();
+ else
+ aCbxRLE.Disable();
+
+ return 0L;
+}
+
+
+/******************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Ctor
+|*
+\************************************************************************/
+
+DlgExportVec::DlgExportVec( FltCallDialogParameter& rPara ) :
+ ModalDialog ( rPara.pWindow, ResId( DLG_EXPORT_VEC, *rPara.pResMgr ) ),
+ rFltCallPara ( rPara ),
+ aBtnOK ( this, ResId( BTN_OK_VEC, *rPara.pResMgr ) ),
+ aBtnCancel ( this, ResId( BTN_CANCEL_VEC, *rPara.pResMgr ) ),
+ aBtnHelp ( this, ResId( BTN_HELP_VEC, *rPara.pResMgr ) ),
+ aRbOriginal ( this, ResId( RB_ORIGINAL_VEC, *rPara.pResMgr ) ),
+ aRbSize ( this, ResId( RB_SIZE_VEC, *rPara.pResMgr ) ),
+ aGrpMode ( this, ResId( GRP_MODE_VEC, *rPara.pResMgr ) ),
+ aFtSizeX ( this, ResId( FT_SIZEX_VEC, *rPara.pResMgr ) ),
+ aMtfSizeX ( this, ResId( MTF_SIZEX_VEC, *rPara.pResMgr ) ),
+ aFtSizeY ( this, ResId( FT_SIZEY_VEC, *rPara.pResMgr ) ),
+ aMtfSizeY ( this, ResId( MTF_SIZEY_VEC, *rPara.pResMgr ) ),
+ aGrpSize ( this, ResId( GRP_SIZE_VEC, *rPara.pResMgr ) ),
+ pMgr ( rPara.pResMgr ),
+ aExt ( rPara.aFilterExt )
+{
+ aExt.ToUpperAscii();
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Export/" ) );
+ aFilterConfigPath.Append( aExt );
+ pConfigItem = new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData );
+
+ String aTitle( aExt );
+ FreeResource();
+
+ aBtnOK.SetClickHdl( LINK( this, DlgExportVec, OK ) );
+ aRbOriginal.SetClickHdl( LINK( this, DlgExportVec, ClickRbOriginal ) );
+ aRbSize.SetClickHdl( LINK( this, DlgExportVec, ClickRbSize ) );
+
+ aTitle.ToUpperAscii();
+ aTitle += String( ResId( EXPORT_DIALOG_TITLE, *pMgr ) );
+ SetText( aTitle );
+
+ // reading config-parameter
+ sal_Int32 nMode = pConfigItem->ReadInt32( String( ResId( KEY_MODE, *pMgr ) ), 0 );
+
+ ::com::sun::star::awt::Size aDefault( 10000, 10000 );
+ ::com::sun::star::awt::Size aSize;
+ aSize = pConfigItem->ReadSize( String( ResId( KEY_SIZE, *pMgr ) ), aDefault );
+
+ aMtfSizeX.SetDefaultUnit( FUNIT_MM );
+ aMtfSizeY.SetDefaultUnit( FUNIT_MM );
+ aMtfSizeX.SetValue( aSize.Width );
+ aMtfSizeY.SetValue( aSize.Height );
+
+ switch ( rPara.eFieldUnit )
+ {
+// case FUNIT_NONE :
+// case FUNIT_KM :
+// case FUNIT_PERCENT :
+// case FUNIT_CUSTOM :
+// case FUNIT_MILE :
+// case FUNIT_FOOT :
+ case FUNIT_MM :
+ case FUNIT_CM :
+ case FUNIT_M :
+ case FUNIT_TWIP :
+ case FUNIT_POINT :
+ case FUNIT_PICA :
+ case FUNIT_INCH :
+ case FUNIT_100TH_MM :
+ {
+ aMtfSizeX.SetUnit( rPara.eFieldUnit );
+ aMtfSizeY.SetUnit( rPara.eFieldUnit );
+ }
+ break;
+ default:
+ break; // -Wall Multiple values not handled.
+ }
+
+ switch ( nMode )
+ {
+ case 1 :
+ {
+ aRbSize.Check( TRUE );
+ ClickRbSize( NULL );
+ }
+ break;
+
+ default :
+ {
+ aRbOriginal.Check( TRUE );
+ ClickRbOriginal( NULL );
+ }
+ break;
+ }
+}
+
+DlgExportVec::~DlgExportVec()
+{
+ delete pConfigItem;
+}
+/*************************************************************************
+|*
+|* Speichert eingestellte Werte in ini-Datei
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportVec, OK, void *, EMPTYARG )
+{
+ // Config-Parameter schreiben
+ ::com::sun::star::awt::Size aSize(
+ static_cast<long>(MetricField::ConvertDoubleValue( static_cast<double>(aMtfSizeX.GetValue()), 2, aMtfSizeX.GetUnit(), MAP_100TH_MM )),
+ static_cast<long>(MetricField::ConvertDoubleValue( static_cast<double>(aMtfSizeY.GetValue()), 2, aMtfSizeY.GetUnit(), MAP_100TH_MM )) );
+
+ sal_Int32 nMode;
+ if ( aRbSize.IsChecked() )
+ nMode = 1;
+ else
+ nMode = 0;
+
+ pConfigItem->WriteInt32( String( ResId( KEY_MODE, *pMgr ) ), nMode );
+ pConfigItem->WriteSize( String( ResId( KEY_SIZE, *pMgr ) ), aSize );
+ rFltCallPara.aFilterData = pConfigItem->GetFilterData();
+ EndDialog( RET_OK );
+
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* Enabled/Disabled Controls
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportVec, ClickRbOriginal, void*, EMPTYARG )
+{
+ aGrpSize.Disable();
+ aFtSizeX.Disable();
+ aMtfSizeX.Disable();
+ aFtSizeY.Disable();
+ aMtfSizeY.Disable();
+
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* Enabled/Disabled Controls
+|*
+\************************************************************************/
+
+IMPL_LINK( DlgExportVec, ClickRbSize, void*, EMPTYARG )
+{
+ aGrpSize.Enable();
+ aFtSizeX.Enable();
+ aMtfSizeX.Enable();
+ aFtSizeY.Enable();
+ aMtfSizeY.Enable();
+
+ return 0;
+}
+
+
+
diff --git a/svtools/source/filter.vcl/filter/dlgexpor.hrc b/svtools/source/filter.vcl/filter/dlgexpor.hrc
new file mode 100644
index 000000000000..69870c9b00b0
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgexpor.hrc
@@ -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 <svtools/svtools.hrc>
+
+#define BTN_OK_PIX 1
+#define BTN_CANCEL_PIX 1
+#define BTN_HELP_PIX 1
+#define CBX_RES_PIX 1
+#define CBX_SIZE_PIX 2
+#define CBX_RLE 3
+#define CBB_RES_PIX 1
+#define LB_COLORS 1
+#define MTF_SIZEX_PIX 1
+#define MTF_SIZEY_PIX 2
+#define FT_SIZEX_PIX 1
+#define FT_SIZEY_PIX 2
+#define GRP_MODE_PIX 1
+#define GRP_COLORS 4
+#define RB_ORIGINAL_PIX 1
+#define RB_RES_PIX 2
+#define RB_SIZE_PIX 3
+
+#define BTN_OK_VEC 1
+#define BTN_CANCEL_VEC 1
+#define BTN_HELP_VEC 1
+#define CBX_SIZE_VEC 2
+#define MTF_SIZEX_VEC 1
+#define MTF_SIZEY_VEC 2
+#define FT_SIZEX_VEC 1
+#define FT_SIZEY_VEC 2
+#define GRP_SIZE_VEC 1
+#define GRP_MODE_VEC 2
+#define RB_ORIGINAL_VEC 1
+#define RB_SIZE_VEC 2
diff --git a/svtools/source/filter.vcl/filter/dlgexpor.hxx b/svtools/source/filter.vcl/filter/dlgexpor.hxx
new file mode 100644
index 000000000000..8c7b2d462e70
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgexpor.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 _DLGEXPOR_HXX_
+#define _DLGEXPOR_HXX_
+
+#include <svtools/fltcall.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/field.hxx>
+#include <vcl/lstbox.hxx>
+
+/*************************************************************************
+|*
+|* Dialog zum Einstellen von Filteroptionen bei Pixelformaten
+|*
+\************************************************************************/
+
+class FilterConfigItem;
+class DlgExportPix : public ModalDialog
+{
+private:
+
+ FltCallDialogParameter& rFltCallPara;
+
+ OKButton aBtnOK;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ ListBox aLbColors;
+ CheckBox aCbxRLE;
+ FixedLine aGrpColors;
+
+ RadioButton aRbOriginal;
+ RadioButton aRbRes;
+ RadioButton aRbSize;
+ FixedText aFtSizeX;
+ MetricField aMtfSizeX;
+ FixedText aFtSizeY;
+ MetricField aMtfSizeY;
+ FixedLine aGrpMode;
+ ComboBox aCbbRes;
+
+ FilterConfigItem* pConfigItem;
+ ResMgr* pMgr;
+
+ String aExt;
+
+ DECL_LINK( OK, void* p );
+ DECL_LINK( ClickRbOriginal,void* p );
+ DECL_LINK( ClickRbRes,void* p );
+ DECL_LINK( ClickRbSize,void* p );
+ DECL_LINK( SelectLbColors, void* p );
+
+public:
+ DlgExportPix( FltCallDialogParameter& rPara );
+ ~DlgExportPix();
+};
+
+
+/*************************************************************************
+|*
+|* Dialog zum Einstellen von Filteroptionen bei Vektorformaten
+|*
+\************************************************************************/
+class DlgExportVec : public ModalDialog
+{
+private:
+
+ FltCallDialogParameter& rFltCallPara;
+
+ OKButton aBtnOK;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ RadioButton aRbOriginal;
+ RadioButton aRbSize;
+ FixedLine aGrpMode;
+
+ FixedText aFtSizeX;
+ MetricField aMtfSizeX;
+ FixedText aFtSizeY;
+ MetricField aMtfSizeY;
+ FixedLine aGrpSize;
+
+ FilterConfigItem* pConfigItem;
+ ResMgr* pMgr;
+
+ String aExt;
+
+ DECL_LINK( OK, void* p );
+ DECL_LINK( ClickRbOriginal,void* p );
+ DECL_LINK( ClickRbSize,void* p );
+
+public:
+ DlgExportVec( FltCallDialogParameter& rPara );
+ ~DlgExportVec();
+};
+
+#endif // _DLGEXPOR_HXX_
+
diff --git a/svtools/source/filter.vcl/filter/dlgexpor.src b/svtools/source/filter.vcl/filter/dlgexpor.src
new file mode 100644
index 000000000000..7573b394d72f
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/dlgexpor.src
@@ -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.
+ *
+ ************************************************************************/
+
+
+#include "dlgexpor.hrc"
+
+ModalDialog DLG_EXPORT_PIX
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 178 , 135 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ FixedLine GRP_COLORS
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 110 , 8 ) ;
+ Text [ en-US ] = "Color resolution" ;
+ };
+ ListBox LB_COLORS
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 98 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ AutoHScroll = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Original" ; Default ; > ;
+ < "1 Bit - Threshold Value" ; Default ; > ;
+ < "1 Bit - Dithering" ; Default ; > ;
+ < "4 Bit - Grayscale" ; Default ; > ;
+ < "4 Bit - Color Palette" ; Default ; > ;
+ < "8 Bit - Grayscales" ; Default ; > ;
+ < "8 Bit - Color Palette" ; Default ; > ;
+ < "24 Bit - True Colors" ; Default ; > ;
+ };
+ };
+ CheckBox CBX_RLE
+ {
+ Pos = MAP_APPFONT ( 12 , 31 ) ;
+ Size = MAP_APPFONT ( 98 , 12 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "RLE coding" ;
+ };
+ FixedLine GRP_MODE_PIX
+ {
+ Pos = MAP_APPFONT ( 6 , 48 ) ;
+ Size = MAP_APPFONT ( 110 , 8 ) ;
+ Text [ en-US ] = "Mode" ;
+ };
+ RadioButton RB_ORIGINAL_PIX
+ {
+ Pos = MAP_APPFONT ( 12 , 59 ) ;
+ Size = MAP_APPFONT ( 98 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Original" ;
+ };
+ RadioButton RB_RES_PIX
+ {
+ Pos = MAP_APPFONT ( 12 , 73 ) ;
+ Size = MAP_APPFONT ( 55 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Resolution" ;
+ };
+ ComboBox CBB_RES_PIX
+ {
+ Pos = MAP_APPFONT ( 70 , 73 ) ;
+ Size = MAP_APPFONT ( 40 , 50 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList =
+ {
+ "75 DPI" ;
+ "150 DPI" ;
+ "300 DPI" ;
+ "600 DPI" ;
+ };
+ };
+ RadioButton RB_SIZE_PIX
+ {
+ Pos = MAP_APPFONT ( 12 , 87 ) ;
+ Size = MAP_APPFONT ( 98 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Size" ;
+ };
+ MetricField MTF_SIZEX_PIX
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 100 ;
+ Maximum = 99999 ;
+ StrictFormat = TRUE ;
+ DecimalDigits = 2 ;
+ Unit = FUNIT_MM ;
+ First = 100 ;
+ Last = 99999 ;
+ SpinSize = 100 ;
+ };
+ FixedText FT_SIZEX_PIX
+ {
+ Pos = MAP_APPFONT ( 18 , 102 ) ;
+ Size = MAP_APPFONT ( 41 , 10 ) ;
+ Text [ en-US ] = "Width" ;
+ };
+ MetricField MTF_SIZEY_PIX
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 117 ) ;
+ Size = MAP_APPFONT ( 50 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 100 ;
+ Maximum = 99999 ;
+ StrictFormat = TRUE ;
+ DecimalDigits = 2 ;
+ Unit = FUNIT_MM ;
+ First = 100 ;
+ Last = 99999 ;
+ SpinSize = 100 ;
+ };
+ FixedText FT_SIZEY_PIX
+ {
+ Pos = MAP_APPFONT ( 18 , 118 ) ;
+ Size = MAP_APPFONT ( 41 , 10 ) ;
+ Text [ en-US ] = "Height" ;
+ };
+ OKButton BTN_OK_PIX
+ {
+ Pos = MAP_APPFONT ( 122 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL_PIX
+ {
+ Pos = MAP_APPFONT ( 122 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP_PIX
+ {
+ Pos = MAP_APPFONT ( 122 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
+ModalDialog DLG_EXPORT_VEC
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 178 , 89 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ FixedLine GRP_MODE_VEC
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 110 , 8 ) ;
+ Text [ en-US ] = "Mode" ;
+ };
+ RadioButton RB_ORIGINAL_VEC
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 98 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Original" ;
+ };
+ RadioButton RB_SIZE_VEC
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 98 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Size" ;
+ };
+ FixedLine GRP_SIZE_VEC
+ {
+ Pos = MAP_APPFONT ( 6 , 44 ) ;
+ Size = MAP_APPFONT ( 110 , 8 ) ;
+ Text [ en-US ] = "Size" ;
+ };
+ FixedText FT_SIZEX_VEC
+ {
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "Width" ;
+ };
+ MetricField MTF_SIZEX_VEC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 55 ) ;
+ Size = MAP_APPFONT ( 50 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 100 ;
+ Maximum = 99999 ;
+ StrictFormat = TRUE ;
+ DecimalDigits = 2 ;
+ Unit = FUNIT_MM ;
+ First = 100 ;
+ Last = 99999 ;
+ SpinSize = 100 ;
+ };
+ FixedText FT_SIZEY_VEC
+ {
+ Pos = MAP_APPFONT ( 12 , 72 ) ;
+ Size = MAP_APPFONT ( 45 , 10 ) ;
+ Text [ en-US ] = "Height" ;
+ };
+ MetricField MTF_SIZEY_VEC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 71 ) ;
+ Size = MAP_APPFONT ( 50 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 100 ;
+ Maximum = 99999 ;
+ StrictFormat = TRUE ;
+ DecimalDigits = 2 ;
+ Unit = FUNIT_MM ;
+ First = 100 ;
+ Last = 99999 ;
+ SpinSize = 100 ;
+ };
+ OKButton BTN_OK_VEC
+ {
+ Pos = MAP_APPFONT ( 122 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL_VEC
+ {
+ Pos = MAP_APPFONT ( 122 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP_VEC
+ {
+ Pos = MAP_APPFONT ( 122 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/filter.vcl/filter/filter.cxx b/svtools/source/filter.vcl/filter/filter.cxx
new file mode 100644
index 000000000000..c8a79d3a35cd
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/filter.cxx
@@ -0,0 +1,2171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#if defined UNX && defined ALPHA
+#include <fstream.hxx>
+#endif
+#include <vos/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/salctype.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/pngwrite.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/file.hxx>
+#include <svtools/filter.hxx>
+#include "FilterConfigCache.hxx"
+#include <svtools/FilterConfigItem.hxx>
+#include <svtools/fltcall.hxx>
+#include <svtools/wmf.hxx>
+#include "gifread.hxx"
+#include "jpeg.hxx"
+#include "xbmread.hxx"
+#include "xpmread.hxx"
+#include <svl/solar.hrc>
+#include "strings.hrc"
+#include "sgffilt.hxx"
+#include "osl/module.hxx"
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/XWeak.hpp>
+#include <com/sun/star/uno/XAggregation.hpp>
+#ifndef _COM_SUN_STAR_UNO_XTYPEPROVIDER_HPP_
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#endif
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/svg/XSVGWriter.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/instance.hxx>
+
+#include "SvFilterOptionsDialog.hxx"
+
+#define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF
+
+#if defined WIN || (defined OS2 && !defined ICC)
+
+#define IMPORT_FUNCTION_NAME "_GraphicImport"
+#define EXPORT_FUNCTION_NAME "_GraphicExport"
+#define IMPDLG_FUNCTION_NAME "_DoImportDialog"
+#define EXPDLG_FUNCTION_NAME "_DoExportDialog"
+
+#else
+
+#define IMPORT_FUNCTION_NAME "GraphicImport"
+#define EXPORT_FUNCTION_NAME "GraphicExport"
+#define IMPDLG_FUNCTION_NAME "DoImportDialog"
+#define EXPDLG_FUNCTION_NAME "DoExportDialog"
+
+#endif
+
+// Compilerfehler, wenn Optimierung bei WNT & MSC
+#ifdef _MSC_VER
+#pragma optimize( "", off )
+#endif
+
+// -----------
+// - statics -
+// -----------
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+static List* pFilterHdlList = NULL;
+
+static ::osl::Mutex& getListMutex()
+{
+ static ::osl::Mutex s_aListProtection;
+ return s_aListProtection;
+}
+
+static GraphicFilter* pGraphicFilter=0;
+
+// -------------------------
+// - ImpFilterOutputStream -
+// -------------------------
+
+class ImpFilterOutputStream : public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream >
+{
+protected:
+
+ SvStream& mrStm;
+
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& rData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { mrStm.Write( rData.getConstArray(), rData.getLength() ); }
+ virtual void SAL_CALL flush() throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { mrStm.Flush(); }
+ virtual void SAL_CALL closeOutput() throw() {}
+
+public:
+
+ ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {}
+ ~ImpFilterOutputStream() {}
+};
+
+BOOL ImplDirEntryHelper::Exists( const INetURLObject& rObj )
+{
+ BOOL bExists = FALSE;
+
+ try
+ {
+ ::rtl::OUString aTitle;
+ ::ucbhelper::Content aCnt( rObj.GetMainURL( INetURLObject::NO_DECODE ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ bExists = aCnt.isDocument();
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ::com::sun::star::ucb::ContentCreationException& )
+ {
+ DBG_ERRORFILE( "ContentCreationException" );
+ }
+ catch( ... )
+ {
+// DBG_ERRORFILE( "Any other exception" );
+ }
+ return bExists;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplDirEntryHelper::Kill( const String& rMainUrl )
+{
+ try
+ {
+ ::ucbhelper::Content aCnt( rMainUrl,
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+}
+
+// --------------------
+// - Helper functions -
+// --------------------
+
+//--------------------------------------------------------------------------
+
+BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ ULONG i;
+ for ( i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+//--------------------------------------------------------------------------
+
+inline String ImpGetExtension( const String &rPath )
+{
+ String aExt;
+ INetURLObject aURL( rPath );
+ aExt = aURL.GetFileExtension().toAsciiUpperCase();
+ return aExt;
+}
+
+/*************************************************************************
+|*
+|* ImpPeekGraphicFormat()
+|*
+|* Beschreibung:
+|* Diese Funktion kann zweierlei:
+|* 1.) Datei anlesen, Dateiformat ermitteln
+|* Eingabe-prarameter:
+|* rPath - Dateipfad
+|* rFormatExtension - Inhalt egal
+|* bTest - setze FALSE
+|* Ausgabe-parameter:
+|* Funkionswert - TRUE wenn Erfolg
+|* rFormatExtension - Bei Erfolg: uebliche Dateiendung
+|* des Formats (Grossbuchstaben)
+|* 2.) Datei anlesen, Dateiformat ueberpruefen
+|* Eingabe-prarameter:
+|* rPath - Dateipfad
+|* rFormatExtension - uebliche Dateiendung des Formats
+|* (Grossbuchstaben)
+|* bTest - setze TRUE
+|* Ausgabe-parameter:
+|* Funkionswert - FALSE, wenn die Datei bestimmt nicht
+|* vom uebgebenen Format ist.
+|* TRUE, wenn die Datei WAHRSCHEINLICH von
+|* dem Format ist, ODER WENN DAS FORMAT
+|* DIESER FUNKTION NICHT BEKANNT IST!
+|*
+|* Ersterstellung OH 26.05.95
+|* Letzte Aenderung OH 07.08.95
+|*
+*************************************************************************/
+
+static BOOL ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtension, BOOL bTest )
+{
+ USHORT i;
+ BYTE sFirstBytes[ 256 ];
+ ULONG nFirstLong,nSecondLong;
+ ULONG nStreamPos = rStream.Tell();
+
+ rStream.Seek( STREAM_SEEK_TO_END );
+ ULONG nStreamLen = rStream.Tell() - nStreamPos;
+ rStream.Seek( nStreamPos );
+
+ if ( !nStreamLen )
+ {
+ SvLockBytes* pLockBytes = rStream.GetLockBytes();
+ if ( pLockBytes )
+ pLockBytes->SetSynchronMode( TRUE );
+
+ rStream.Seek( STREAM_SEEK_TO_END );
+ nStreamLen = rStream.Tell() - nStreamPos;
+ rStream.Seek( nStreamPos );
+ }
+ // Die ersten 256 Bytes in einen Buffer laden:
+ if( nStreamLen >= 256 )
+ rStream.Read( sFirstBytes, 256 );
+ else
+ {
+ rStream.Read( sFirstBytes, nStreamLen );
+
+ for( i = (USHORT) nStreamLen; i < 256; i++ )
+ sFirstBytes[ i ]=0;
+ }
+
+ if( rStream.GetError() )
+ return FALSE;
+
+ // Die ersten 8 Bytes in nFirstLong, nSecondLong unterbringen,
+ // Big-Endian:
+ for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ )
+ {
+ nFirstLong=(nFirstLong<<8)|(ULONG)sFirstBytes[i];
+ nSecondLong=(nSecondLong<<8)|(ULONG)sFirstBytes[i+4];
+ }
+
+ // Folgende Variable ist nur bei bTest==TRUE interessant. Sie
+ // bleibt FALSE, wenn das Format (rFormatExtension) hier noch nicht
+ // einprogrammiert wurde.
+ BOOL bSomethingTested = FALSE;
+
+ // Nun werden die verschieden Formate ueberprueft. Dabei ist die
+ // Reihenfolge nicht egal. Z.b. koennte eine MET-Datei auch durch
+ // den BMP-Test gehen, umgekehrt kann eine BMP-Datei kaum durch den
+ // MET-Test gehen. Also sollte MET vor BMP getestet werden.
+ // Theoretisch waere aber vielleicht auch eine BMP-Datei denkbar,
+ // die durch den MET-Test geht.
+ // Diese Probleme gibt es natuerlich nicht nur bei MET und BMP.
+ // Deshalb wird im Falle der Uberpruefung eines Formats (bTest==TRUE)
+ // nur genau dieses eine Format getestet. Alles andere koennte fatale
+ // Folgen haben, z.B. wenn der Benutzer sagt, es sei BMP-Datei (und es
+ // ist BMP-Datei), und hier wuerde die Datei durch den MET-Test gehen...
+
+ //--------------------------- MET ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "MET", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if( sFirstBytes[2] == 0xd3 )
+ {
+ rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStream.Seek( nStreamPos );
+ USHORT nFieldSize;
+ BYTE nMagic;
+ BOOL bOK=TRUE;
+ rStream >> nFieldSize >> nMagic;
+ for (i=0; i<3; i++) {
+ if (nFieldSize<6) { bOK=FALSE; break; }
+ if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=FALSE; break; }
+ rStream.SeekRel(nFieldSize-3);
+ rStream >> nFieldSize >> nMagic;
+ if (nMagic!=0xd3) { bOK=FALSE; break; }
+ }
+ rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ if (bOK && !rStream.GetError()) {
+ rFormatExtension= UniString::CreateFromAscii( "MET", 3 );
+ return TRUE;
+ }
+ }
+ }
+
+ //--------------------------- BMP ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "BMP", 3 ) == COMPARE_EQUAL ) )
+ {
+ BYTE nOffs;
+
+ bSomethingTested=TRUE;
+
+ // OS/2-Bitmaparray ('BA') koennen wir evtl. auch lesen,
+ // dementspr. muessen wir den Offset anpassen,
+ // um auf die erste Bitmap im Array zu stossen
+ if ( sFirstBytes[0] == 0x42 && sFirstBytes[1] == 0x41 )
+ nOffs = 14;
+ else
+ nOffs = 0;
+
+ // Jetzt testen wir zunaechst auf 'BM'
+ if ( sFirstBytes[0+nOffs]==0x42 && sFirstBytes[1+nOffs]==0x4d )
+ {
+ // unter OS/2 koennen die Reserved-Flags != 0 sein
+ // (was sie eigentlich nicht duerften);
+ // in diesem Fall testen wir die Groesse des BmpInfoHeaders
+ if ( ( sFirstBytes[6+nOffs]==0x00 &&
+ sFirstBytes[7+nOffs]==0x00 &&
+ sFirstBytes[8+nOffs]==0x00 &&
+ sFirstBytes[9+nOffs]==0x00 ) ||
+ sFirstBytes[14+nOffs] == 0x28 ||
+ sFirstBytes[14+nOffs] == 0x0c )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "BMP", 3 );
+ return TRUE;
+ }
+ }
+ }
+
+ //--------------------------- WMF/EMF ------------------------------------
+
+ if( !bTest ||
+ ( rFormatExtension.CompareToAscii( "WMF", 3 ) == COMPARE_EQUAL ) ||
+ ( rFormatExtension.CompareToAscii( "EMF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+
+ if ( nFirstLong==0xd7cdc69a || nFirstLong==0x01000900 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "WMF", 3 );
+ return TRUE;
+ }
+ else if( nFirstLong == 0x01000000 && sFirstBytes[ 40 ] == 0x20 && sFirstBytes[ 41 ] == 0x45 &&
+ sFirstBytes[ 42 ] == 0x4d && sFirstBytes[ 43 ] == 0x46 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "EMF", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- PCX ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PCX", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if (sFirstBytes[0]==0x0a)
+ {
+ BYTE nVersion=sFirstBytes[1];
+ BYTE nEncoding=sFirstBytes[2];
+ if( ( nVersion==0 || nVersion==2 || nVersion==3 || nVersion==5 ) && nEncoding<=1 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCX", 3 );
+ return TRUE;
+ }
+ }
+ }
+
+ //--------------------------- TIF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "TIF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if ( nFirstLong==0x49492a00 || nFirstLong==0x4d4d002a )
+ {
+ rFormatExtension=UniString::CreateFromAscii( "TIF", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- GIF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "GIF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if ( nFirstLong==0x47494638 && (sFirstBytes[4]==0x37 || sFirstBytes[4]==0x39) && sFirstBytes[5]==0x61 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "GIF", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- PNG ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PNG", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if (nFirstLong==0x89504e47 && nSecondLong==0x0d0a1a0a)
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PNG", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- JPG ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "JPG", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if ( ( nFirstLong==0xffd8ffe0 && sFirstBytes[6]==0x4a && sFirstBytes[7]==0x46 && sFirstBytes[8]==0x49 && sFirstBytes[9]==0x46 ) ||
+ ( nFirstLong==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong & 0xffffff00 ) ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "JPG", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- SVM ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SVM", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if( nFirstLong==0x53564744 && sFirstBytes[4]==0x49 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
+ return TRUE;
+ }
+ else if( sFirstBytes[0]==0x56 && sFirstBytes[1]==0x43 && sFirstBytes[2]==0x4C &&
+ sFirstBytes[3]==0x4D && sFirstBytes[4]==0x54 && sFirstBytes[5]==0x46 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- PCD ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PCD", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+ if( nStreamLen >= 2055 )
+ {
+ char sBuf[8];
+ rStream.Seek( nStreamPos + 2048 );
+ rStream.Read( sBuf, 7 );
+
+ if( strncmp( sBuf, "PCD_IPI", 7 ) == 0 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCD", 3 );
+ return TRUE;
+ }
+ }
+ }
+
+ //--------------------------- PSD ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PSD", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+ if ( ( nFirstLong == 0x38425053 ) && ( (nSecondLong >> 16 ) == 1 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PSD", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- EPS ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "EPS", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+ if ( ( nFirstLong == 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes, (BYTE*)"%!PS-Adobe", 10, 10 ) &&
+ ImplSearchEntry( &sFirstBytes[15], (BYTE*)"EPS", 3, 3 ) ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "EPS", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- DXF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "DXF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+
+ i=0;
+ while (i<256 && sFirstBytes[i]<=32)
+ i++;
+
+ if (i<256)
+ {
+ if( sFirstBytes[i]=='0' )
+ i++;
+ else
+ i=256;
+ }
+ while( i<256 && sFirstBytes[i]<=32 )
+ i++;
+
+ if (i+7<256)
+ {
+ if (strncmp((char*)(sFirstBytes+i),"SECTION",7)==0)
+ {
+ rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
+ return TRUE;
+ }
+ }
+
+ if( strncmp( (char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- PCT ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+ BYTE sBuf[4];
+ sal_uInt32 nOffset; // in ms documents the pict format is used without the first 512 bytes
+ for ( nOffset = 10; ( nOffset <= 522 ) && ( ( nStreamPos + nOffset + 3 ) <= nStreamLen ); nOffset += 512 )
+ {
+ rStream.Seek( nStreamPos + nOffset );
+ rStream.Read( sBuf,3 );
+ if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && ( sBuf[ 2 ] == 0x01 || sBuf[ 2 ] == 0x02 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
+ return TRUE;
+ }
+ }
+ }
+
+ //------------------------- PBM + PGM + PPM ---------------------------
+ if( !bTest ||
+ ( rFormatExtension.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL ) ||
+ ( rFormatExtension.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL ) ||
+ ( rFormatExtension.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if ( sFirstBytes[ 0 ] == 'P' )
+ {
+ switch( sFirstBytes[ 1 ] )
+ {
+ case '1' :
+ case '4' :
+ rFormatExtension = UniString::CreateFromAscii( "PBM", 3 );
+ return TRUE;
+
+ case '2' :
+ case '5' :
+ rFormatExtension = UniString::CreateFromAscii( "PGM", 3 );
+ return TRUE;
+
+ case '3' :
+ case '6' :
+ rFormatExtension = UniString::CreateFromAscii( "PPM", 3 );
+ return TRUE;
+ }
+ }
+ }
+
+ //--------------------------- RAS( SUN RasterFile )------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if( nFirstLong == 0x59a66a95 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "RAS", 3 );
+ return TRUE;
+ }
+ }
+
+ //--------------------------- XPM ------------------------------------
+ if( !bTest )
+ {
+ bSomethingTested = TRUE;
+ if( ImplSearchEntry( sFirstBytes, (BYTE*)"/* XPM */", 256, 9 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "XPM", 3 );
+ return TRUE;
+ }
+ }
+ else if( rFormatExtension.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL )
+ {
+ bSomethingTested = TRUE;
+ return TRUE;
+ }
+
+ //--------------------------- XBM ------------------------------------
+ if( !bTest )
+ {
+ ULONG nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen;
+ BYTE* pBuf = new BYTE [ nSize ];
+
+ rStream.Seek( nStreamPos );
+ rStream.Read( pBuf, nSize );
+ BYTE* pPtr = ImplSearchEntry( pBuf, (BYTE*)"#define", nSize, 7 );
+
+ if( pPtr )
+ {
+ if( ImplSearchEntry( pPtr, (BYTE*)"_width", pBuf + nSize - pPtr, 6 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "XBM", 3 );
+ delete[] pBuf;
+ return TRUE;
+ }
+ }
+ delete[] pBuf;
+ }
+ else if( rFormatExtension.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL )
+ {
+ bSomethingTested = TRUE;
+ return TRUE;
+ }
+
+ //--------------------------- TGA ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+ if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL )
+ return TRUE;
+ }
+
+ //--------------------------- SGV ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = TRUE;
+ if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL )
+ return TRUE;
+ }
+
+ //--------------------------- SGF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=TRUE;
+ if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SGF", 3 );
+ return TRUE;
+ }
+ }
+
+ return bTest && !bSomethingTested;
+}
+
+//--------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat )
+{
+ sal_uInt16 n = pConfig->GetImportFormatCount();
+
+ // ggf. Filter bzw. Format durch anlesen ermitteln,
+ // oder durch anlesen zusichern, dass das Format stimmt:
+ if( rFormat == GRFILTER_FORMAT_DONTKNOW )
+ {
+ String aFormatExt;
+ if( ImpPeekGraphicFormat( rStream, aFormatExt, FALSE ) )
+ {
+ for( sal_uInt16 i = 0; i < n; i++ )
+ {
+ if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aFormatExt ) )
+ {
+ rFormat = i;
+ return GRFILTER_OK;
+ }
+ }
+ }
+ // ggf. Filter anhand der Datei-Endung raussuchen:
+ if( rPath.Len() )
+ {
+ String aExt( ImpGetExtension( rPath ) );
+ for( sal_uInt16 i = 0; i < n; i++ )
+ {
+ if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
+ {
+ rFormat = i;
+ return GRFILTER_OK;
+ }
+ }
+ }
+ return GRFILTER_FORMATERROR;
+ }
+ else
+ {
+ String aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
+ if( !ImpPeekGraphicFormat( rStream, aTmpStr, TRUE ) )
+ return GRFILTER_FORMATERROR;
+ if ( pConfig->GetImportFormatExtension( rFormat ).EqualsIgnoreCaseAscii( "pcd" ) )
+ {
+ sal_Int32 nBase = 2; // default Base0
+ if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) )
+ nBase = 1;
+ else if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) )
+ nBase = 0;
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
+ FilterConfigItem aFilterConfigItem( aFilterConfigPath );
+ aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
+ }
+ }
+
+ return GRFILTER_OK;
+}
+
+//--------------------------------------------------------------------------
+
+static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
+{
+ Graphic aGraphic;
+ ByteString aResMgrName( "svt", 3 );
+ ResMgr* pResMgr;
+
+ pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+
+ sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) ), 0 );
+ sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) ), 0 );
+
+ if ( rGraphic.GetType() != GRAPHIC_NONE )
+ {
+ sal_Int32 nMode = rConfigItem.ReadInt32( String( ResId( KEY_MODE, *pResMgr ) ), -1 );
+
+ if ( nMode == -1 ) // the property is not there, this is possible, if the graphic filter
+ { // is called via UnoGraphicExporter and not from a graphic export Dialog
+ nMode = 0; // then we are defaulting this mode to 0
+ if ( nLogicalWidth || nLogicalHeight )
+ nMode = 2;
+ }
+
+
+ Size aOriginalSize;
+ Size aPrefSize( rGraphic.GetPrefSize() );
+ MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
+ if ( aPrefMapMode == MAP_PIXEL )
+ aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
+ else
+ aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
+ if ( !nLogicalWidth )
+ nLogicalWidth = aOriginalSize.Width();
+ if ( !nLogicalHeight )
+ nLogicalHeight = aOriginalSize.Height();
+ if( rGraphic.GetType() == GRAPHIC_BITMAP )
+ {
+
+ // Aufloesung wird eingestellt
+ if( nMode == 1 )
+ {
+ Bitmap aBitmap( rGraphic.GetBitmap() );
+ MapMode aMap( MAP_100TH_INCH );
+
+ sal_Int32 nDPI = rConfigItem.ReadInt32( String( ResId( KEY_RES, *pResMgr ) ), 75 );
+ Fraction aFrac( 1, Min( Max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
+
+ aMap.SetScaleX( aFrac );
+ aMap.SetScaleY( aFrac );
+
+ Size aOldSize = aBitmap.GetSizePixel();
+ aBitmap.SetPrefMapMode( aMap );
+ aBitmap.SetPrefSize( Size( aOldSize.Width() * 100,
+ aOldSize.Height() * 100 ) );
+
+ aGraphic = Graphic( aBitmap );
+ }
+ // Groesse wird eingestellt
+ else if( nMode == 2 )
+ {
+ BitmapEx aBitmapEx( rGraphic.GetBitmapEx() );
+ aBitmapEx.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
+ aBitmapEx.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
+ aGraphic = Graphic( aBitmapEx );
+ }
+ else
+ aGraphic = rGraphic;
+
+ sal_Int32 nColors = rConfigItem.ReadInt32( String( ResId( KEY_COLORS, *pResMgr ) ), 0 ); // #92767#
+ if ( nColors ) // graphic conversion necessary ?
+ {
+ BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
+ aBmpEx.Convert( (BmpConversion)nColors ); // the entries in the xml section have the same meaning as
+ aGraphic = aBmpEx; // they have in the BmpConversion enum, so it should be
+ } // allowed to cast them
+ }
+ else
+ {
+ if( ( nMode == 1 ) || ( nMode == 2 ) )
+ {
+ GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
+ ::com::sun::star::awt::Size aDefaultSize( 10000, 10000 );
+ Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) );
+
+ if( aNewSize.Width() && aNewSize.Height() )
+ {
+ const Size aPreferredSize( aMtf.GetPrefSize() );
+ aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
+ Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
+ }
+ aGraphic = Graphic( aMtf );
+ }
+ else
+ aGraphic = rGraphic;
+ }
+
+ }
+ else
+ aGraphic = rGraphic;
+
+ delete pResMgr;
+
+ return aGraphic;
+}
+
+static String ImpCreateFullFilterPath( const String& rPath, const String& rFilterName )
+{
+ ::rtl::OUString aPathURL;
+
+ ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL );
+ aPathURL += String( '/' );
+
+ ::rtl::OUString aSystemPath;
+ ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
+ aSystemPath += ::rtl::OUString( rFilterName );
+
+ return String( aSystemPath );
+}
+
+
+// --------------------------
+// - ImpFilterLibCacheEntry -
+// --------------------------
+
+class ImpFilterLibCache;
+
+struct ImpFilterLibCacheEntry
+{
+ ImpFilterLibCacheEntry* mpNext;
+ osl::Module maLibrary;
+ String maFiltername;
+ PFilterCall mpfnImport;
+ PFilterDlgCall mpfnImportDlg;
+
+ ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername );
+ int operator==( const String& rFiltername ) const { return maFiltername == rFiltername; }
+
+ PFilterCall GetImportFunction();
+ PFilterDlgCall GetImportDlgFunction();
+ PFilterCall GetExportFunction() { return (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) ); }
+ PFilterDlgCall GetExportDlgFunction() { return (PFilterDlgCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) ); }
+};
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ) :
+ mpNext ( NULL ),
+ maLibrary ( rPathname ),
+ maFiltername ( rFiltername ),
+ mpfnImport ( NULL ),
+ mpfnImportDlg ( NULL )
+{
+}
+
+// ------------------------------------------------------------------------
+
+PFilterCall ImpFilterLibCacheEntry::GetImportFunction()
+{
+ if( !mpfnImport )
+ mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPORT_FUNCTION_NAME ) );
+
+ return mpfnImport;
+}
+
+// ------------------------------------------------------------------------
+
+PFilterDlgCall ImpFilterLibCacheEntry::GetImportDlgFunction()
+{
+ if( !mpfnImportDlg )
+ mpfnImportDlg = (PFilterDlgCall)maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPDLG_FUNCTION_NAME ) );
+
+ return mpfnImportDlg;
+}
+
+// ---------------------
+// - ImpFilterLibCache -
+// ---------------------
+
+class ImpFilterLibCache
+{
+ ImpFilterLibCacheEntry* mpFirst;
+ ImpFilterLibCacheEntry* mpLast;
+
+public:
+ ImpFilterLibCache();
+ ~ImpFilterLibCache();
+
+ ImpFilterLibCacheEntry* GetFilter( const String& rFilterPath, const String& rFiltername );
+};
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCache::ImpFilterLibCache() :
+ mpFirst ( NULL ),
+ mpLast ( NULL )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCache::~ImpFilterLibCache()
+{
+ ImpFilterLibCacheEntry* pEntry = mpFirst;
+ while( pEntry )
+ {
+ ImpFilterLibCacheEntry* pNext = pEntry->mpNext;
+ delete pEntry;
+ pEntry = pNext;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const String& rFilterPath, const String& rFilterName )
+{
+ ImpFilterLibCacheEntry* pEntry = mpFirst;
+
+ while( pEntry )
+ {
+ if( *pEntry == rFilterName )
+ break;
+ else
+ pEntry = pEntry->mpNext;
+ }
+ if( !pEntry )
+ {
+ String aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) );
+ pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName );
+
+ if ( pEntry->maLibrary.is() )
+ {
+ if( !mpFirst )
+ mpFirst = mpLast = pEntry;
+ else
+ mpLast = mpLast->mpNext = pEntry;
+ }
+ else
+ {
+ delete pEntry;
+ pEntry = NULL;
+ }
+ }
+ return pEntry;
+};
+
+// ------------------------------------------------------------------------
+
+namespace { struct Cache : public rtl::Static<ImpFilterLibCache, Cache> {}; }
+
+// -----------------
+// - GraphicFilter -
+// -----------------
+
+GraphicFilter::GraphicFilter( sal_Bool bConfig ) :
+ bUseConfig ( bConfig ),
+ nExpGraphHint ( 0 )
+{
+ ImplInit();
+}
+
+// ------------------------------------------------------------------------
+
+GraphicFilter::~GraphicFilter()
+{
+ {
+ ::osl::MutexGuard aGuard( getListMutex() );
+ pFilterHdlList->Remove( (void*)this );
+ if ( !pFilterHdlList->Count() )
+ {
+ delete pFilterHdlList, pFilterHdlList = NULL;
+ delete pConfig;
+ }
+ }
+
+
+ delete pErrorEx;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicFilter::ImplInit()
+{
+ {
+ ::osl::MutexGuard aGuard( getListMutex() );
+
+ if ( !pFilterHdlList )
+ {
+ pFilterHdlList = new List;
+ pConfig = new FilterConfigCache( bUseConfig );
+ }
+ else
+ pConfig = ((GraphicFilter*)pFilterHdlList->First())->pConfig;
+
+ pFilterHdlList->Insert( (void*)this );
+ }
+
+ if( bUseConfig )
+ {
+#if defined WNT
+ rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program"));
+#else
+ rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program"));
+#endif
+ rtl::Bootstrap::expandMacros(url); //TODO: detect failure
+ utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath);
+ }
+
+ pErrorEx = new FilterErrorEx;
+ bAbort = sal_False;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GraphicFilter::ImplSetError( ULONG nError, const SvStream* pStm )
+{
+ pErrorEx->nFilterError = nError;
+ pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE;
+ return nError;
+}
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetImportFormatCount()
+{
+ return pConfig->GetImportFormatCount();
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetImportFormatNumber( const String& rFormatName )
+{
+ return pConfig->GetImportFormatNumber( rFormatName );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetImportFormatNumberForMediaType( const String& rMediaType )
+{
+ return pConfig->GetImportFormatNumberForMediaType( rMediaType );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetImportFormatNumberForShortName( const String& rShortName )
+{
+ return pConfig->GetImportFormatNumberForShortName( rShortName );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const String& rType )
+{
+ return pConfig->GetImportFormatNumberForTypeName( rType );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatName( USHORT nFormat )
+{
+ return pConfig->GetImportFormatName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatTypeName( USHORT nFormat )
+{
+ return pConfig->GetImportFilterTypeName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatMediaType( USHORT nFormat )
+{
+ return pConfig->GetImportFormatMediaType( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatShortName( USHORT nFormat )
+{
+ return pConfig->GetImportFormatShortName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportOSFileType( USHORT )
+{
+ String aOSFileType;
+ return aOSFileType;
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportWildcard( USHORT nFormat, sal_Int32 nEntry )
+{
+ return pConfig->GetImportWildcard( nFormat, nEntry );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicFilter::IsImportPixelFormat( USHORT nFormat )
+{
+ return pConfig->IsImportPixelFormat( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetExportFormatCount()
+{
+ return pConfig->GetExportFormatCount();
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetExportFormatNumber( const String& rFormatName )
+{
+ return pConfig->GetExportFormatNumber( rFormatName );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetExportFormatNumberForMediaType( const String& rMediaType )
+{
+ return pConfig->GetExportFormatNumberForMediaType( rMediaType );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::GetExportFormatNumberForShortName( const String& rShortName )
+{
+ return pConfig->GetExportFormatNumberForShortName( rShortName );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const String& rType )
+{
+ return pConfig->GetExportFormatNumberForTypeName( rType );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatName( USHORT nFormat )
+{
+ return pConfig->GetExportFormatName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatTypeName( USHORT nFormat )
+{
+ return pConfig->GetExportFilterTypeName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatMediaType( USHORT nFormat )
+{
+ return pConfig->GetExportFormatMediaType( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatShortName( USHORT nFormat )
+{
+ return pConfig->GetExportFormatShortName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportOSFileType( USHORT )
+{
+ String aOSFileType;
+ return aOSFileType;
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportWildcard( USHORT nFormat, sal_Int32 nEntry )
+{
+ return pConfig->GetExportWildcard( nFormat, nEntry );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicFilter::IsExportPixelFormat( USHORT nFormat )
+{
+ return pConfig->IsExportPixelFormat( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::CanImportGraphic( const INetURLObject& rPath,
+ USHORT nFormat, USHORT* pDeterminedFormat )
+{
+ sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
+ DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
+
+ String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
+ if ( pStream )
+ {
+ nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat );
+ delete pStream;
+ }
+ return nRetValue;
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::CanImportGraphic( const String& rMainUrl, SvStream& rIStream,
+ USHORT nFormat, USHORT* pDeterminedFormat )
+{
+ ULONG nStreamPos = rIStream.Tell();
+ sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
+
+ rIStream.Seek(nStreamPos);
+
+ if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL )
+ *pDeterminedFormat = nFormat;
+
+ return (USHORT) ImplSetError( nRes, &rIStream );
+}
+
+// ------------------------------------------------------------------------
+//SJ: TODO, we need to create a GraphicImporter component
+USHORT GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
+ USHORT nFormat, USHORT * pDeterminedFormat, sal_uInt32 nImportFlags )
+{
+ sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
+ DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
+
+ String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
+ if ( pStream )
+ {
+ nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags );
+ delete pStream;
+ }
+ return nRetValue;
+}
+
+USHORT GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
+ USHORT nFormat, USHORT* pDeterminedFormat, sal_uInt32 nImportFlags )
+{
+ return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL );
+}
+
+//-------------------------------------------------------------------------
+
+USHORT GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
+ USHORT nFormat, USHORT* pDeterminedFormat, sal_uInt32 nImportFlags,
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData )
+{
+ String aFilterName;
+ ULONG nStmBegin;
+ USHORT nStatus;
+ GraphicReader* pContext = rGraphic.GetContext();
+ GfxLinkType eLinkType = GFX_LINK_TYPE_NONE;
+ BOOL bDummyContext = ( pContext == (GraphicReader*) 1 );
+ const BOOL bLinkSet = rGraphic.IsLink();
+ FilterConfigItem* pFilterConfigItem = NULL;
+
+ Size aPreviewSizeHint( 0, 0 );
+ sal_Bool bAllowPartialStreamRead = sal_False;
+ sal_Bool bCreateNativeLink = sal_True;
+
+ ResetLastError();
+
+ if ( pFilterData )
+ {
+ sal_Int32 i;
+ for ( i = 0; i < pFilterData->getLength(); i++ )
+ {
+ if ( (*pFilterData)[ i ].Name.equalsAscii( "PreviewSizeHint" ) )
+ {
+ awt::Size aSize;
+ if ( (*pFilterData)[ i ].Value >>= aSize )
+ {
+ aPreviewSizeHint = Size( aSize.Width, aSize.Height );
+ if ( aSize.Width || aSize.Height )
+ nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW;
+ else
+ nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW;
+ }
+ }
+ else if ( (*pFilterData)[ i ].Name.equalsAscii( "AllowPartialStreamRead" ) )
+ {
+ (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead;
+ if ( bAllowPartialStreamRead )
+ nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
+ else
+ nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
+ }
+ else if ( (*pFilterData)[ i ].Name.equalsAscii( "CreateNativeLink" ) )
+ {
+ (*pFilterData)[ i ].Value >>= bCreateNativeLink;
+ }
+ }
+ }
+
+ if( !pContext || bDummyContext )
+ {
+ if( bDummyContext )
+ {
+ rGraphic.SetContext( NULL );
+ nStmBegin = 0;
+ }
+ else
+ nStmBegin = rIStream.Tell();
+
+ bAbort = FALSE;
+ nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
+ // Falls Pending, geben wir GRFILTER_OK zurueck,
+ // um mehr Bytes anzufordern
+ if( rIStream.GetError() == ERRCODE_IO_PENDING )
+ {
+ rGraphic.SetContext( (GraphicReader*) 1 );
+ rIStream.ResetError();
+ rIStream.Seek( nStmBegin );
+ return (USHORT) ImplSetError( GRFILTER_OK );
+ }
+
+ rIStream.Seek( nStmBegin );
+
+ if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() )
+ return (USHORT) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream );
+
+ if( pDeterminedFormat )
+ *pDeterminedFormat = nFormat;
+
+ aFilterName = pConfig->GetImportFilterName( nFormat );
+ }
+ else
+ {
+ if( pContext && !bDummyContext )
+ aFilterName = pContext->GetUpperFilterName();
+
+ nStmBegin = 0;
+ nStatus = GRFILTER_OK;
+ }
+
+ // read graphic
+ if ( pConfig->IsImportInternalFilter( nFormat ) )
+ {
+ if( aFilterName.EqualsIgnoreCaseAscii( IMP_GIF ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ if( !ImportGIF( rIStream, rGraphic ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ eLinkType = GFX_LINK_TYPE_NATIVE_GIF;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_PNG ) )
+ {
+ if ( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ vcl::PNGReader aPNGReader( rIStream );
+
+ // ignore animation for previews and set preview size
+ if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() )
+ {
+ // position the stream at the end of the image if requested
+ if( !bAllowPartialStreamRead )
+ aPNGReader.GetChunks();
+ }
+ else
+ {
+ // check if this PNG contains a GIF chunk!
+ const std::vector< vcl::PNGReader::ChunkData >& rChunkData = aPNGReader.GetChunks();
+ std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() );
+ std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() );
+ while( aIter != aEnd )
+ {
+ // Microsoft Office is storing Animated GIFs in following chunk
+ if ( aIter->nType == PMGCHUNG_msOG )
+ {
+ sal_uInt32 nChunkSize = aIter->aData.size();
+ if ( nChunkSize > 11 )
+ {
+ const std::vector< sal_uInt8 >& rData = aIter->aData;
+ SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ );
+ ImportGIF( aIStrm, rGraphic );
+ eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
+ break;
+ }
+ }
+ aIter++;
+ }
+ }
+
+ if ( eLinkType == GFX_LINK_TYPE_NONE )
+ {
+ BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) );
+ if ( aBmpEx.IsEmpty() )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ rGraphic = aBmpEx;
+ eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
+ }
+ }
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_JPEG ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ // set LOGSIZE flag always, if not explicitly disabled
+ // (see #90508 and #106763)
+ if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) )
+ nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
+
+ if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ eLinkType = GFX_LINK_TYPE_NATIVE_JPG;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ if( !ImportXBM( rIStream, rGraphic ) )
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XPM ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ if( !ImportXPM( rIStream, rGraphic ) )
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP ) ||
+ aFilterName.EqualsIgnoreCaseAscii( IMP_SVMETAFILE ) )
+ {
+ // SV interne Importfilter fuer Bitmaps und MetaFiles
+ rIStream >> rGraphic;
+ if( rIStream.GetError() )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_WMF ) ||
+ aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) )
+ {
+ GDIMetaFile aMtf;
+ if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL ) )
+ nStatus = GRFILTER_FORMATERROR;
+ else
+ {
+ rGraphic = aMtf;
+ eLinkType = GFX_LINK_TYPE_NATIVE_WMF;
+ }
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGF )
+ || aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGV ) )
+ {
+ USHORT nVersion;
+ unsigned char nTyp = CheckSgfTyp( rIStream, nVersion );
+
+ switch( nTyp )
+ {
+ case SGF_BITIMAGE:
+ {
+ SvMemoryStream aTempStream;
+ if( aTempStream.GetError() )
+ return GRFILTER_OPENERROR;
+
+ if( !SgfBMapFilter( rIStream, aTempStream ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ aTempStream.Seek( 0L );
+ aTempStream >> rGraphic;
+
+ if( aTempStream.GetError() )
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ break;
+
+ case SGF_SIMPVECT:
+ {
+ GDIMetaFile aMtf;
+ if( !SgfVectFilter( rIStream, aMtf ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ rGraphic = Graphic( aMtf );
+ }
+ break;
+
+ case SGF_STARDRAW:
+ {
+ if( nVersion != SGV_VERSION )
+ nStatus = GRFILTER_VERSIONERROR;
+ else
+ {
+ GDIMetaFile aMtf;
+ if( !SgfSDrwFilter( rIStream, aMtf,
+ INetURLObject(aFilterPath) ) )
+ {
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else
+ rGraphic = Graphic( aMtf );
+ }
+ }
+ break;
+
+ default:
+ {
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ break;
+ }
+ }
+ else
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else
+ {
+ ImpFilterLibCacheEntry* pFilter = NULL;
+
+ // find first filter in filter pathes
+ xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
+ ImpFilterLibCache &rCache = Cache::get();
+ for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ )
+ pFilter = rCache.GetFilter( aFilterPath.GetToken(i), aFilterName );
+ if( !pFilter )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ PFilterCall pFunc = pFilter->GetImportFunction();
+
+ if( !pFunc )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ String aShortName;
+ if( nFormat != GRFILTER_FORMAT_DONTKNOW )
+ {
+ aShortName = GetImportFormatShortName( nFormat ).ToUpperAscii();
+ if ( ( pFilterConfigItem == NULL ) && aShortName.EqualsAscii( "PCD" ) )
+ {
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
+ pFilterConfigItem = new FilterConfigItem( aFilterConfigPath );
+ }
+ }
+ if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem, sal_False ) )
+ nStatus = GRFILTER_FORMATERROR;
+ else
+ {
+ // try to set link type if format matches
+ if( nFormat != GRFILTER_FORMAT_DONTKNOW )
+ {
+ if( aShortName.CompareToAscii( TIF_SHORTNAME ) == COMPARE_EQUAL )
+ eLinkType = GFX_LINK_TYPE_NATIVE_TIF;
+ else if( aShortName.CompareToAscii( MET_SHORTNAME ) == COMPARE_EQUAL )
+ eLinkType = GFX_LINK_TYPE_NATIVE_MET;
+ else if( aShortName.CompareToAscii( PCT_SHORTNAME ) == COMPARE_EQUAL )
+ eLinkType = GFX_LINK_TYPE_NATIVE_PCT;
+ }
+ }
+ }
+ }
+ }
+
+ if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet )
+ {
+ const ULONG nStmEnd = rIStream.Tell();
+ const ULONG nBufSize = nStmEnd - nStmBegin;
+
+ if( nBufSize )
+ {
+ BYTE* pBuf=0;
+ try
+ {
+ pBuf = new BYTE[ nBufSize ];
+ }
+ catch (std::bad_alloc)
+ {
+ nStatus = GRFILTER_TOOBIG;
+ }
+
+ if( nStatus == GRFILTER_OK )
+ {
+ rIStream.Seek( nStmBegin );
+ rIStream.Read( pBuf, nBufSize );
+ rGraphic.SetLink( GfxLink( pBuf, nBufSize, eLinkType, TRUE ) );
+ }
+ }
+ }
+
+ // Set error code or try to set native buffer
+ if( nStatus != GRFILTER_OK )
+ {
+ if( bAbort )
+ nStatus = GRFILTER_ABORT;
+
+ ImplSetError( nStatus, &rIStream );
+ rIStream.Seek( nStmBegin );
+ rGraphic.Clear();
+ }
+
+ delete pFilterConfigItem;
+ return nStatus;
+}
+
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
+ sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
+{
+ sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
+ DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
+ BOOL bAlreadyExists = ImplDirEntryHelper::Exists( rPath );
+
+ String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC );
+ if ( pStream )
+ {
+ nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData );
+ delete pStream;
+
+ if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists )
+ ImplDirEntryHelper::Kill( aMainUrl );
+ }
+ return nRetValue;
+}
+
+// ------------------------------------------------------------------------
+
+USHORT GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& rPath,
+ SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
+{
+ USHORT nFormatCount = GetExportFormatCount();
+
+ ResetLastError();
+ nExpGraphHint = 0;
+
+ if( nFormat == GRFILTER_FORMAT_DONTKNOW )
+ {
+ INetURLObject aURL( rPath );
+ String aExt( aURL.GetFileExtension().toAsciiUpperCase() );
+
+
+ for( USHORT i = 0; i < nFormatCount; i++ )
+ {
+ if ( pConfig->GetExportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
+ {
+ nFormat=i;
+ break;
+ }
+ }
+ }
+ if( nFormat >= nFormatCount )
+ return (USHORT) ImplSetError( GRFILTER_FORMATERROR );
+
+ FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
+ String aFilterName( pConfig->GetExportFilterName( nFormat ) );
+
+ bAbort = FALSE;
+ USHORT nStatus = GRFILTER_OK;
+ GraphicType eType;
+ Graphic aGraphic( rGraphic );
+
+ aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
+ eType = aGraphic.GetType();
+
+ if( pConfig->IsExportPixelFormat( nFormat ) )
+ {
+ if( eType != GRAPHIC_BITMAP )
+ {
+ Size aSizePixel;
+ ULONG nColorCount,nBitsPerPixel,nNeededMem,nMaxMem;
+ VirtualDevice aVirDev;
+
+ // Maximalen Speicherbedarf fuer das Bildes holen:
+// if( GetOptionsConfig() )
+// nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32();
+// else
+ nMaxMem = 1024;
+
+ nMaxMem *= 1024; // In Bytes
+
+ // Berechnen, wie gross das Bild normalerweise werden wuerde:
+ aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
+
+ // Berechnen, wieviel Speicher das Bild benoetigen wuerde:
+ nColorCount=aVirDev.GetColorCount();
+ if (nColorCount<=2) nBitsPerPixel=1;
+ else if (nColorCount<=4) nBitsPerPixel=2;
+ else if (nColorCount<=16) nBitsPerPixel=4;
+ else if (nColorCount<=256) nBitsPerPixel=8;
+ else if (nColorCount<=65536) nBitsPerPixel=16;
+ else nBitsPerPixel=24;
+ nNeededMem=((ULONG)aSizePixel.Width()*(ULONG)aSizePixel.Height()*nBitsPerPixel+7)/8;
+
+ // ggf. Groesse des Bildes einschraenken:
+ if (nMaxMem<nNeededMem)
+ {
+ double fFak=sqrt(((double)nMaxMem)/((double)nNeededMem));
+ aSizePixel.Width()=(ULONG)(((double)aSizePixel.Width())*fFak);
+ aSizePixel.Height()=(ULONG)(((double)aSizePixel.Height())*fFak);
+ }
+
+ aVirDev.SetMapMode(MapMode(MAP_PIXEL));
+ aVirDev.SetOutputSizePixel(aSizePixel);
+ Graphic aGraphic2=aGraphic;
+ aGraphic2.Draw(&aVirDev,Point(0,0),aSizePixel); // Gemein: dies aendert den MapMode
+ aVirDev.SetMapMode(MapMode(MAP_PIXEL));
+ aGraphic=Graphic(aVirDev.GetBitmap(Point(0,0),aSizePixel));
+ }
+ }
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ if( GRFILTER_OK == nStatus )
+ {
+ if ( pConfig->IsExportInternalFilter( nFormat ) )
+ {
+ if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
+ {
+ Bitmap aBmp( aGraphic.GetBitmap() );
+ sal_Int32 nColorRes = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Colors" ) ), 0 );
+ if ( nColorRes && ( nColorRes <= (USHORT)BMP_CONVERSION_24BIT) )
+ {
+ if( !aBmp.Convert( (BmpConversion) nColorRes ) )
+ aBmp = aGraphic.GetBitmap();
+ }
+ ResMgr* pResMgr = CREATERESMGR( svt );
+ sal_Bool bRleCoding = aConfigItem.ReadBool( String( ResId( KEY_RLE_CODING, *pResMgr ) ), sal_True );
+ // Wollen wir RLE-Kodiert speichern?
+ aBmp.Write( rOStm, bRleCoding );
+ delete pResMgr;
+
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) )
+ {
+ sal_Int32 nVersion = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), 0 ) ;
+ if ( nVersion )
+ rOStm.SetVersion( nVersion );
+ GDIMetaFile aMTF;
+
+ if ( eType != GRAPHIC_BITMAP )
+ aMTF = aGraphic.GetGDIMetaFile();
+ else
+ {
+ VirtualDevice aVirDev;
+
+ aMTF.Record( &aVirDev );
+ aGraphic.Draw( &aVirDev, Point(), aGraphic.GetPrefSize() );
+ aMTF.Stop();
+ aMTF.SetPrefSize( aGraphic.GetPrefSize() );
+ aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() );
+ }
+ rOStm << aMTF;
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) )
+ {
+ if( eType == GRAPHIC_GDIMETAFILE )
+ {
+ if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ else
+ {
+ Bitmap aBmp( aGraphic.GetBitmap() );
+ GDIMetaFile aMTF;
+ VirtualDevice aVirDev;
+
+ aMTF.Record( &aVirDev );
+ aVirDev.DrawBitmap( Point(), aBmp );
+ aMTF.Stop();
+ aMTF.SetPrefSize( aBmp.GetSizePixel() );
+
+ if( !ConvertGDIMetaFileToWMF( aMTF, rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) )
+ {
+ if( eType == GRAPHIC_GDIMETAFILE )
+ {
+ if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ else
+ {
+ Bitmap aBmp( aGraphic.GetBitmap() );
+ GDIMetaFile aMTF;
+ VirtualDevice aVirDev;
+
+ aMTF.Record( &aVirDev );
+ aVirDev.DrawBitmap( Point(), aBmp );
+ aMTF.Stop();
+ aMTF.SetPrefSize( aBmp.GetSizePixel() );
+
+ if( !ConvertGDIMetaFileToEMF( aMTF, rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
+ {
+ bool bExportedGrayJPEG = false;
+ if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) )
+ nStatus = GRFILTER_FORMATERROR;
+ nExpGraphHint = bExportedGrayJPEG ? GRFILTER_OUTHINT_GREY : 0;
+
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
+ {
+ vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
+ if ( pFilterData )
+ {
+ sal_Int32 k, j, i = 0;
+ for ( i = 0; i < pFilterData->getLength(); i++ )
+ {
+ if ( (*pFilterData)[ i ].Name.equalsAscii( "AdditionalChunks" ) )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence;
+ if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence )
+ {
+ for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ )
+ {
+ if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 )
+ {
+ sal_uInt32 nChunkType = 0;
+ for ( k = 0; k < 4; k++ )
+ {
+ nChunkType <<= 8;
+ nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ];
+ }
+ com::sun::star::uno::Sequence< sal_Int8 > aByteSeq;
+ if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq )
+ {
+ std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
+ if ( rChunkData.size() )
+ {
+ sal_uInt32 nChunkLen = aByteSeq.getLength();
+
+ vcl::PNGWriter::ChunkData aChunkData;
+ aChunkData.nType = nChunkType;
+ if ( nChunkLen )
+ {
+ aChunkData.aData.resize( nChunkLen );
+ rtl_copyMemory( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen );
+ }
+ std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
+ rChunkData.insert( aIter, aChunkData );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ aPNGWriter.Write( rOStm );
+
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) )
+ {
+ try
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
+
+ if( xMgr.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xSaxWriter.is() && xSVGWriter.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource(
+ xSaxWriter, ::com::sun::star::uno::UNO_QUERY );
+
+ if( xActiveDataSource.is() )
+ {
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf(
+ static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
+
+ SvMemoryStream aMemStm( 65535, 65535 );
+
+ aMemStm.SetCompressMode( COMPRESSMODE_FULL );
+ ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm );
+
+ xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >(
+ xStmIf, ::com::sun::star::uno::UNO_QUERY ) );
+ ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() );
+ xSVGWriter->write( xSaxWriter, aMtfSeq );
+ }
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ nStatus = GRFILTER_IOERROR;
+ }
+ }
+ else
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else
+ {
+ xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
+ for ( i = 0; i < nTokenCount; i++ )
+ {
+ String aPhysicalName( ImpCreateFullFilterPath( aFilterPath.GetToken( i ), aFilterName ) );
+ osl::Module aLibrary( aPhysicalName );
+
+ PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) );
+ // Dialog in DLL ausfuehren
+ if( pFunc )
+ {
+ if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem, sal_False ) )
+ nStatus = GRFILTER_FORMATERROR;
+ break;
+ }
+ else
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ }
+ if( nStatus != GRFILTER_OK )
+ {
+ if( bAbort )
+ nStatus = GRFILTER_ABORT;
+
+ ImplSetError( nStatus, &rOStm );
+ }
+ return nStatus;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicFilter::Setup( USHORT )
+{
+ return FALSE;
+}
+
+/* ------------------------------------------------------------------------
+ No Import filter has a dialog, so
+ the following two methods are obsolete */
+
+BOOL GraphicFilter::HasImportDialog( USHORT )
+{
+ return sal_True;
+// return pConfig->IsImportDialog( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicFilter::DoImportDialog( Window*, USHORT )
+{
+ return sal_True;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicFilter::HasExportDialog( USHORT nFormat )
+{
+ return pConfig->IsExportDialog( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicFilter::DoExportDialog( Window* pWindow, USHORT nFormat )
+{
+ return DoExportDialog( pWindow, nFormat, FUNIT_MM );
+}
+
+BOOL GraphicFilter::DoExportDialog( Window*, USHORT nFormat, FieldUnit )
+{
+ sal_Bool bRet = sal_False;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xSMgr( ::comphelper::getProcessServiceFactory() );
+
+ uno::Reference< com::sun::star::uno::XInterface > xFilterOptionsDialog
+ ( xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.svtools.SvFilterOptionsDialog" ) ),
+ com::sun::star::uno::UNO_QUERY );
+ if ( xFilterOptionsDialog.is() )
+ {
+ com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XExecutableDialog > xExecutableDialog
+ ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xPropertyAccess
+ ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
+ if ( xExecutableDialog.is() && xPropertyAccess.is() )
+ {
+ com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aMediaDescriptor( 1 );
+ aMediaDescriptor[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ rtl::OUString aStr( pConfig->GetExportInternalFilterName( nFormat ) );
+ aMediaDescriptor[ 0 ].Value <<= aStr;
+ xPropertyAccess->setPropertyValues( aMediaDescriptor );
+ bRet = xExecutableDialog->execute() == com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
+ }
+ }
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+const FilterErrorEx& GraphicFilter::GetLastError() const
+{
+ return *pErrorEx;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicFilter::ResetLastError()
+{
+ pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL;
+}
+
+// ------------------------------------------------------------------------
+
+const Link GraphicFilter::GetFilterCallback() const
+{
+ const Link aLink( LINK( this, GraphicFilter, FilterCallback ) );
+ return aLink;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData )
+{
+ long nRet = 0L;
+
+ if( pData )
+ {
+ USHORT nFormat = GRFILTER_FORMAT_DONTKNOW;
+ ByteString aShortName;
+ switch( pData->mnFormat )
+ {
+ case( CVT_BMP ): aShortName = BMP_SHORTNAME; break;
+ case( CVT_GIF ): aShortName = GIF_SHORTNAME; break;
+ case( CVT_JPG ): aShortName = JPG_SHORTNAME; break;
+ case( CVT_MET ): aShortName = MET_SHORTNAME; break;
+ case( CVT_PCT ): aShortName = PCT_SHORTNAME; break;
+ case( CVT_PNG ): aShortName = PNG_SHORTNAME; break;
+ case( CVT_SVM ): aShortName = SVM_SHORTNAME; break;
+ case( CVT_TIF ): aShortName = TIF_SHORTNAME; break;
+ case( CVT_WMF ): aShortName = WMF_SHORTNAME; break;
+ case( CVT_EMF ): aShortName = EMF_SHORTNAME; break;
+
+ default:
+ break;
+ }
+ if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import
+ {
+ // Import
+ nFormat = GetImportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
+ nRet = ImportGraphic( pData->maGraphic, String(), pData->mrStm ) == 0;
+ }
+ else if( aShortName.Len() )
+ {
+ // Export
+ nFormat = GetExportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
+ nRet = ExportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0;
+ }
+ }
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+GraphicFilter* GraphicFilter::GetGraphicFilter()
+{
+ if( !pGraphicFilter )
+ {
+ pGraphicFilter = new GraphicFilter;
+ pGraphicFilter->GetImportFormatCount();
+ }
+ return pGraphicFilter;
+}
+
+int GraphicFilter::LoadGraphic( const String &rPath, const String &rFilterName,
+ Graphic& rGraphic, GraphicFilter* pFilter,
+ USHORT* pDeterminedFormat )
+{
+ if ( !pFilter )
+ pFilter = GetGraphicFilter();
+
+ const USHORT nFilter = rFilterName.Len() && pFilter->GetImportFormatCount()
+ ? pFilter->GetImportFormatNumber( rFilterName )
+ : GRFILTER_FORMAT_DONTKNOW;
+
+ SvStream* pStream = NULL;
+ INetURLObject aURL( rPath );
+
+ if ( aURL.HasError() || INET_PROT_NOT_VALID == aURL.GetProtocol() )
+ {
+ aURL.SetSmartProtocol( INET_PROT_FILE );
+ aURL.SetSmartURL( rPath );
+ }
+ else if ( INET_PROT_FILE != aURL.GetProtocol() )
+ {
+ pStream = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
+ }
+
+ int nRes = GRFILTER_OK;
+ if ( !pStream )
+ nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat );
+ else
+ nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat );
+
+#ifdef DBG_UTIL
+ if( nRes )
+ DBG_WARNING2( "GrafikFehler [%d] - [%s]", nRes, rPath.GetBuffer() );
+#endif
+
+ return nRes;
+}
+
diff --git a/svtools/source/filter.vcl/filter/filter2.cxx b/svtools/source/filter.vcl/filter/filter2.cxx
new file mode 100644
index 000000000000..de2bef64ba6e
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/filter2.cxx
@@ -0,0 +1,1419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <string.h>
+#include <stdio.h>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <vcl/outdev.hxx>
+#include <tools/config.hxx>
+#include <svtools/filter.hxx>
+#include "FilterConfigCache.hxx"
+#include <unotools/ucbstreamhelper.hxx>
+
+#define DATA_SIZE 640
+
+BYTE* ImplSearchEntry( BYTE* , BYTE* , ULONG , ULONG );
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+GraphicDescriptor::GraphicDescriptor( const String* pPath ) :
+ pFileStm ( NULL )
+{
+ ImpConstruct();
+
+ if ( pPath )
+ {
+ INetURLObject aURL( *pPath, INET_PROT_FILE );
+ aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
+ }
+ bLinked = TRUE;
+ bLinkChanged = FALSE;
+ bWideSearch = FALSE;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
+ pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ) ),
+ aPathExt( rPath.GetFileExtension().toAsciiLowerCase() )
+{
+ if ( pFileStm )
+ {
+ nStmPos = 0;
+ pFileStm->Seek( nStmPos );
+ bDataReady = TRUE;
+ }
+
+ ImpConstruct();
+
+ if ( pFileStm && !pFileStm->GetError() )
+ bDataReady = TRUE;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) :
+ pFileStm ( NULL )
+{
+ ImpConstruct();
+
+ if ( pPath )
+ {
+ INetURLObject aURL( *pPath );
+ aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
+ }
+ nStmPos = rInStream.Tell();
+ pBaseStm = &rInStream;
+ bBaseStm = TRUE;
+
+ if ( !pBaseStm->GetError() )
+ bDataReady = TRUE;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+GraphicDescriptor::~GraphicDescriptor()
+{
+ delete pFileStm;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::Detect( BOOL bExtendedInfo )
+{
+ BOOL bRet = FALSE;
+
+ // Link-Status ueberpruefen
+ if ( bLinked && bLinkChanged )
+ {
+ DBG_ASSERT( aReqLink.IsSet(), "Wo ist der RequestHandler???" );
+ pMemStm = (SvStream*) aReqLink.Call( this );
+ if ( pMemStm )
+ {
+ nStmPos = pMemStm->Tell();
+ bDataReady = TRUE;
+ }
+ }
+
+ if ( bDataReady )
+ {
+ SvStream& rStm = GetSearchStream();
+ UINT16 nOldFormat = rStm.GetNumberFormatInt();
+
+ if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPCX( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectDXF( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectMET( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectSGF( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectSGV( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPBM( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPGM( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPPM( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectRAS( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = TRUE;
+ else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = TRUE;
+
+ // diese Formate lassen sich nur bei WideSearch im gesamten
+ // Stream ermitteln
+ else if ( bWideSearch )
+ {
+ if ( ImpDetectPCD( rStm, bExtendedInfo ) )
+ bRet = TRUE;
+ }
+
+ rStm.SetNumberFormatInt( nOldFormat );
+ rStm.Seek( nStmPos );
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::IsDataReady() const
+{
+ return bDataReady;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::IsWideSearch() const
+{
+ return bWideSearch;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+SvStream& GraphicDescriptor::GetSearchStream() const
+{
+ DBG_ASSERT( bDataReady, "Was laeuft hier falsch???" );
+
+ if ( bLinked )
+ return *pMemStm;
+ else if ( bBaseStm )
+ return *pBaseStm;
+ else
+ return *pFileStm;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+void GraphicDescriptor::SetRequestHdl( const Link& rRequestLink )
+{
+ aReqLink = rRequestLink;
+ bLinkChanged = TRUE;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+ULONG GraphicDescriptor::GetRequestedByteCount() const
+{
+ return DATA_SIZE;
+}
+
+
+/******************************************************************************/
+/* IMP-Methoden */
+/* */
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+void GraphicDescriptor::ImpConstruct()
+{
+ if ( !pFileStm )
+ pFileStm = new SvStream();
+ nFormat = GFF_NOT;
+ nBitsPerPixel = 0;
+ nPlanes = 0;
+ bCompressed = FALSE;
+ bDataReady = FALSE;
+ bLinked = FALSE;
+ bWideSearch = TRUE;
+ bBaseStm = FALSE;
+ pMemStm = NULL;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectBMP( SvStream& rStm, BOOL bExtendedInfo )
+{
+ UINT16 nTemp16;
+ BOOL bRet = FALSE;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStm.Seek( nStmPos );
+
+ rStm >> nTemp16;
+
+ // OS/2-BitmapArray
+ if ( nTemp16 == 0x4142 )
+ {
+ rStm.SeekRel( 0x0c );
+ rStm >> nTemp16;
+ }
+
+ // Bitmap
+ if ( nTemp16 == 0x4d42 )
+ {
+ nFormat = GFF_BMP;
+ bRet = TRUE;
+
+ if ( bExtendedInfo )
+ {
+ UINT32 nTemp32;
+ UINT32 nCompression;
+
+ // bis zur ersten Information
+ rStm.SeekRel( 0x10 );
+
+ // PixelBreite auslesen
+ rStm >> nTemp32;
+ aPixSize.Width() = nTemp32;
+
+ // PixelHoehe auslesen
+ rStm >> nTemp32;
+ aPixSize.Height() = nTemp32;
+
+ // Planes auslesen
+ rStm >> nTemp16;
+ nPlanes = nTemp16;
+
+ // BitCount auslesen
+ rStm >> nTemp16;
+ nBitsPerPixel = nTemp16;
+
+ // Compression auslesen
+ rStm >> nTemp32;
+ bCompressed = ( ( nCompression = nTemp32 ) > 0 );
+
+ // logische Breite
+ rStm.SeekRel( 4 );
+ rStm >> nTemp32;
+ if ( nTemp32 )
+ aLogSize.Width() = ( aPixSize.Width() * 100000 ) / nTemp32;
+
+ // logische Hoehe
+ rStm >> nTemp32;
+ if ( nTemp32 )
+ aLogSize.Height() = ( aPixSize.Height() * 100000 ) / nTemp32;
+
+ // Wir wollen noch etwas feiner differenzieren und
+ // auf sinnvolle Werte ueberpruefen ( Bug-Id #29001 )
+ if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
+ {
+ nFormat = GFF_NOT;
+ bRet = FALSE;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectGIF( SvStream& rStm, BOOL bExtendedInfo )
+{
+ UINT32 n32;
+ UINT16 n16;
+ BOOL bRet = FALSE;
+ BYTE cByte;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStm.Seek( nStmPos );
+
+ rStm >> n32;
+ if ( n32 == 0x38464947 )
+ {
+ rStm >> n16;
+ if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
+ {
+ nFormat = GFF_GIF;
+ bRet = TRUE;
+
+ if ( bExtendedInfo )
+ {
+ UINT16 nTemp16;
+
+ // PixelBreite auslesen
+ rStm >> nTemp16;
+ aPixSize.Width() = nTemp16;
+
+ // PixelHoehe auslesen
+ rStm >> nTemp16;
+ aPixSize.Height() = nTemp16;
+
+ // Bits/Pixel auslesen
+ rStm >> cByte;
+ nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectJPG( SvStream& rStm, BOOL bExtendedInfo )
+{
+ UINT32 nTemp32;
+ BOOL bRet = FALSE;
+ BYTE cByte = 0;
+ BOOL bM_COM;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStm.Seek( nStmPos );
+
+ rStm >> nTemp32;
+
+ // compare upper 28 bits
+ if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
+ {
+ nFormat = GFF_JPG;
+ return TRUE;
+ }
+
+ bM_COM = ( nTemp32 == 0xffd8fffe );
+ if ( ( nTemp32 == 0xffd8ffe0 ) || bM_COM )
+ {
+ if( !bM_COM )
+ {
+ rStm.SeekRel( 2 );
+ rStm >> nTemp32;
+ }
+
+ if( bM_COM || ( nTemp32 == 0x4a464946 ) )
+ {
+ nFormat = GFF_JPG;
+ bRet = TRUE;
+
+ if( bExtendedInfo )
+ {
+ MapMode aMap;
+ UINT16 nTemp16;
+ ULONG nCount = 9;
+ ULONG nMax;
+ ULONG nResX;
+ ULONG nResY;
+ BYTE cUnit;
+
+ // Groesse des verbleibenden Puffers ermitteln
+ if ( bLinked )
+ nMax = static_cast< SvMemoryStream& >(rStm).GetEndOfData()
+ - 16;
+ else
+ nMax = DATA_SIZE - 16;
+
+ // max. 8K
+ nMax = Min( nMax, (ULONG) 8192 );
+
+ // Res-Unit ermitteln
+ rStm.SeekRel( 3 );
+ rStm >> cUnit;
+
+ // ResX ermitteln
+ rStm >> nTemp16;
+ nResX = nTemp16;
+
+ // ResY ermitteln
+ rStm >> nTemp16;
+ nResY = nTemp16;
+
+ // SOF0/1-Marker finden, aber dabei
+ // nicht mehr als DATA_SIZE Pixel lesen, falls
+ // kein WideSearch
+ do
+ {
+ while ( ( cByte != 0xff ) &&
+ ( bWideSearch || ( nCount++ < nMax ) ) )
+ {
+ rStm >> cByte;
+ }
+
+ while ( ( cByte == 0xff ) &&
+ ( bWideSearch || ( nCount++ < nMax ) ) )
+ {
+ rStm >> cByte;
+ }
+ }
+ while ( ( cByte != 0xc0 ) &&
+ ( cByte != 0xc1 ) &&
+ ( bWideSearch || ( nCount < nMax ) ) );
+
+ // wir haben den SOF0/1-Marker
+ if ( ( cByte == 0xc0 ) || ( cByte == 0xc1 ) )
+ {
+ // Hoehe einlesen
+ rStm.SeekRel( 3 );
+ rStm >> nTemp16;
+ aPixSize.Height() = nTemp16;
+
+ // Breite einlesen
+ rStm >> nTemp16;
+ aPixSize.Width() = nTemp16;
+
+ // Bit/Pixel einlesen
+ rStm >> cByte;
+ nBitsPerPixel = ( cByte == 3 ? 24 : cByte == 1 ? 8 : 0 );
+
+ // logische Groesse setzen
+ if ( cUnit && nResX && nResY )
+ {
+ aMap.SetMapUnit( cUnit == 1 ? MAP_INCH : MAP_CM );
+ aMap.SetScaleX( Fraction( 1, nResX ) );
+ aMap.SetScaleY( Fraction( 1, nResY ) );
+ aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
+ MapMode( MAP_100TH_MM ) );
+ }
+
+ // Planes immer 1
+ nPlanes = 1;
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPCD( SvStream& rStm, BOOL )
+{
+ BOOL bRet = FALSE;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStm.Seek( nStmPos );
+
+ if ( bWideSearch )
+ {
+ UINT32 nTemp32;
+ UINT16 nTemp16;
+ BYTE cByte;
+
+ rStm.SeekRel( 2048 );
+ rStm >> nTemp32;
+ rStm >> nTemp16;
+ rStm >> cByte;
+
+ if ( ( nTemp32 == 0x5f444350 ) &&
+ ( nTemp16 == 0x5049 ) &&
+ ( cByte == 0x49 ) )
+ {
+ nFormat = GFF_PCD;
+ bRet = TRUE;
+ }
+ }
+ else
+ {
+ bRet = aPathExt.CompareToAscii( "pcd", 3 ) == COMPARE_EQUAL;
+ if ( bRet )
+ {
+ nFormat = GFF_PCD;
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPCX( SvStream& rStm, BOOL bExtendedInfo )
+{
+ // ! Because 0x0a can be interpreted as LF too ...
+ // we cant be shure that this special sign represent a PCX file only.
+ // Every Ascii file is possible here :-(
+ // We must detect the whole header.
+ bExtendedInfo = TRUE;
+
+ BOOL bRet = FALSE;
+ BYTE cByte;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStm.Seek( nStmPos );
+
+ rStm >> cByte;
+ if ( cByte == 0x0a )
+ {
+ nFormat = GFF_PCX;
+ bRet = TRUE;
+
+ if ( bExtendedInfo )
+ {
+ UINT16 nTemp16;
+ USHORT nXmin;
+ USHORT nXmax;
+ USHORT nYmin;
+ USHORT nYmax;
+ USHORT nDPIx;
+ USHORT nDPIy;
+
+
+ rStm.SeekRel( 1 );
+
+ // Kompression lesen
+ rStm >> cByte;
+ bCompressed = ( cByte > 0 );
+
+ bRet = (cByte==0 || cByte ==1);
+
+ // Bits/Pixel lesen
+ rStm >> cByte;
+ nBitsPerPixel = cByte;
+
+ // Bildabmessungen
+ rStm >> nTemp16;
+ nXmin = nTemp16;
+ rStm >> nTemp16;
+ nYmin = nTemp16;
+ rStm >> nTemp16;
+ nXmax = nTemp16;
+ rStm >> nTemp16;
+ nYmax = nTemp16;
+
+ aPixSize.Width() = nXmax - nXmin + 1;
+ aPixSize.Height() = nYmax - nYmin + 1;
+
+ // Aufloesung
+ rStm >> nTemp16;
+ nDPIx = nTemp16;
+ rStm >> nTemp16;
+ nDPIy = nTemp16;
+
+ // logische Groesse setzen
+ MapMode aMap( MAP_INCH, Point(),
+ Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
+ aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
+ MapMode( MAP_100TH_MM ) );
+
+
+ // Anzahl Farbebenen
+ rStm.SeekRel( 49 );
+ rStm >> cByte;
+ nPlanes = cByte;
+
+ bRet = (nPlanes<=4);
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPNG( SvStream& rStm, BOOL bExtendedInfo )
+{
+ UINT32 nTemp32;
+ BOOL bRet = FALSE;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStm.Seek( nStmPos );
+
+ rStm >> nTemp32;
+ if ( nTemp32 == 0x89504e47 )
+ {
+ rStm >> nTemp32;
+ if ( nTemp32 == 0x0d0a1a0a )
+ {
+ nFormat = GFF_PNG;
+ bRet = TRUE;
+
+ if ( bExtendedInfo )
+ {
+ BYTE cByte;
+
+ // IHDR-Chunk
+ rStm.SeekRel( 8 );
+
+ // Breite einlesen
+ rStm >> nTemp32;
+ aPixSize.Width() = nTemp32;
+
+ // Hoehe einlesen
+ rStm >> nTemp32;
+ aPixSize.Height() = nTemp32;
+
+ // Bits/Pixel einlesen
+ rStm >> cByte;
+ nBitsPerPixel = cByte;
+
+ // Planes immer 1;
+ // Kompression immer
+ nPlanes = 1;
+ bCompressed = TRUE;
+
+ if ( bWideSearch )
+ {
+ UINT32 nLen32;
+
+ rStm.SeekRel( 8 );
+
+ // so lange ueberlesen, bis wir den pHYs-Chunk haben oder
+ // den Anfang der Bilddaten
+ rStm >> nLen32;
+ rStm >> nTemp32;
+ while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) )
+ {
+ rStm.SeekRel( 4 + nLen32 );
+ rStm >> nLen32;
+ rStm >> nTemp32;
+ }
+
+ if ( nTemp32 == 0x70485973 )
+ {
+ ULONG nXRes;
+ ULONG nYRes;
+
+ // horizontale Aufloesung
+ rStm >> nTemp32;
+ nXRes = nTemp32;
+
+ // vertikale Aufloesung
+ rStm >> nTemp32;
+ nYRes = nTemp32;
+
+ // Unit einlesen
+ rStm >> cByte;
+
+ if ( cByte )
+ {
+ if ( nXRes )
+ aLogSize.Width() = ( aPixSize.Width() * 100000 ) /
+ nTemp32;
+
+ if ( nYRes )
+ aLogSize.Height() = ( aPixSize.Height() * 100000 ) /
+ nTemp32;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectTIF( SvStream& rStm, BOOL bExtendedInfo )
+{
+ BOOL bDetectOk = FALSE;
+ BOOL bRet = FALSE;
+ BYTE cByte1;
+ BYTE cByte2;
+
+ rStm.Seek( nStmPos );
+ rStm >> cByte1;
+ rStm >> cByte2;
+ if ( cByte1 == cByte2 )
+ {
+ if ( cByte1 == 0x49 )
+ {
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ bDetectOk = TRUE;
+ }
+ else if ( cByte1 == 0x4d )
+ {
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ bDetectOk = TRUE;
+ }
+
+ if ( bDetectOk )
+ {
+ UINT16 nTemp16;
+
+ rStm >> nTemp16;
+ if ( nTemp16 == 0x2a )
+ {
+ nFormat = GFF_TIF;
+ bRet = TRUE;
+
+ if ( bExtendedInfo )
+ {
+ ULONG nCount;
+ ULONG nMax = DATA_SIZE - 48;
+ UINT32 nTemp32;
+ BOOL bOk = FALSE;
+
+ // Offset des ersten IFD einlesen
+ rStm >> nTemp32;
+ rStm.SeekRel( ( nCount = ( nTemp32 + 2 ) ) - 0x08 );
+
+ if ( bWideSearch || ( nCount < nMax ) )
+ {
+ // Tag's lesen, bis wir auf Tag256 ( Width ) treffen
+ // nicht mehr Bytes als DATA_SIZE lesen
+ rStm >> nTemp16;
+ while ( nTemp16 != 256 )
+ {
+ bOk = bWideSearch || ( nCount < nMax );
+ if ( !bOk )
+ {
+ break;
+ }
+ rStm.SeekRel( 10 );
+ rStm >> nTemp16;
+ nCount += 12;
+ }
+
+ if ( bOk )
+ {
+ // Breite lesen
+ rStm >> nTemp16;
+ rStm.SeekRel( 4 );
+ if ( nTemp16 == 3 )
+ {
+ rStm >> nTemp16;
+ aPixSize.Width() = nTemp16;
+ rStm.SeekRel( 2 );
+ }
+ else
+ {
+ rStm >> nTemp32;
+ aPixSize.Width() = nTemp32;
+ }
+ nCount += 12;
+
+ // Hoehe lesen
+ rStm.SeekRel( 2 );
+ rStm >> nTemp16;
+ rStm.SeekRel( 4 );
+ if ( nTemp16 == 3 )
+ {
+ rStm >> nTemp16;
+ aPixSize.Height() = nTemp16;
+ rStm.SeekRel( 2 );
+ }
+ else
+ {
+ rStm >> nTemp32;
+ aPixSize.Height() = nTemp32;
+ }
+ nCount += 12;
+
+ // ggf. Bits/Pixel lesen
+ rStm >> nTemp16;
+ if ( nTemp16 == 258 )
+ {
+ rStm.SeekRel( 6 );
+ rStm >> nTemp16;
+ nBitsPerPixel = nTemp16;
+ rStm.SeekRel( 2 );
+ nCount += 12;
+ }
+ else
+ rStm.SeekRel( -2 );
+
+ // ggf. Compression lesen
+ rStm >> nTemp16;
+ if ( nTemp16 == 259 )
+ {
+ rStm.SeekRel( 6 );
+ rStm >> nTemp16;
+ bCompressed = ( nTemp16 > 1 );
+ rStm.SeekRel( 2 );
+ nCount += 12;
+ }
+ else
+ rStm.SeekRel( -2 );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectXBM( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "xbm", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_XBM;
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectXPM( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "xpm", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_XPM;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPBM( SvStream& rStm, BOOL )
+{
+ BOOL bRet = FALSE;
+
+ // erst auf Datei Extension pruefen, da diese aussagekraeftiger ist
+ // als die 2 ID Bytes
+
+ if ( aPathExt.CompareToAscii( "pbm", 3 ) == COMPARE_EQUAL )
+ bRet = TRUE;
+ else
+ {
+ BYTE nFirst, nSecond;
+ rStm.Seek( nStmPos );
+ rStm >> nFirst >> nSecond;
+ if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
+ bRet = TRUE;
+ }
+
+ if ( bRet )
+ nFormat = GFF_PBM;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPGM( SvStream& rStm, BOOL )
+{
+ BOOL bRet = FALSE;
+
+ if ( aPathExt.CompareToAscii( "pgm", 3 ) == COMPARE_EQUAL )
+ bRet = TRUE;
+ else
+ {
+ BYTE nFirst, nSecond;
+ rStm.Seek( nStmPos );
+ rStm >> nFirst >> nSecond;
+ if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
+ bRet = TRUE;
+ }
+
+ if ( bRet )
+ nFormat = GFF_PGM;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPPM( SvStream& rStm, BOOL )
+{
+ BOOL bRet = FALSE;
+
+ if ( aPathExt.CompareToAscii( "ppm", 3 ) == COMPARE_EQUAL )
+ bRet = TRUE;
+ else
+ {
+ BYTE nFirst, nSecond;
+ rStm.Seek( nStmPos );
+ rStm >> nFirst >> nSecond;
+ if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
+ bRet = TRUE;
+ }
+
+ if ( bRet )
+ nFormat = GFF_PPM;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectRAS( SvStream& rStm, BOOL )
+{
+ UINT32 nMagicNumber;
+ rStm.Seek( nStmPos );
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStm >> nMagicNumber;
+ if ( nMagicNumber == 0x59a66a95 )
+ {
+ nFormat = GFF_RAS;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectTGA( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "tga", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_TGA;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPSD( SvStream& rStm, BOOL bExtendedInfo )
+{
+ BOOL bRet = FALSE;
+
+ UINT32 nMagicNumber;
+ rStm.Seek( nStmPos );
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStm >> nMagicNumber;
+ if ( nMagicNumber == 0x38425053 )
+ {
+ UINT16 nVersion;
+ rStm >> nVersion;
+ if ( nVersion == 1 )
+ {
+ bRet = TRUE;
+ if ( bExtendedInfo )
+ {
+ UINT16 nChannels;
+ UINT32 nRows;
+ UINT32 nColumns;
+ UINT16 nDepth;
+ UINT16 nMode;
+ rStm.SeekRel( 6 ); // Pad
+ rStm >> nChannels >> nRows >> nColumns >> nDepth >> nMode;
+ if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
+ {
+ nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
+ switch ( nChannels )
+ {
+ case 4 :
+ case 3 :
+ nBitsPerPixel = 24;
+ case 2 :
+ case 1 :
+ aPixSize.Width() = nColumns;
+ aPixSize.Height() = nRows;
+ break;
+ default:
+ bRet = FALSE;
+ }
+ }
+ else
+ bRet = FALSE;
+ }
+ }
+ }
+
+ if ( bRet )
+ nFormat = GFF_PSD;
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectEPS( SvStream& rStm, BOOL )
+{
+ // es wird die EPS mit Vorschaubild Variante und die Extensionuebereinstimmung
+ // geprueft
+
+ sal_uInt32 nFirstLong;
+ sal_uInt8 nFirstBytes[20];
+
+ rStm.Seek( nStmPos );
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStm >> nFirstLong;
+ rStm.SeekRel( -4 );
+ rStm.Read( &nFirstBytes, 20 );
+
+ if ( ( nFirstLong == 0xC5D0D3C6 ) || ( aPathExt.CompareToAscii( "eps", 3 ) == COMPARE_EQUAL ) ||
+ ( ImplSearchEntry( nFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 )
+ && ImplSearchEntry( &nFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
+ {
+ nFormat = GFF_EPS;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectDXF( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "dxf", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_DXF;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectMET( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "met", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_MET;
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectPCT( SvStream& rStm, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "pct", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_PCT;
+ else
+ {
+ BYTE sBuf[4];
+
+ rStm.Seek( nStmPos + 522 );
+ rStm.Read( sBuf, 3 );
+
+ if( !rStm.GetError() )
+ {
+ if ( ( sBuf[0] == 0x00 ) && ( sBuf[1] == 0x11 ) &&
+ ( ( sBuf[2] == 0x01 ) || ( sBuf[2] == 0x02 ) ) )
+ {
+ bRet = TRUE;
+ nFormat = GFF_PCT;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectSGF( SvStream& rStm, BOOL )
+{
+ BOOL bRet = FALSE;
+
+ if( aPathExt.CompareToAscii( "sgf", 3 ) == COMPARE_EQUAL )
+ bRet = TRUE;
+ else
+ {
+ BYTE nFirst, nSecond;
+
+ rStm.Seek( nStmPos );
+ rStm >> nFirst >> nSecond;
+
+ if( nFirst == 'J' && nSecond == 'J' )
+ bRet = TRUE;
+ }
+
+ if( bRet )
+ nFormat = GFF_SGF;
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectSGV( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "sgv", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_SGV;
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectSVM( SvStream& rStm, BOOL bExtendedInfo )
+{
+ UINT32 n32;
+ BOOL bRet = FALSE;
+ BYTE cByte;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStm.Seek( nStmPos );
+
+ rStm >> n32;
+ if ( n32 == 0x44475653 )
+ {
+ rStm >> cByte;
+ if ( cByte == 0x49 )
+ {
+ nFormat = GFF_SVM;
+ bRet = TRUE;
+
+ if ( bExtendedInfo )
+ {
+ UINT32 nTemp32;
+ UINT16 nTemp16;
+
+ rStm.SeekRel( 0x04 );
+
+ // Breite auslesen
+ rStm >> nTemp32;
+ aLogSize.Width() = nTemp32;
+
+ // Hoehe auslesen
+ rStm >> nTemp32;
+ aLogSize.Height() = nTemp32;
+
+ // Map-Unit auslesen und PrefSize ermitteln
+ rStm >> nTemp16;
+ aLogSize = OutputDevice::LogicToLogic( aLogSize,
+ MapMode( (MapUnit) nTemp16 ),
+ MapMode( MAP_100TH_MM ) );
+ }
+ }
+ }
+ else
+ {
+ rStm.SeekRel( -4L );
+ rStm >> n32;
+
+ if( n32 == 0x4D4C4356 )
+ {
+ UINT16 nTmp16;
+
+ rStm >> nTmp16;
+
+ if( nTmp16 == 0x4654 )
+ {
+ nFormat = GFF_SVM;
+ bRet = TRUE;
+
+ if( bExtendedInfo )
+ {
+ MapMode aMapMode;
+
+ rStm.SeekRel( 0x06 );
+ rStm >> aMapMode;
+ rStm >> aLogSize;
+ aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MAP_100TH_MM ) );
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectWMF( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "wmf",3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_WMF;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+BOOL GraphicDescriptor::ImpDetectEMF( SvStream&, BOOL )
+{
+ BOOL bRet = aPathExt.CompareToAscii( "emf", 3 ) == COMPARE_EQUAL;
+ if (bRet)
+ nFormat = GFF_EMF;
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+
+String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat )
+{
+ ByteString aKeyName;
+
+ switch( nFormat )
+ {
+ case( GFF_BMP ) : aKeyName = "bmp"; break;
+ case( GFF_GIF ) : aKeyName = "gif"; break;
+ case( GFF_JPG ) : aKeyName = "jpg"; break;
+ case( GFF_PCD ) : aKeyName = "pcd"; break;
+ case( GFF_PCX ) : aKeyName = "pcx"; break;
+ case( GFF_PNG ) : aKeyName = "png"; break;
+ case( GFF_XBM ) : aKeyName = "xbm"; break;
+ case( GFF_XPM ) : aKeyName = "xpm"; break;
+ case( GFF_PBM ) : aKeyName = "pbm"; break;
+ case( GFF_PGM ) : aKeyName = "pgm"; break;
+ case( GFF_PPM ) : aKeyName = "ppm"; break;
+ case( GFF_RAS ) : aKeyName = "ras"; break;
+ case( GFF_TGA ) : aKeyName = "tga"; break;
+ case( GFF_PSD ) : aKeyName = "psd"; break;
+ case( GFF_EPS ) : aKeyName = "eps"; break;
+ case( GFF_TIF ) : aKeyName = "tif"; break;
+ case( GFF_DXF ) : aKeyName = "dxf"; break;
+ case( GFF_MET ) : aKeyName = "met"; break;
+ case( GFF_PCT ) : aKeyName = "pct"; break;
+ case( GFF_SGF ) : aKeyName = "sgf"; break;
+ case( GFF_SGV ) : aKeyName = "sgv"; break;
+ case( GFF_SVM ) : aKeyName = "svm"; break;
+ case( GFF_WMF ) : aKeyName = "wmf"; break;
+ case( GFF_EMF ) : aKeyName = "emf"; break;
+ }
+
+ return String( aKeyName, RTL_TEXTENCODING_ASCII_US );
+}
diff --git a/svtools/source/filter.vcl/filter/fldll.cxx b/svtools/source/filter.vcl/filter/fldll.cxx
new file mode 100644
index 000000000000..b44e08835f34
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/fldll.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_svtools.hxx"
+
+#ifdef WIN
+#include <svwin.h>
+
+// Statische DLL-Verwaltungs-Variablen
+static HINSTANCE hDLLInst = 0; // HANDLE der DLL
+
+
+/***************************************************************************
+|*
+|* LibMain()
+|*
+|* Beschreibung Initialisierungsfunktion der DLL
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
+{
+#ifndef WNT
+ if ( nHeap )
+ UnlockData( 0 );
+#endif
+
+ hDLLInst = hDLL;
+
+ return TRUE;
+}
+
+/***************************************************************************
+|*
+|* WEP()
+|*
+|* Beschreibung DLL-Deinitialisierung
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+#endif
+
diff --git a/svtools/source/filter.vcl/filter/gradwrap.cxx b/svtools/source/filter.vcl/filter/gradwrap.cxx
new file mode 100644
index 000000000000..be5dade03313
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/gradwrap.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_svtools.hxx"
+
+#include <math.h>
+#include <svgrad.hxx>
+#include <svbmpacc.hxx>
+#include <gradwrap.hxx>
+
+// -------------------
+// - GradientWrapper -
+// -------------------
+
+GradientWrapper::GradientWrapper(const Link& rDrawPolyRecordHdl,
+ const Link& rDrawPolyPolyRecordHdl,
+ const Link& rSetFillInBrushRecordHdl) :
+ aDrawPolyRecordHdl (rDrawPolyRecordHdl),
+ aDrawPolyPolyRecordHdl (rDrawPolyPolyRecordHdl),
+ aSetFillInBrushRecordHdl(rSetFillInBrushRecordHdl)
+{
+}
+
+// ------------------------------------------------------------------------
+
+GradientWrapper::~GradientWrapper()
+{
+}
+
+// ------------------------------------------------------------------------
+
+void GradientWrapper::WriteLinearGradient(const Rectangle& rRect,
+ const Gradient& rGradient)
+{
+ USHORT nStepCount = 100;
+
+ Rectangle aRect = rRect;
+ aRect.Left()--;
+ aRect.Top()--;
+ aRect.Right()++;
+ aRect.Bottom()++;
+
+ // rotiertes BoundRect ausrechnen
+ double fAngle = (rGradient.GetAngle() % 3600) * F_PI1800;
+ double fWidth = aRect.GetWidth();
+ double fHeight = aRect.GetHeight();
+ double fDX = fWidth * fabs( cos( fAngle ) ) +
+ fHeight * fabs( sin( fAngle ) );
+ double fDY = fHeight * fabs( cos( fAngle ) ) +
+ fWidth * fabs( sin( fAngle ) );
+ fDX = (fDX - fWidth) * 0.5 + 0.5;
+ fDY = (fDY - fHeight) * 0.5 + 0.5;
+ aRect.Left() -= (long)fDX;
+ aRect.Right() += (long)fDX;
+ aRect.Top() -= (long)fDY;
+ aRect.Bottom() += (long)fDY;
+
+ // Rand berechnen und Rechteck neu setzen
+ Point aCenter = rRect.Center();
+ Rectangle aFullRect = aRect;
+ long nBorder = (long)rGradient.GetBorder() * aRect.GetHeight() / 100;
+ BOOL bLinear;
+
+ // Rand berechnen und Rechteck neu setzen fuer linearen Farbverlauf
+ if ( rGradient.GetStyle() == GRADIENT_LINEAR )
+ {
+ bLinear = TRUE;
+ aRect.Top() += nBorder;
+ }
+ // Rand berechnen und Rechteck neu setzen fuer axiale Farbverlauf
+ else
+ {
+ bLinear = FALSE;
+ nBorder >>= 1;
+
+ aRect.Top() += nBorder;
+ aRect.Bottom() -= nBorder;
+ }
+
+ // Top darf nicht groesser als Bottom sein
+ aRect.Top() = Min( aRect.Top(), (long)(aRect.Bottom() - 1) );
+
+ long nMinRect = aRect.GetHeight();
+
+ // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
+ if ( !nStepCount )
+ {
+ long nInc = ((nMinRect >> 9) + 1) << 3;
+
+ if ( !nInc )
+ nInc = 1;
+
+ nStepCount = (USHORT)(nMinRect / nInc);
+ }
+ // minimal drei Schritte
+ long nSteps = Max( nStepCount, (USHORT)3 );
+
+ // Falls axialer Farbverlauf, muss die Schrittanzahl ungerade sein
+ if ( !bLinear && !(nSteps & 1) )
+ nSteps++;
+
+ // Berechnung ueber Double-Addition wegen Genauigkeit
+ double fScanLine = aRect.Top();
+ double fScanInc = (double)aRect.GetHeight() / (double)nSteps;
+
+ // Intensitaeten von Start- und Endfarbe ggf. aendern und
+ // Farbschrittweiten berechnen
+ long nFactor;
+ const Color& rStartCol = rGradient.GetStartColor();
+ const Color& rEndCol = rGradient.GetEndColor();
+ long nRed = rStartCol.GetRed();
+ long nGreen = rStartCol.GetGreen();
+ long nBlue = rStartCol.GetBlue();
+ long nEndRed = rEndCol.GetRed();
+ long nEndGreen = rEndCol.GetGreen();
+ long nEndBlue = rEndCol.GetBlue();
+ nFactor = rGradient.GetStartIntensity();
+ nRed = (nRed * nFactor) / 100;
+ nGreen = (nGreen * nFactor) / 100;
+ nBlue = (nBlue * nFactor) / 100;
+ nFactor = rGradient.GetEndIntensity();
+ nEndRed = (nEndRed * nFactor) / 100;
+ nEndGreen = (nEndGreen * nFactor) / 100;
+ nEndBlue = (nEndBlue * nFactor) / 100;
+ long nStepRed = (nEndRed - nRed) / nSteps;
+ long nStepGreen = (nEndGreen - nGreen) / nSteps;
+ long nStepBlue = (nEndBlue - nBlue) / nSteps;
+ long nSteps2;
+
+ if ( bLinear )
+ {
+ // Um 1 erhoeht, um die Border innerhalb der Schleife
+ // zeichnen zu koennen
+ nSteps2 = nSteps + 1;
+ }
+ else
+ {
+ nStepRed <<= 1;
+ nStepGreen <<= 1;
+ nStepBlue <<= 1;
+ nRed = nEndRed;
+ nGreen = nEndGreen;
+ nBlue = nEndBlue;
+
+ // Um 2 erhoeht, um die Border innerhalb der Schleife
+ // zeichnen zu koennen
+ nSteps2 = nSteps + 2;
+ }
+ Color aCol( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+
+ // GDI-Objekte sichern und setzen
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ // Startpolygon erzeugen (== Borderpolygon)
+ Polygon aPoly( 4 );
+ Polygon aTempPoly( 2 );
+ aPoly[0] = aFullRect.TopLeft();
+ aPoly[1] = aFullRect.TopRight();
+ aPoly[2] = aRect.TopRight();
+ aPoly[3] = aRect.TopLeft();
+ aPoly.Rotate( aCenter, rGradient.GetAngle() );
+
+ // Schleife, um rotierten Verlauf zu fuellen
+ for ( long i = 0; i < nSteps2; i++ )
+ {
+ Polygon aTempPoly = aPoly;
+ aTempPoly.Clip( rRect );
+ aDrawPolyRecordHdl.Call(&aTempPoly);
+ aTempPoly.SetSize( 2 );
+
+ // neues Polygon berechnen
+ aRect.Top() = (long)(fScanLine += fScanInc);
+
+ // unteren Rand komplett fuellen
+ if ( i == nSteps )
+ {
+ aTempPoly[0] = aFullRect.BottomLeft();
+ aTempPoly[1] = aFullRect.BottomRight();
+ }
+ else
+ {
+ aTempPoly[0] = aRect.TopLeft();
+ aTempPoly[1] = aRect.TopRight();
+ }
+ aTempPoly.Rotate( aCenter, rGradient.GetAngle() );
+
+ aPoly[0] = aPoly[3];
+ aPoly[1] = aPoly[2];
+ aPoly[2] = aTempPoly[1];
+ aPoly[3] = aTempPoly[0];
+
+ // Farbintensitaeten aendern...
+ // fuer lineare FV
+ if ( bLinear )
+ {
+ nRed += nStepRed;
+ nGreen += nStepGreen;
+ nBlue += nStepBlue;
+ }
+ // fuer radiale FV
+ else
+ {
+ if ( i <= (nSteps >> 1) )
+ {
+ nRed -= nStepRed;
+ nGreen -= nStepGreen;
+ nBlue -= nStepBlue;
+ }
+ // genau die Mitte und hoeher
+ else
+ {
+ nRed += nStepRed;
+ nGreen += nStepGreen;
+ nBlue += nStepBlue;
+ }
+ }
+
+ nRed = MinMax( nRed, 0, 255 );
+ nGreen = MinMax( nGreen, 0, 255 );
+ nBlue = MinMax( nBlue, 0, 255 );
+
+ // fuer lineare FV ganz normale Bestimmung der Farbe
+ if ( bLinear || (i <= nSteps) )
+ {
+ aCol = Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+ }
+ // fuer axiale FV muss die letzte Farbe der ersten
+ // Farbe entsprechen
+ else
+ {
+ aCol = Color( (BYTE) nEndRed, (BYTE) nEndGreen, (BYTE) nEndBlue );
+ }
+
+ aSetFillInBrushRecordHdl.Call(&aCol);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GradientWrapper::WriteRadialGradient(const Rectangle& rRect,
+ const Gradient& rGradient)
+{
+ USHORT nStepCount = 100;
+ Rectangle aClipRect = rRect;
+ Rectangle aRect = rRect;
+ long nZWidth = aRect.GetWidth() * (long)rGradient.GetOfsX() / 100;
+ long nZHeight= aRect.GetHeight() * (long)rGradient.GetOfsY() / 100;
+ Size aSize = aRect.GetSize();
+ Point aCenter( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
+
+ // Radien-Berechnung fuer Kreisausgabe (Kreis schliesst Rechteck ein)
+ if ( rGradient.GetStyle() == GRADIENT_RADIAL )
+ {
+ aSize.Width() = (long)(0.5 + sqrt((double)aSize.Width()*(double)aSize.Width() +
+ (double)aSize.Height()*(double)aSize.Height()));
+ aSize.Height() = aSize.Width();
+ }
+ // Radien-Berechnung fuer Ellipse
+ else
+ {
+ aSize.Width() = (long)(0.5 + (double)aSize.Width() * 1.4142);
+ aSize.Height() = (long)(0.5 + (double)aSize.Height() * 1.4142);
+ }
+
+ long nBorderX = (long)rGradient.GetBorder() * aSize.Width() / 100;
+ long nBorderY = (long)rGradient.GetBorder() * aSize.Height() / 100;
+ aSize.Width() -= nBorderX;
+ aSize.Height() -= nBorderY;
+ aRect.Left() = aCenter.X() - (aSize.Width() >> 1);
+ aRect.Top() = aCenter.Y() - (aSize.Height() >> 1);
+ aRect.SetSize( aSize );
+
+ long nMinRect = Min( aRect.GetWidth(), aRect.GetHeight() );
+
+ // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
+ if ( !nStepCount )
+ {
+ long nInc = ((nMinRect >> 9) + 1) << 3;
+
+ if ( !nInc )
+ nInc = 1;
+
+ nStepCount = (USHORT)(nMinRect / nInc);
+ }
+ // minimal drei Schritte
+ long nSteps = Max( nStepCount, (USHORT)3 );
+
+ // Ausgabebegrenzungen und Schrittweite fuer jede Richtung festlegen
+ double fScanLeft = aRect.Left();
+ double fScanTop = aRect.Top();
+ double fScanRight = aRect.Right();
+ double fScanBottom = aRect.Bottom();
+ double fScanInc = (double)nMinRect / (double)nSteps * 0.5;
+
+ // Intensitaeten von Start- und Endfarbe ggf. aendern und
+ // Farbschrittweiten berechnen
+ long nFactor;
+ const Color& rStartCol = rGradient.GetStartColor();
+ const Color& rEndCol = rGradient.GetEndColor();
+ long nRed = rStartCol.GetRed();
+ long nGreen = rStartCol.GetGreen();
+ long nBlue = rStartCol.GetBlue();
+ long nEndRed = rEndCol.GetRed();
+ long nEndGreen = rEndCol.GetGreen();
+ long nEndBlue = rEndCol.GetBlue();
+ nFactor = rGradient.GetStartIntensity();
+ nRed = (nRed * nFactor) / 100;
+ nGreen = (nGreen * nFactor) / 100;
+ nBlue = (nBlue * nFactor) / 100;
+ nFactor = rGradient.GetEndIntensity();
+ nEndRed = (nEndRed * nFactor) / 100;
+ nEndGreen = (nEndGreen * nFactor) / 100;
+ nEndBlue = (nEndBlue * nFactor) / 100;
+ long nStepRed = (nEndRed - nRed) / nSteps;
+ long nStepGreen = (nEndGreen - nGreen) / nSteps;
+ long nStepBlue = (nEndBlue - nBlue) / nSteps;
+ Color aCol( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+
+ // GDI-Objekte sichern und setzen
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ // Recteck erstmal ausgeben
+ PolyPolygon aPolyPoly( 2 );
+ Polygon aPoly( rRect );
+
+ aPolyPoly.Insert( aPoly );
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, rGradient.GetAngle() );
+ aPolyPoly.Insert( aPoly );
+
+ // erstes Polygon zeichnen (entspricht Rechteck)
+ PolyPolygon aTempPolyPoly = aPolyPoly;
+ aTempPolyPoly.Clip( aClipRect );
+ aDrawPolyPolyRecordHdl.Call(&aTempPolyPoly);
+
+ for ( long i = 0; i < nSteps; i++ )
+ {
+ Color aCol( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ // neues Polygon berechnen
+ aRect.Left() = (long)(fScanLeft += fScanInc);
+ aRect.Top() = (long)(fScanTop += fScanInc);
+ aRect.Right() = (long)(fScanRight -= fScanInc);
+ aRect.Bottom() = (long)(fScanBottom -= fScanInc);
+
+ if ( (aRect.GetWidth() < 2) || (aRect.GetHeight() < 2) )
+ break;
+
+ aPoly = Polygon( aRect.Center(),
+ aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
+ aPoly.Rotate( aCenter, rGradient.GetAngle() );
+
+ aPolyPoly.Replace( aPolyPoly.GetObject( 1 ), 0 );
+ aPolyPoly.Replace( aPoly, 1 );
+
+ PolyPolygon aTempPolyPoly = aPolyPoly;
+ aTempPolyPoly.Clip( aClipRect );
+ aDrawPolyPolyRecordHdl.Call(&aTempPolyPoly);
+
+ // Farbe entsprechend anpassen
+ nRed += nStepRed;
+ nGreen += nStepGreen;
+ nBlue += nStepBlue;
+
+ nRed = MinMax( nRed, 0, 0xFF );
+ nGreen = MinMax( nGreen, 0, 0xFF );
+ nBlue = MinMax( nBlue, 0, 0xFF );
+ }
+
+ // Falls PolyPolygon-Ausgabe, muessen wir noch ein letztes
+ // inneres Polygon zeichnen
+ aCol = Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ aPoly = aPolyPoly.GetObject( 1 );
+ if ( !aPoly.GetBoundRect().IsEmpty() )
+ {
+ aPoly.Clip( aClipRect );
+ aDrawPolyRecordHdl.Call(&aPoly);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GradientWrapper::WriteRectGradient(const Rectangle& rRect,
+ const Gradient& rGradient)
+{
+ USHORT nStepCount = 100;
+ Rectangle aClipRect = rRect;
+ Rectangle aRect = rRect;
+
+ aRect.Left()--;
+ aRect.Top()--;
+ aRect.Right()++;
+ aRect.Bottom()++;
+
+ // rotiertes BoundRect ausrechnen
+ double fAngle = (rGradient.GetAngle() % 3600) * F_PI1800;
+ double fWidth = aRect.GetWidth();
+ double fHeight = aRect.GetHeight();
+ double fDX = fWidth * fabs( cos( fAngle ) ) +
+ fHeight * fabs( sin( fAngle ) );
+ double fDY = fHeight * fabs( cos( fAngle ) ) +
+ fWidth * fabs( sin( fAngle ) );
+ fDX = (fDX - fWidth) * 0.5 + 0.5;
+ fDY = (fDY - fHeight) * 0.5 + 0.5;
+ aRect.Left() -= (long)fDX;
+ aRect.Right() += (long)fDX;
+ aRect.Top() -= (long)fDY;
+ aRect.Bottom() += (long)fDY;
+
+ // Quadratisch machen, wenn angefordert;
+ Size aSize = aRect.GetSize();
+ if ( rGradient.GetStyle() == GRADIENT_SQUARE )
+ {
+ if ( aSize.Width() > aSize.Height() )
+ aSize.Height() = aSize.Width();
+ else
+ aSize.Width() = aSize.Height();
+ }
+
+ // neue Mittelpunkte berechnen
+ long nZWidth = aRect.GetWidth() * (long)rGradient.GetOfsX() / 100;
+ long nZHeight = aRect.GetHeight() * (long)rGradient.GetOfsY() / 100;
+ long nBorderX = (long)rGradient.GetBorder() * aSize.Width() / 100;
+ long nBorderY = (long)rGradient.GetBorder() * aSize.Height() / 100;
+ Point aCenter( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
+
+ // Rand beruecksichtigen
+ aSize.Width() -= nBorderX;
+ aSize.Height() -= nBorderY;
+
+ // Ausgaberechteck neu setzen
+ aRect.Left() = aCenter.X() - (aSize.Width() >> 1);
+ aRect.Top() = aCenter.Y() - (aSize.Height() >> 1);
+ aRect.SetSize( aSize );
+
+ long nMinRect = Min( aRect.GetWidth(), aRect.GetHeight() );
+
+ // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
+ if ( !nStepCount )
+ {
+ long nInc = ((nMinRect >> 9) + 1) << 3;
+
+ if ( !nInc )
+ nInc = 1;
+
+ nStepCount = (USHORT)(nMinRect / nInc);
+ }
+ // minimal drei Schritte
+ long nSteps = Max( nStepCount, (USHORT)3 );
+
+ // Ausgabebegrenzungen und Schrittweite fuer jede Richtung festlegen
+ double fScanLeft = aRect.Left();
+ double fScanTop = aRect.Top();
+ double fScanRight = aRect.Right();
+ double fScanBottom = aRect.Bottom();
+ double fScanInc = (double)nMinRect / (double)nSteps * 0.5;
+
+ // Intensitaeten von Start- und Endfarbe ggf. aendern und
+ // Farbschrittweiten berechnen
+ long nFactor;
+ const Color& rStartCol = rGradient.GetStartColor();
+ const Color& rEndCol = rGradient.GetEndColor();
+ long nRed = rStartCol.GetRed();
+ long nGreen = rStartCol.GetGreen();
+ long nBlue = rStartCol.GetBlue();
+ long nEndRed = rEndCol.GetRed();
+ long nEndGreen = rEndCol.GetGreen();
+ long nEndBlue = rEndCol.GetBlue();
+ nFactor = rGradient.GetStartIntensity();
+ nRed = (nRed * nFactor) / 100;
+ nGreen = (nGreen * nFactor) / 100;
+ nBlue = (nBlue * nFactor) / 100;
+ nFactor = rGradient.GetEndIntensity();
+ nEndRed = (nEndRed * nFactor) / 100;
+ nEndGreen = (nEndGreen * nFactor) / 100;
+ nEndBlue = (nEndBlue * nFactor) / 100;
+ long nStepRed = (nEndRed - nRed) / nSteps;
+ long nStepGreen = (nEndGreen - nGreen) / nSteps;
+ long nStepBlue = (nEndBlue - nBlue) / nSteps;
+ Color aCol( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+
+ // GDI-Objekte sichern und setzen
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ // Recteck erstmal ausgeben
+ PolyPolygon aPolyPoly( 2 );
+ Polygon aPoly( rRect );
+
+ aPolyPoly.Insert( aPoly );
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, rGradient.GetAngle() );
+ aPolyPoly.Insert( aPoly );
+
+ PolyPolygon aTempPolyPoly = aPolyPoly;
+ aTempPolyPoly.Clip( aClipRect );
+ aDrawPolyPolyRecordHdl.Call(&aTempPolyPoly);
+
+ // Schleife, um nacheinander die Polygone/PolyPolygone auszugeben
+ for ( long i = 0; i < nSteps; i++ )
+ {
+ Color aCol( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ // neues Polygon berechnen
+ aRect.Left() = (long)(fScanLeft += fScanInc);
+ aRect.Top() = (long)(fScanTop += fScanInc);
+ aRect.Right() = (long)(fScanRight -= fScanInc);
+ aRect.Bottom() = (long)(fScanBottom-= fScanInc);
+
+ if ( (aRect.GetWidth() < 2) || (aRect.GetHeight() < 2) )
+ break;
+
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, rGradient.GetAngle() );
+
+ aPolyPoly.Replace( aPolyPoly.GetObject( 1 ), 0 );
+ aPolyPoly.Replace( aPoly, 1 );
+
+ PolyPolygon aTempPolyPoly = aPolyPoly;
+ aTempPolyPoly.Clip( aClipRect );
+ aDrawPolyPolyRecordHdl.Call(&aTempPolyPoly);
+
+ // Farben aendern
+ nRed += nStepRed;
+ nGreen += nStepGreen;
+ nBlue += nStepBlue;
+
+ nRed = MinMax( nRed, 0, 0xFF );
+ nGreen = MinMax( nGreen, 0, 0xFF );
+ nBlue = MinMax( nBlue, 0, 0xFF );
+ }
+
+ aCol = Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue );
+ aSetFillInBrushRecordHdl.Call(&aCol);
+
+ aPoly = aPolyPoly.GetObject( 1 );
+ if ( !aPoly.GetBoundRect().IsEmpty() )
+ {
+ aPoly.Clip( aClipRect );
+ aDrawPolyRecordHdl.Call(&aPoly);
+ }
+}
diff --git a/svtools/source/filter.vcl/filter/makefile.mk b/svtools/source/filter.vcl/filter/makefile.mk
new file mode 100644
index 000000000000..272bb9a76b03
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/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=svtools
+TARGET=filter
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+SOLARINC+=-I../../inc
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES= strings.src \
+ dlgexpor.src \
+ dlgepng.src \
+ dlgejpg.src
+
+SLOFILES= $(SLO)$/filter.obj \
+ $(SLO)$/filter2.obj \
+ $(SLO)$/dlgexpor.obj \
+ $(SLO)$/dlgejpg.obj \
+ $(SLO)$/dlgepng.obj \
+ $(SLO)$/sgfbram.obj \
+ $(SLO)$/sgvmain.obj \
+ $(SLO)$/sgvtext.obj \
+ $(SLO)$/sgvspln.obj \
+ $(SLO)$/FilterConfigItem.obj \
+ $(SLO)$/FilterConfigCache.obj \
+ $(SLO)$/SvFilterOptionsDialog.obj
+
+EXCEPTIONSNOOPTFILES= $(SLO)$/filter.obj \
+ $(SLO)$/FilterConfigItem.obj \
+ $(SLO)$/FilterConfigCache.obj \
+ $(SLO)$/SvFilterOptionsDialog.obj
+
+LIB1TARGET= $(SLB)$/$(TARGET).uno.lib
+LIB1OBJFILES= \
+ $(SLO)$/dlgexpor.obj \
+ $(SLO)$/dlgejpg.obj \
+ $(SLO)$/dlgepng.obj \
+ $(SLO)$/SvFilterOptionsDialog.obj
+
+LIB2TARGET= $(SLB)$/$(TARGET).lib
+LIB2OBJFILES= \
+ $(SLO)$/filter.obj \
+ $(SLO)$/filter2.obj \
+ $(SLO)$/sgfbram.obj \
+ $(SLO)$/sgvmain.obj \
+ $(SLO)$/sgvtext.obj \
+ $(SLO)$/sgvspln.obj \
+ $(SLO)$/FilterConfigItem.obj \
+ $(SLO)$/FilterConfigCache.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/filter.vcl/filter/sgf.ini b/svtools/source/filter.vcl/filter/sgf.ini
new file mode 100644
index 000000000000..7444e40c8836
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/sgf.ini
@@ -0,0 +1,118 @@
+#Family : (Roman,Swiss,Modern,Script,Decora);
+#CharSet : (Ansi,IBMPC,Mac,Symbol,System); Default is System
+#Attribute: (Bold,Ital,Sans,Serf,Fixd);
+
+[SGV Fonts fuer StarView]
+#IF-ID Fontname Attribute SV-Fam ChSet Width FontName
+ 3848=(ITC Zapf Dingbats) Decora ()
+ 5720=(Symbol) Serf Decora Symbol ()
+ 5721=(Symbol) Bold Serf Decora Symbol ()
+ 5723=(Symbol Sans) Sans Decora Symbol ()
+ 5724=(Symbol Sans) Bold Sans Decora Symbol ()
+ 90133=(Dom Casual) Sans Script ()
+ 90326=(Brush) Bold Ital Serf Script ()
+ 90349=(Park Avenue) Ital Serf Script ()
+ 90508=(Uncial) Sans Roman ()
+ 91118=(Antique Olive) Bold Sans Swiss ()
+ 91119=(Antique Olive) Sans Swiss ()
+ 91120=(Antique Olive Compact) Bold Sans Swiss ()
+ 91335=(ITC Benguiat) Bold Serf Roman ()
+ 91336=(ITC Benguiat) Bold Ital Serf Roman ()
+ 91846=(Antique Olive) Ital Sans Roman ()
+#92500=(CG Times) Serf Roman ()
+#92501=(CG Times) Ital Serf Roman ()
+#92504=(CG Times) Bold Serf Roman ()
+#92505=(CG Times) Bold Ital Serf Roman ()
+#93950=(Courier) Serf Fixd Modern ()
+#93951=(Courier) Ital Serf Fixd Modern ()
+#93952=(Courier) Bold Serf Fixd Modern ()
+#93953=(Courier) Bold Ital Serf Fixd Modern ()
+#94021=(Univers) Sans Swiss ()
+#94022=(Univers) Ital Sans Swiss ()
+#94023=(Univers) Bold Sans Swiss ()
+#94024=(Univers) Bold Ital Sans Swiss ()
+102004=(Avanti) Bold Ital Sans Swiss ()
+102005=(Avanti) Ital Sans Swiss ()
+102007=(Booklet) Bold Sans Roman ()
+102008=(Booklet) Bold Ital Sans Roman ()
+102009=(Booklet) Ital Sans Roman ()
+102010=(Centuri) Sans Roman ()
+102011=(Centuri) Bold Sans Roman ()
+102012=(Centuri) Bold Ital Sans Roman ()
+102013=(Centuri) Ital Sans Roman ()
+102014=(Paltus) Bold Sans Roman ()
+102015=(Paltus) Sans Roman ()
+102016=(Paltus) Bold Ital Sans Roman ()
+102017=(Paltus) Ital Sans Roman ()
+102018=(Sans) Sans Swiss ()
+102019=(Sans) Bold Sans Swiss ()
+102020=(Sans) Bold Ital Sans Swiss ()
+102021=(Sans) Ital Sans Swiss ()
+102022=(SansCondensed) Sans Swiss ()
+102023=(SansCondensed) Bold Sans Swiss ()
+102024=(SansCondensed) Bold Ital Sans Swiss ()
+102025=(SansCondensed) Ital Sans Swiss ()
+102026=(PS-Roman) Sans Roman ()
+102027=(PS-Roman) Bold Sans Roman ()
+102028=(PS-Roman) Bold Ital Sans Roman ()
+102029=(PS-Roman) Ital Sans Roman ()
+200111=(Chalenge) Sans ()
+200112=(Chalenge) Bold Sans ()
+200113=(Chalenge) Ital Sans ()
+200114=(Chalenge) Bold Ital Sans ()
+200121=(Office) Sans ()
+200122=(Office) Bold Sans ()
+200123=(Office) Ital Sans ()
+200124=(Office) Bold Ital Sans ()
+200131=(Milano) Sans ()
+200132=(Milano) Bold Sans ()
+200133=(Milano) Ital Sans ()
+200134=(Milano) Bold Ital Sans ()
+200141=(Atlantic) Sans Roman ()
+200142=(Atlantic) Bold Sans Roman ()
+200143=(Atlantic) Ital Sans Roman ()
+200144=(Atlantic) Bold Ital Sans Roman ()
+200151=(Pentagon) Sans ()
+200152=(Pentagon) Bold Sans ()
+200153=(Pentagon) Ital Sans ()
+200154=(Pentagon) Bold Ital Sans ()
+200161=(Classico) Sans ()
+200162=(Classico) Bold Sans ()
+200163=(Classico) Ital Sans ()
+200164=(Classico) Bold Ital Sans ()
+200211=(Westcost) Sans ()
+200212=(Westcost) Bold Sans ()
+200213=(Westcost) Ital Sans ()
+200214=(Westcost) Bold Ital Sans ()
+200221=(Finish) Sans ()
+200222=(Finish) Bold Sans ()
+200223=(Finish) Ital Sans ()
+200224=(Finish) Bold Ital Sans ()
+200231=(Classic) Sans ()
+200232=(Classic) Bold Sans ()
+200233=(Classic) Ital Sans ()
+200234=(Classic) Bold Ital Sans ()
+200241=(Hilton) Sans ()
+200242=(Hilton) Bold Sans ()
+200243=(Hilton) Ital Sans ()
+200244=(Hilton) Bold Ital Sans ()
+200251=(Progress) Sans ()
+200252=(Progress) Bold Sans ()
+200253=(Progress) Ital Sans ()
+200254=(Progress) Bold Ital Sans ()
+200261=(PrestigeElite) Sans ()
+200262=(PrestigeElite) Bold Sans ()
+200263=(PrestigeElite) Ital Sans ()
+200271=(Ovetti) Bold Sans ()
+200272=(Ovetti) Sans ()
+200301=(Cescendo) Sans ()
+200302=(Funky) Sans Decora ()
+200303=(Speed) Sans Decora ()
+200304=(Skyline) Sans Decora ()
+200305=(Calculator) Sans Decora ()
+200306=(Xpress) Sans Decora ()
+200307=(Console) Sans Decora ()
+200308=(Paisley) Sans ()
+200309=(Nova) Sans ()
+200310=(New York) Sans Decora ()
+200311=(Shanghai) Sans Decora ()
diff --git a/svtools/source/filter.vcl/filter/sgfbram.cxx b/svtools/source/filter.vcl/filter/sgfbram.cxx
new file mode 100644
index 000000000000..43cf0fbbacd3
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/sgfbram.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <string.h>
+#include <osl/endian.h>
+#include <tools/stream.hxx>
+#include <vcl/gdimtf.hxx>
+#include <tools/color.hxx>
+#include <vcl/virdev.hxx>
+#include "sgffilt.hxx"
+#include "sgfbram.hxx"
+
+#if defined( WIN ) && defined( MSC )
+#pragma code_seg( "SVTOOLS_FILTER4", "SVTOOLS_CODE" )
+#endif
+
+/*************************************************************************
+|*
+|* operator>>( SvStream&, SgfHeader& )
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+SvStream& operator>>(SvStream& rIStream, SgfHeader& rHead)
+{
+ rIStream.Read((char*)&rHead.Magic,SgfHeaderSize);
+#if defined OSL_BIGENDIAN
+ rHead.Magic =SWAPSHORT(rHead.Magic );
+ rHead.Version=SWAPSHORT(rHead.Version);
+ rHead.Typ =SWAPSHORT(rHead.Typ );
+ rHead.Xsize =SWAPSHORT(rHead.Xsize );
+ rHead.Ysize =SWAPSHORT(rHead.Ysize );
+ rHead.Xoffs =SWAPSHORT(rHead.Xoffs );
+ rHead.Yoffs =SWAPSHORT(rHead.Yoffs );
+ rHead.Planes =SWAPSHORT(rHead.Planes );
+ rHead.SwGrCol=SWAPSHORT(rHead.SwGrCol);
+ rHead.OfsLo =SWAPSHORT(rHead.OfsLo );
+ rHead.OfsHi =SWAPSHORT(rHead.OfsHi );
+#endif
+ return rIStream;
+}
+
+
+/*************************************************************************
+|*
+|* SgfHeader::ChkMagic()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfHeader::ChkMagic()
+{ return Magic=='J'*256+'J'; }
+
+UINT32 SgfHeader::GetOffset()
+{ return UINT32(OfsLo)+0x00010000*UINT32(OfsHi); }
+
+
+/*************************************************************************
+|*
+|* operator>>( SvStream&, SgfEntry& )
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+SvStream& operator>>(SvStream& rIStream, SgfEntry& rEntr)
+{
+ rIStream.Read((char*)&rEntr.Typ,SgfEntrySize);
+#if defined OSL_BIGENDIAN
+ rEntr.Typ =SWAPSHORT(rEntr.Typ );
+ rEntr.iFrei=SWAPSHORT(rEntr.iFrei);
+ rEntr.lFreiLo=SWAPSHORT (rEntr.lFreiLo);
+ rEntr.lFreiHi=SWAPSHORT (rEntr.lFreiHi);
+ rEntr.OfsLo=SWAPSHORT(rEntr.OfsLo);
+ rEntr.OfsHi=SWAPSHORT(rEntr.OfsHi);
+#endif
+ return rIStream;
+}
+
+UINT32 SgfEntry::GetOffset()
+{ return UINT32(OfsLo)+0x00010000*UINT32(OfsHi); }
+
+
+/*************************************************************************
+|*
+|* operator>>( SvStream&, SgfVector& )
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+SvStream& operator>>(SvStream& rIStream, SgfVector& rVect)
+{
+ rIStream.Read((char*)&rVect,sizeof(rVect));
+#if defined OSL_BIGENDIAN
+ rVect.Flag =SWAPSHORT(rVect.Flag );
+ rVect.x =SWAPSHORT(rVect.x );
+ rVect.y =SWAPSHORT(rVect.y );
+ rVect.OfsLo=SWAPLONG (rVect.OfsLo);
+ rVect.OfsHi=SWAPLONG (rVect.OfsHi);
+#endif
+ return rIStream;
+}
+
+
+/*************************************************************************
+|*
+|* operator<<( SvStream&, BmpFileHeader& )
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+SvStream& operator<<(SvStream& rOStream, BmpFileHeader& rHead)
+{
+#if defined OSL_BIGENDIAN
+ rHead.Typ =SWAPSHORT(rHead.Typ );
+ rHead.SizeLo =SWAPSHORT(rHead.SizeLo );
+ rHead.SizeHi =SWAPSHORT(rHead.SizeHi );
+ rHead.Reserve1=SWAPSHORT(rHead.Reserve1);
+ rHead.Reserve2=SWAPSHORT(rHead.Reserve2);
+ rHead.OfsLo =SWAPSHORT(rHead.OfsLo );
+ rHead.OfsHi =SWAPSHORT(rHead.OfsHi );
+#endif
+ rOStream.Write((char*)&rHead,sizeof(rHead));
+#if defined OSL_BIGENDIAN
+ rHead.Typ =SWAPSHORT(rHead.Typ );
+ rHead.SizeLo =SWAPSHORT(rHead.SizeLo );
+ rHead.SizeHi =SWAPSHORT(rHead.SizeHi );
+ rHead.Reserve1=SWAPSHORT(rHead.Reserve1);
+ rHead.Reserve2=SWAPSHORT(rHead.Reserve2);
+ rHead.OfsLo =SWAPSHORT(rHead.OfsLo );
+ rHead.OfsHi =SWAPSHORT(rHead.OfsHi );
+#endif
+ return rOStream;
+}
+
+void BmpFileHeader::SetSize(UINT32 Size)
+{
+ SizeLo=UINT16(Size & 0x0000FFFF);
+ SizeHi=UINT16((Size & 0xFFFF0000)>>16);
+}
+
+void BmpFileHeader::SetOfs(UINT32 Ofs)
+{
+ OfsLo=UINT16(Ofs & 0x0000FFFF);
+ OfsHi=UINT16((Ofs & 0xFFFF0000)>>16);
+}
+
+UINT32 BmpFileHeader::GetOfs()
+{
+ return UINT32(OfsLo)+0x00010000*UINT32(OfsHi);
+}
+
+/*************************************************************************
+|*
+|* operator<<( SvStream&, BmpInfoHeader& )
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+SvStream& operator<<(SvStream& rOStream, BmpInfoHeader& rInfo)
+{
+#if defined OSL_BIGENDIAN
+ rInfo.Size =SWAPLONG (rInfo.Size );
+ rInfo.Width =SWAPLONG (rInfo.Width );
+ rInfo.Hight =SWAPLONG (rInfo.Hight );
+ rInfo.Planes =SWAPSHORT(rInfo.Planes );
+ rInfo.PixBits =SWAPSHORT(rInfo.PixBits );
+ rInfo.Compress=SWAPLONG (rInfo.Compress);
+ rInfo.ImgSize =SWAPLONG (rInfo.ImgSize );
+ rInfo.xDpmm =SWAPLONG (rInfo.xDpmm );
+ rInfo.yDpmm =SWAPLONG (rInfo.yDpmm );
+ rInfo.ColUsed =SWAPLONG (rInfo.ColUsed );
+ rInfo.ColMust =SWAPLONG (rInfo.ColMust );
+#endif
+ rOStream.Write((char*)&rInfo,sizeof(rInfo));
+#if defined OSL_BIGENDIAN
+ rInfo.Size =SWAPLONG (rInfo.Size );
+ rInfo.Width =SWAPLONG (rInfo.Width );
+ rInfo.Hight =SWAPLONG (rInfo.Hight );
+ rInfo.Planes =SWAPSHORT(rInfo.Planes );
+ rInfo.PixBits =SWAPSHORT(rInfo.PixBits );
+ rInfo.Compress=SWAPLONG (rInfo.Compress);
+ rInfo.ImgSize =SWAPLONG (rInfo.ImgSize );
+ rInfo.xDpmm =SWAPLONG (rInfo.xDpmm );
+ rInfo.yDpmm =SWAPLONG (rInfo.yDpmm );
+ rInfo.ColUsed =SWAPLONG (rInfo.ColUsed );
+ rInfo.ColMust =SWAPLONG (rInfo.ColMust );
+#endif
+ return rOStream;
+}
+
+
+/*************************************************************************
+|*
+|* operator<<( SvStream&, RGBQuad& )
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+SvStream& operator<<(SvStream& rOStream, const RGBQuad& rQuad)
+{
+ rOStream.Write((char*)&rQuad,sizeof(rQuad));
+ return rOStream;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// PcxExpand ///////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class PcxExpand
+{
+private:
+ USHORT Count;
+ BYTE Data;
+public:
+ PcxExpand() { Count=0; }
+ BYTE GetByte(SvStream& rInp);
+};
+
+BYTE PcxExpand::GetByte(SvStream& rInp)
+{
+ if (Count>0) {
+ Count--;
+ } else {
+ rInp.Read((char*)&Data,1);
+ if ((Data & 0xC0) == 0xC0) {
+ Count=(Data & 0x3F) -1;
+ rInp.Read((char*)&Data,1);
+ }
+ }
+ return Data;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SgfBMapFilter ///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+/*************************************************************************
+|*
+|* SgfFilterBmp()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfFilterBMap(SvStream& rInp, SvStream& rOut, SgfHeader& rHead, SgfEntry&)
+{
+ BmpFileHeader aBmpHead;
+ BmpInfoHeader aBmpInfo;
+ USHORT nWdtInp=(rHead.Xsize+7)/8; // Breite der Input-Bitmap in Bytes
+ USHORT nWdtOut; // Breite der Output-Bitmap in Bytes
+ USHORT nColors; // Anzahl der Farben (1,16,256)
+ USHORT nColBits; // Anzahl der Bits/Pixel (2, 4, 8)
+ USHORT i,j,k; // Spaltenzaehler, Zeilenzaehler, Planezaehler
+ USHORT a,b; // Hilfsvariable
+ BYTE pl1 = 0,pl2= 0; // Masken fuer die Planes
+ BYTE* pBuf=NULL; // Buffer fuer eine Pixelzeile
+ PcxExpand aPcx;
+ ULONG nOfs;
+ BYTE cRGB[4];
+
+ if (rHead.Planes<=1) nColBits=1; else nColBits=4; if (rHead.Typ==4) nColBits=8;
+ nColors=1<<nColBits;
+ nWdtOut=((rHead.Xsize*nColBits+31)/32)*4;
+ aBmpHead.Typ='B'+'M'*256;
+ aBmpHead.SetOfs(sizeof(aBmpHead)+sizeof(aBmpInfo)+nColors*4);
+ aBmpHead.SetSize(aBmpHead.GetOfs()+nWdtOut*rHead.Ysize);
+ aBmpHead.Reserve1=0;
+ aBmpHead.Reserve2=0;
+ aBmpInfo.Size=sizeof(aBmpInfo);
+ aBmpInfo.Width=rHead.Xsize;
+ aBmpInfo.Hight=rHead.Ysize;
+ aBmpInfo.Planes=1;
+ aBmpInfo.PixBits=nColBits;
+ aBmpInfo.Compress=0;
+ aBmpInfo.ImgSize=0;
+ aBmpInfo.xDpmm=0;
+ aBmpInfo.yDpmm=0;
+ aBmpInfo.ColUsed=0;
+ aBmpInfo.ColMust=0;
+ pBuf=new BYTE[nWdtOut];
+ if (!pBuf) return FALSE; // Fehler: kein Speichel da
+ rOut<<aBmpHead<<aBmpInfo;
+ memset(pBuf,0,nWdtOut); // Buffer mit Nullen fuellen
+
+ if (nColors==2)
+ {
+
+ rOut<<RGBQuad(0x00,0x00,0x00); // Schwarz
+ rOut<<RGBQuad(0xFF,0xFF,0xFF); // Weiss
+ nOfs=rOut.Tell();
+ for (j=0;j<rHead.Ysize;j++)
+ rOut.Write((char*)pBuf,nWdtOut); // Datei erstmal komplett mit Nullen fuellen
+ for (j=0;j<rHead.Ysize;j++) {
+ for(i=0;i<nWdtInp;i++) {
+ pBuf[i]=aPcx.GetByte(rInp);
+ }
+ for(i=nWdtInp;i<nWdtOut;i++) pBuf[i]=0; // noch bis zu 3 Bytes
+ rOut.Seek(nOfs+((ULONG)rHead.Ysize-j-1L)*(ULONG)nWdtOut); // rueckwaerts schreiben!
+ rOut.Write((char*)pBuf,nWdtOut);
+ }
+ } else if (nColors==16) {
+ rOut<<RGBQuad(0x00,0x00,0x00); // Schwarz
+ rOut<<RGBQuad(0x24,0x24,0x24); // Grau 80%
+ rOut<<RGBQuad(0x49,0x49,0x49); // Grau 60%
+ rOut<<RGBQuad(0x92,0x92,0x92); // Grau 40%
+ rOut<<RGBQuad(0x6D,0x6D,0x6D); // Grau 30%
+ rOut<<RGBQuad(0xB6,0xB6,0xB6); // Grau 20%
+ rOut<<RGBQuad(0xDA,0xDA,0xDA); // Grau 10%
+ rOut<<RGBQuad(0xFF,0xFF,0xFF); // Weiss
+ rOut<<RGBQuad(0x00,0x00,0x00); // Schwarz
+ rOut<<RGBQuad(0xFF,0x00,0x00); // Rot
+ rOut<<RGBQuad(0x00,0x00,0xFF); // Blau
+ rOut<<RGBQuad(0xFF,0x00,0xFF); // Magenta
+ rOut<<RGBQuad(0x00,0xFF,0x00); // Gruen
+ rOut<<RGBQuad(0xFF,0xFF,0x00); // Gelb
+ rOut<<RGBQuad(0x00,0xFF,0xFF); // Cyan
+ rOut<<RGBQuad(0xFF,0xFF,0xFF); // Weiss
+
+ nOfs=rOut.Tell();
+ for (j=0;j<rHead.Ysize;j++)
+ rOut.Write((char*)pBuf,nWdtOut); // Datei erstmal komplett mit Nullen fuellen
+ for (j=0;j<rHead.Ysize;j++) {
+ memset(pBuf,0,nWdtOut);
+ for(k=0;k<4;k++) {
+ if (k==0) {
+ pl1=0x10; pl2=0x01;
+ } else {
+ pl1<<=1; pl2<<=1;
+ }
+ for(i=0;i<nWdtInp;i++) {
+ a=i*4;
+ b=aPcx.GetByte(rInp);
+ if (b & 0x80) pBuf[a ]|=pl1;
+ if (b & 0x40) pBuf[a ]|=pl2;
+ if (b & 0x20) pBuf[a+1]|=pl1;
+ if (b & 0x10) pBuf[a+1]|=pl2;
+ if (b & 0x08) pBuf[a+2]|=pl1;
+ if (b & 0x04) pBuf[a+2]|=pl2;
+ if (b & 0x02) pBuf[a+3]|=pl1;
+ if (b & 0x01) pBuf[a+3]|=pl2;
+ }
+ }
+ for(i=nWdtInp*4;i<nWdtOut;i++) pBuf[i]=0; // noch bis zu 3 Bytes
+ rOut.Seek(nOfs+((ULONG)rHead.Ysize-j-1L)*(ULONG)nWdtOut); // rueckwaerts schreiben!
+ rOut.Write((char*)pBuf,nWdtOut);
+ }
+ } else if (nColors==256) {
+ cRGB[3]=0; // der 4. Paletteneintrag fuer BMP
+ for (i=0;i<256;i++) { // Palette kopieren
+ rInp.Read((char*)cRGB,3);
+ pl1=cRGB[0]; // Rot mit Blau tauschen
+ cRGB[0]=cRGB[2];
+ cRGB[2]=pl1;
+ rOut.Write((char*)cRGB,4);
+ }
+
+ nOfs=rOut.Tell();
+ for (j=0;j<rHead.Ysize;j++)
+ rOut.Write((char*)pBuf,nWdtOut); // Datei erstmal komplett mit Nullen fuellen
+ for (j=0;j<rHead.Ysize;j++) {
+ for(i=0;i<rHead.Xsize;i++)
+ pBuf[i]=aPcx.GetByte(rInp);
+ for(i=rHead.Xsize;i<nWdtOut;i++) pBuf[i]=0; // noch bis zu 3 Bytes
+ rOut.Seek(nOfs+((ULONG)rHead.Ysize-j-1L)*(ULONG)nWdtOut); // rueckwaerts schreiben!
+ rOut.Write((char*)pBuf,nWdtOut);
+ }
+ }
+ delete[] pBuf;
+ return TRUE;
+}
+
+
+/*************************************************************************
+|*
+|* SgfBMapFilter()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfBMapFilter(SvStream& rInp, SvStream& rOut)
+{
+ ULONG nFileStart; // Offset des SgfHeaders. Im allgemeinen 0.
+ SgfHeader aHead;
+ SgfEntry aEntr;
+ ULONG nNext;
+ BOOL bRdFlag=FALSE; // Grafikentry gelesen ?
+ BOOL bRet=FALSE; // Returncode
+
+ nFileStart=rInp.Tell();
+ rInp>>aHead;
+ if (aHead.ChkMagic() && (aHead.Typ==SgfBitImag0 || aHead.Typ==SgfBitImag1 ||
+ aHead.Typ==SgfBitImag2 || aHead.Typ==SgfBitImgMo)) {
+ nNext=aHead.GetOffset();
+ while (nNext && !bRdFlag && !rInp.GetError() && !rOut.GetError()) {
+ rInp.Seek(nFileStart+nNext);
+ rInp>>aEntr;
+ nNext=aEntr.GetOffset();
+ if (aEntr.Typ==aHead.Typ) {
+ bRdFlag=TRUE;
+ switch(aEntr.Typ) {
+ case SgfBitImag0:
+ case SgfBitImag1:
+ case SgfBitImag2:
+ case SgfBitImgMo: bRet=SgfFilterBMap(rInp,rOut,aHead,aEntr); break;
+ }
+ }
+ } // while(nNext)
+ }
+ if (rInp.GetError()) bRet=FALSE;
+ return(bRet);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SgfVectFilter ///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Fuer StarDraw Embedded SGF-Vector
+long SgfVectXofs=0;
+long SgfVectYofs=0;
+long SgfVectXmul=0;
+long SgfVectYmul=0;
+long SgfVectXdiv=0;
+long SgfVectYdiv=0;
+BOOL SgfVectScal=FALSE;
+
+////////////////////////////////////////////////////////////
+// Hpgl2SvFarbe ////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+
+Color Hpgl2SvFarbe( BYTE nFarb )
+{
+ ULONG nColor = COL_BLACK;
+
+ switch (nFarb & 0x07) {
+ case 0: nColor=COL_WHITE; break;
+ case 1: nColor=COL_YELLOW; break;
+ case 2: nColor=COL_LIGHTMAGENTA; break;
+ case 3: nColor=COL_LIGHTRED; break;
+ case 4: nColor=COL_LIGHTCYAN; break;
+ case 5: nColor=COL_LIGHTGREEN; break;
+ case 6: nColor=COL_LIGHTBLUE; break;
+ case 7: nColor=COL_BLACK; break;
+ }
+ Color aColor( nColor );
+ return aColor;
+}
+
+/*************************************************************************
+|*
+|* SgfFilterVect()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfFilterVect(SvStream& rInp, SgfHeader& rHead, SgfEntry&, GDIMetaFile& rMtf)
+{
+ VirtualDevice aOutDev;
+ SgfVector aVect;
+ BYTE nFarb;
+ BYTE nFrb0=7;
+ BYTE nLTyp;
+ BYTE nOTyp;
+ BOOL bEoDt=FALSE;
+ BOOL bPDwn=FALSE;
+ Point aP0(0,0);
+ Point aP1(0,0);
+ String Msg;
+ USHORT RecNr=0;
+
+ rMtf.Record(&aOutDev);
+ aOutDev.SetLineColor(Color(COL_BLACK));
+ aOutDev.SetFillColor(Color(COL_BLACK));
+
+ while (!bEoDt && !rInp.GetError()) {
+ rInp>>aVect; RecNr++;
+ nFarb=(BYTE) (aVect.Flag & 0x000F);
+ nLTyp=(BYTE)((aVect.Flag & 0x00F0) >>4);
+ nOTyp=(BYTE)((aVect.Flag & 0x0F00) >>8);
+ bEoDt=(aVect.Flag & 0x4000) !=0;
+ bPDwn=(aVect.Flag & 0x8000) !=0;
+
+ long x=aVect.x-rHead.Xoffs;
+ long y=rHead.Ysize-(aVect.y-rHead.Yoffs);
+ if (SgfVectScal) {
+ if (SgfVectXdiv==0) SgfVectXdiv=rHead.Xsize;
+ if (SgfVectYdiv==0) SgfVectYdiv=rHead.Ysize;
+ if (SgfVectXdiv==0) SgfVectXdiv=1;
+ if (SgfVectYdiv==0) SgfVectYdiv=1;
+ x=SgfVectXofs+ x *SgfVectXmul /SgfVectXdiv;
+ y=SgfVectYofs+ y *SgfVectXmul /SgfVectYdiv;
+ }
+ aP1=Point(x,y);
+ if (!bEoDt && !rInp.GetError()) {
+ if (bPDwn && nLTyp<=6) {
+ switch(nOTyp) {
+ case 1: if (nFarb!=nFrb0) {
+ switch(rHead.SwGrCol) {
+ case SgfVectFarb: aOutDev.SetLineColor(Hpgl2SvFarbe(nFarb)); break;
+ case SgfVectGray: break;
+ case SgfVectWdth: break;
+ }
+ }
+ aOutDev.DrawLine(aP0,aP1); break; // Linie
+ case 2: break; // Kreis
+ case 3: break; // Text
+ case 5: aOutDev.DrawRect(Rectangle(aP0,aP1)); break; // Rechteck (solid)
+ }
+ }
+ aP0=aP1;
+ nFrb0=nFarb;
+ }
+ }
+ rMtf.Stop();
+ rMtf.WindStart();
+ MapMode aMap( MAP_10TH_MM, Point(),
+ Fraction( 1, 4 ), Fraction( 1, 4 ) );
+ rMtf.SetPrefMapMode( aMap );
+ rMtf.SetPrefSize( Size( (short)rHead.Xsize, (short)rHead.Ysize ) );
+ return TRUE;
+}
+
+
+/*************************************************************************
+|*
+|* SgfVectFilter()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfVectFilter(SvStream& rInp, GDIMetaFile& rMtf)
+{
+ ULONG nFileStart; // Offset des SgfHeaders. Im allgemeinen 0.
+ SgfHeader aHead;
+ SgfEntry aEntr;
+ ULONG nNext;
+ BOOL bRdFlag=FALSE; // Grafikentry gelesen ?
+ BOOL bRet=FALSE; // Returncode
+
+ nFileStart=rInp.Tell();
+ rInp>>aHead;
+ if (aHead.ChkMagic() && aHead.Typ==SGF_SIMPVECT) {
+ nNext=aHead.GetOffset();
+ while (nNext && !bRdFlag && !rInp.GetError()) {
+ rInp.Seek(nFileStart+nNext);
+ rInp>>aEntr;
+ nNext=aEntr.GetOffset();
+ if (aEntr.Typ==aHead.Typ) {
+ bRet=SgfFilterVect(rInp,aHead,aEntr,rMtf);
+ }
+ } // while(nNext)
+ if (bRdFlag) {
+ if (!rInp.GetError()) bRet=TRUE; // Scheinbar Ok
+ }
+ }
+ return(bRet);
+}
+
+
+/*************************************************************************
+|*
+|* SgfFilterPScr()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfFilterPScr(SvStream&, SgfHeader&, SgfEntry&)
+{
+ return FALSE; // PostSrcipt wird noch nicht unterstuetzt !
+}
+
+
+/*************************************************************************
+|*
+|* CheckSgfTyp()
+|*
+|* Beschreibung Feststellen, um was fuer ein SGF/SGV es sich handelt.
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BYTE CheckSgfTyp(SvStream& rInp, USHORT& nVersion)
+{
+#if OSL_DEBUG_LEVEL > 1 // Recordgroessen checken. Neuer Compiler hat vielleichte anderes Allignment!
+ if (sizeof(SgfHeader)!=SgfHeaderSize ||
+ sizeof(SgfEntry) !=SgfEntrySize ||
+ sizeof(SgfVector)!=SgfVectorSize ||
+ sizeof(BmpFileHeader)!=BmpFileHeaderSize ||
+ sizeof(BmpInfoHeader)!=BmpInfoHeaderSize ||
+ sizeof(RGBQuad )!=RGBQuadSize ) return SGF_DONTKNOW;
+#endif
+
+ ULONG nPos;
+ SgfHeader aHead;
+ nVersion=0;
+ nPos=rInp.Tell();
+ rInp>>aHead;
+ rInp.Seek(nPos);
+ if (aHead.ChkMagic()) {
+ nVersion=aHead.Version;
+ switch(aHead.Typ) {
+ case SgfBitImag0:
+ case SgfBitImag1:
+ case SgfBitImag2:
+ case SgfBitImgMo: return SGF_BITIMAGE;
+ case SgfSimpVect: return SGF_SIMPVECT;
+ case SgfPostScrp: return SGF_POSTSCRP;
+ case SgfStarDraw: return SGF_STARDRAW;
+ default : return SGF_DONTKNOW;
+ }
+ } else {
+ return SGF_DONTKNOW;
+ }
+}
diff --git a/svtools/source/filter.vcl/filter/sgvmain.cxx b/svtools/source/filter.vcl/filter/sgvmain.cxx
new file mode 100644
index 000000000000..e175380244b3
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/sgvmain.cxx
@@ -0,0 +1,1143 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <rtl/math.hxx>
+#include <osl/endian.h>
+#include <vcl/graph.hxx>
+#include <tools/poly.hxx>
+#include <svtools/filter.hxx>
+#include "sgffilt.hxx"
+#include "sgfbram.hxx"
+#include "sgvmain.hxx"
+#include "sgvspln.hxx"
+#include <unotools/ucbstreamhelper.hxx>
+
+//#if OSL_DEBUG_LEVEL > 1
+//#include "Debug.c"
+//#endif
+
+#define SWAPPOINT(p) { \
+ p.x=SWAPSHORT(p.x); \
+ p.y=SWAPSHORT(p.y); }
+
+#define SWAPPAGE(p) { \
+ p.Next =SWAPLONG (p.Next ); \
+ p.nList =SWAPLONG (p.nList ); \
+ p.ListEnd=SWAPLONG (p.ListEnd); \
+ p.Paper.Size.x=SWAPSHORT(p.Paper.Size.x); \
+ p.Paper.Size.y=SWAPSHORT(p.Paper.Size.y); \
+ p.Paper.RandL =SWAPSHORT(p.Paper.RandL ); \
+ p.Paper.RandR =SWAPSHORT(p.Paper.RandR ); \
+ p.Paper.RandO =SWAPSHORT(p.Paper.RandO ); \
+ p.Paper.RandU =SWAPSHORT(p.Paper.RandU ); \
+ SWAPPOINT(p.U); \
+ UINT16 iTemp; \
+ for (iTemp=0;iTemp<20;iTemp++) { \
+ rPage.HlpLnH[iTemp]=SWAPSHORT(rPage.HlpLnH[iTemp]); \
+ rPage.HlpLnV[iTemp]=SWAPSHORT(rPage.HlpLnV[iTemp]); }}
+
+#define SWAPOBJK(o) { \
+ o.Last =SWAPLONG (o.Last ); \
+ o.Next =SWAPLONG (o.Next ); \
+ o.MemSize =SWAPSHORT(o.MemSize ); \
+ SWAPPOINT(o.ObjMin); \
+ SWAPPOINT(o.ObjMax); }
+
+#define SWAPLINE(l) { \
+ l.LMSize=SWAPSHORT(l.LMSize); \
+ l.LDicke=SWAPSHORT(l.LDicke); }
+
+#define SWAPAREA(a) { \
+ a.FDummy2=SWAPSHORT(a.FDummy2); \
+ a.FMuster=SWAPSHORT(a.FMuster); }
+
+#define SWAPTEXT(t) { \
+ SWAPLINE(t.L); \
+ SWAPAREA(t.F); \
+ t.FontLo =SWAPSHORT(t.FontLo ); \
+ t.FontHi =SWAPSHORT(t.FontHi ); \
+ t.Grad =SWAPSHORT(t.Grad ); \
+ t.Breite =SWAPSHORT(t.Breite ); \
+ t.Schnitt=SWAPSHORT(t.Schnitt); \
+ t.LnFeed =SWAPSHORT(t.LnFeed ); \
+ t.Slant =SWAPSHORT(t.Slant ); \
+ SWAPLINE(t.ShdL); \
+ SWAPAREA(t.ShdF); \
+ SWAPPOINT(t.ShdVers); \
+ SWAPAREA(t.BackF); }
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Einschraenkungen:
+//
+// - Flaechenmuster werden den unter StarView verfuegbaren Mustern angenaehert.
+// - Linienenden werden unter StarView immer rund dargestellt und gehen ueber
+// den Endpunkt der Linie hinaus.
+// - Linienmuster werden den unter StarView verfuegbaren Mustern angenaehert.
+// Transparent/Opak wird zur Zeit noch nicht beruecksichtigt.
+// - Keine gedrehten Ellipsen
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if defined( WIN ) && defined( MSC )
+#pragma code_seg( "svtools", "AUTO_CODE" )
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Fuer Fontuebersetzung ///////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+SgfFontLst* pSgfFonts = 0;
+
+#if defined( WIN ) && defined( MSC )
+#pragma code_seg( "SVTOOLS_FILTER3", "SVTOOLS_CODE" )
+static void AntiMscBug() {}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Fuer Kreisunterarten, Text und gedrehte Rechtecke ///////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void RotatePoint(PointType& P, INT16 cx, INT16 cy, double sn, double cs)
+{
+ INT16 dx,dy;
+ double x1,y1;
+ dx=P.x-cx;
+ dy=P.y-cy;
+ x1=dx*cs-dy*sn;
+ y1=dy*cs+dx*sn;
+ P.x=cx+INT16(x1);
+ P.y=cy+INT16(y1);
+}
+
+void RotatePoint(Point& P, INT16 cx, INT16 cy, double sn, double cs)
+{
+ INT16 dx,dy;
+ double x1,y1;
+ dx=(INT16)(P.X()-cx);
+ dy=(INT16)(P.Y()-cy);
+ x1=dx*cs-dy*sn;
+ y1=dy*cs+dx*sn;
+ P=Point(cx+INT16(x1),cy+INT16(y1));
+}
+
+INT16 iMulDiv(INT16 a, INT16 Mul, INT16 Div)
+{
+ INT32 Temp;
+ Temp=INT32(a)*INT32(Mul)/INT32(Div);
+ return INT16(Temp);
+}
+
+UINT16 MulDiv(UINT16 a, UINT16 Mul, UINT16 Div)
+{
+ UINT32 Temp;
+ Temp=UINT32(a)*UINT32(Mul)/UINT32(Div);
+ return UINT16(Temp);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SgfFilterSDrw ///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>(SvStream& rIStream, DtHdType& rDtHd)
+{
+ rIStream.Read((char*)&rDtHd.Reserved[0],DtHdSize);
+ return rIStream;
+}
+
+void DtHdOverSeek(SvStream& rInp)
+{
+ ULONG FPos=rInp.Tell();
+ FPos+=(ULONG)DtHdSize;
+ rInp.Seek(FPos);
+// rInp.seekg(rInp.tellg()+(ULONG)DtHdSize);
+}
+
+
+SvStream& operator>>(SvStream& rIStream, PageType& rPage)
+{
+ rIStream.Read((char*)&rPage.Next,PageSize);
+#if defined OSL_BIGENDIAN
+ SWAPPAGE(rPage);
+#endif
+ return rIStream;
+}
+
+void ObjkOverSeek(SvStream& rInp, ObjkType& rObjk)
+{
+ ULONG Siz;
+ Siz=(ULONG)rObjk.MemSize+rObjk.Last; // ObjSize+ObjAnhSize
+ rInp.Seek(rInp.Tell()+Siz);
+}
+
+SvStream& operator>>(SvStream& rInp, ObjkType& rObjk)
+{ // Die Fileposition im Stream bleibt unveraendert!
+ ULONG nPos;
+ nPos=rInp.Tell();
+ rInp.Read((char*)&rObjk.Last,ObjkSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK(rObjk);
+#endif
+#ifdef InArbeit
+ ULONG nPos1=rInp.Tell();
+ if(nPos == nPos1) InfoBox( NULL, "tellg funkt nich" ).Execute();
+#endif
+ rInp.Seek(nPos);
+#ifdef InArbeit
+ if (rInp.Tell() != nPos) InfoBox( NULL, "seekg funkt nich" ).Execute();
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, StrkType& rStrk)
+{
+ rInp.Read((char*)&rStrk.Last,StrkSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rStrk);
+ SWAPLINE (rStrk.L);
+ SWAPPOINT(rStrk.Pos1);
+ SWAPPOINT(rStrk.Pos2);
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, RectType& rRect)
+{
+ rInp.Read((char*)&rRect.Last,RectSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rRect);
+ SWAPLINE (rRect.L);
+ SWAPAREA (rRect.F);
+ SWAPPOINT(rRect.Pos1);
+ SWAPPOINT(rRect.Pos2);
+ rRect.Radius =SWAPSHORT(rRect.Radius );
+ rRect.DrehWink=SWAPSHORT(rRect.DrehWink);
+ rRect.Slant =SWAPSHORT(rRect.Slant );
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, PolyType& rPoly)
+{
+ rInp.Read((char*)&rPoly.Last,PolySize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rPoly);
+ SWAPLINE (rPoly.L);
+ SWAPAREA (rPoly.F);
+ // rPoly.EckP=SWAPLONG(rPoly.EckP);
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, SplnType& rSpln)
+{
+ rInp.Read((char*)&rSpln.Last,SplnSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rSpln);
+ SWAPLINE (rSpln.L);
+ SWAPAREA (rSpln.F);
+ // rSpln.EckP=SWAPLONG(rSpln.EckP);
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, CircType& rCirc)
+{
+ rInp.Read((char*)&rCirc.Last,CircSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rCirc);
+ SWAPLINE (rCirc.L);
+ SWAPAREA (rCirc.F);
+ SWAPPOINT(rCirc.Radius);
+ SWAPPOINT(rCirc.Center);
+ rCirc.DrehWink =SWAPSHORT(rCirc.DrehWink );
+ rCirc.StartWink=SWAPSHORT(rCirc.StartWink);
+ rCirc.RelWink =SWAPSHORT(rCirc.RelWink );
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, TextType& rText)
+{
+ rInp.Read((char*)&rText.Last,TextSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rText);
+ SWAPTEXT (rText.T);
+ SWAPPOINT(rText.Pos1);
+ SWAPPOINT(rText.Pos2);
+ rText.TopOfs =SWAPSHORT(rText.TopOfs );
+ rText.DrehWink=SWAPSHORT(rText.DrehWink);
+ rText.BoxSlant=SWAPSHORT(rText.BoxSlant);
+ rText.BufSize =SWAPSHORT(rText.BufSize );
+ //rText.Buf =SWAPLONG (rText.Buf );
+ //rText.Ext =SWAPLONG (rText.Ext );
+ SWAPPOINT(rText.FitSize);
+ rText.FitBreit=SWAPSHORT(rText.FitBreit);
+#endif
+ rText.Buffer=NULL;
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, BmapType& rBmap)
+{
+ rInp.Read((char*)&rBmap.Last,BmapSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rBmap);
+ SWAPAREA (rBmap.F);
+ SWAPPOINT(rBmap.Pos1);
+ SWAPPOINT(rBmap.Pos2);
+ rBmap.DrehWink=SWAPSHORT(rBmap.DrehWink);
+ rBmap.Slant =SWAPSHORT(rBmap.Slant );
+ SWAPPOINT(rBmap.PixSize);
+#endif
+ return rInp;
+}
+SvStream& operator>>(SvStream& rInp, GrupType& rGrup)
+{
+ rInp.Read((char*)&rGrup.Last,GrupSize);
+#if defined OSL_BIGENDIAN
+ SWAPOBJK (rGrup);
+ rGrup.SbLo =SWAPSHORT(rGrup.SbLo );
+ rGrup.SbHi =SWAPSHORT(rGrup.SbHi );
+ rGrup.UpLo =SWAPSHORT(rGrup.UpLo );
+ rGrup.UpHi =SWAPSHORT(rGrup.UpHi );
+ rGrup.ChartSize=SWAPSHORT(rGrup.ChartSize);
+ rGrup.ChartPtr =SWAPLONG (rGrup.ChartPtr );
+#endif
+ return rInp;
+}
+
+
+
+/*************************************************************************
+|*
+|* Sgv2SvFarbe()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+Color Sgv2SvFarbe(BYTE nFrb1, BYTE nFrb2, BYTE nInts)
+{
+ UINT16 r1=0,g1=0,b1=0,r2=0,g2=0,b2=0;
+ BYTE nInt2=100-nInts;
+ switch(nFrb1 & 0x07) {
+ case 0: r1=0xFF; g1=0xFF; b1=0xFF; break;
+ case 1: r1=0xFF; g1=0xFF; break;
+ case 2: g1=0xFF; b1=0xFF; break;
+ case 3: g1=0xFF; break;
+ case 4: r1=0xFF; b1=0xFF; break;
+ case 5: r1=0xFF; break;
+ case 6: b1=0xFF; break;
+ case 7: break;
+ }
+ switch(nFrb2 & 0x07) {
+ case 0: r2=0xFF; g2=0xFF; b2=0xFF; break;
+ case 1: r2=0xFF; g2=0xFF; break;
+ case 2: g2=0xFF; b2=0xFF; break;
+ case 3: g2=0xFF; break;
+ case 4: r2=0xFF; b2=0xFF; break;
+ case 5: r2=0xFF; break;
+ case 6: b2=0xFF; break;
+ case 7: break;
+ }
+ r1=(UINT16)((UINT32)r1*nInts/100+(UINT32)r2*nInt2/100);
+ g1=(UINT16)((UINT32)g1*nInts/100+(UINT32)g2*nInt2/100);
+ b1=(UINT16)((UINT32)b1*nInts/100+(UINT32)b2*nInt2/100);
+ Color aColor( (sal_uInt8)r1, (sal_uInt8)g1, (sal_uInt8)b1 );
+ return aColor;
+}
+
+void SetLine(ObjLineType& rLine, OutputDevice& rOut)
+{
+/* !!!
+ PenStyle aStyle=PEN_SOLID;
+ switch(rLine.LMuster & 0x07) {
+ case 0: aStyle=PEN_NULL; break;
+ case 1: aStyle=PEN_SOLID; break;
+ case 2: aStyle=PEN_DOT; break; // . . . . . . . . . . . . . .
+ case 3: aStyle=PEN_DASH; break; // __ __ __ __ __ __ __ __ __
+ case 4: aStyle=PEN_DASH; break; // ___ ___ ___ ___ ___ ___ ___
+ case 5: aStyle=PEN_DASHDOT; break; // __ . __ . __ . __ . __ . __
+ case 6: aStyle=PEN_DASHDOT; break; // __ _ __ _ __ _ __ _ __ _ __
+ case 7: aStyle=PEN_DASHDOT; break; // ___ _ _ ___ _ _ ___ _ _ ___
+ }
+ Pen aPen(Sgv2SvFarbe(rLine.LFarbe,rLine.LBFarbe,rLine.LIntens),rLine.LDicke,aStyle);
+ SetPen(aPen,rOut);
+*/
+ if( 0 == ( rLine.LMuster & 0x07 ) )
+ rOut.SetLineColor();
+ else
+ rOut.SetLineColor( Sgv2SvFarbe(rLine.LFarbe,rLine.LBFarbe,rLine.LIntens) );
+}
+
+void SetArea(ObjAreaType& rArea, OutputDevice& rOut)
+{
+/*
+ BrushStyle aStyle=BRUSH_SOLID;
+ switch(rArea.FMuster & 0x00FF) {
+ case 0: aStyle=BRUSH_NULL; break;
+ case 1: aStyle=BRUSH_SOLID; break;
+ case 2: case 4: case 6: case 8:
+ case 10: case 12: case 14: case 16:
+ case 43: case 45: aStyle=BRUSH_VERT; break;
+ case 3: case 5: case 7: case 9:
+ case 11: case 13: case 15: case 17:
+ case 42: case 44: aStyle=BRUSH_HORZ; break;
+ case 18: case 20: case 22: case 24:
+ case 26: case 28: case 30: case 32:
+ case 46: case 48: aStyle=BRUSH_UPDIAG; break;
+ case 19: case 21: case 23: case 25:
+ case 27: case 29: case 31: case 33:
+ case 47: case 49: aStyle=BRUSH_DOWNDIAG; break;
+ case 34: case 35: case 36: case 37: aStyle=BRUSH_CROSS; break;
+ case 38: case 39: case 40: case 41: aStyle=BRUSH_DIAGCROSS; break;
+ default: aStyle=BRUSH_DIAGCROSS; break;
+ }
+ Brush aBrush(Sgv2SvFarbe(rArea.FFarbe,rArea.FBFarbe,rArea.FIntens),aStyle);
+ aBrush.SetTransparent((rArea.FMuster & 0x80) !=0L);
+ SetBrush(aBrush,rOut);
+*/
+ if( 0 == ( rArea.FMuster & 0x00FF ) )
+ rOut.SetFillColor();
+ else
+ rOut.SetFillColor( Sgv2SvFarbe( rArea.FFarbe,rArea.FBFarbe,rArea.FIntens ) );
+}
+
+/*************************************************************************
+|*
+|* ObjkType::DrawObjekt()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void ObjkType::Draw(OutputDevice&)
+{
+// ShowSDObjk(*this);
+}
+
+void Obj0Type::Draw(OutputDevice&) {}
+
+/*************************************************************************
+|*
+|* StrkType::DrawObjekt()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void StrkType::Draw(OutputDevice& rOut)
+{
+ SetLine(L,rOut);
+ rOut.DrawLine(Point(Pos1.x,Pos1.y),Point(Pos2.x,Pos2.y)); // !!!
+}
+
+/*************************************************************************
+|*
+|* RectType::DrawObjekt()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void SgfAreaColorIntens(UINT16 Muster, BYTE Col1, BYTE Col2, BYTE Int, OutputDevice& rOut)
+{
+ ObjAreaType F;
+ F.FMuster=Muster;
+ F.FFarbe=Col2;
+ F.FBFarbe=Col1;
+ F.FIntens=Int;
+ SetArea(F,rOut);
+}
+
+void DrawSlideRect(INT16 x1, INT16 y1, INT16 x2, INT16 y2, ObjAreaType& F, OutputDevice& rOut)
+{
+ INT16 i,i0,b,b0;
+ INT16 Int1,Int2;
+ INT16 Col1,Col2;
+ // ClipMerk: HgdClipRec;
+ INT16 cx,cy;
+ INT16 MaxR;
+ INT32 dx,dy;
+
+ rOut.SetLineColor();
+ if (x1>x2) { i=x1; x1=x2; x2=i; }
+ if (y1>y2) { i=y1; y1=y2; y2=i; }
+ Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
+ Int1=100-F.FIntens; Int2=F.FIntens;
+ if (Int1==Int2) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int2,rOut);
+ rOut.DrawRect(Rectangle(x1,y1,x2,y2));
+ } else {
+ b0=Int1;
+ switch (F.FBFarbe & 0x38) {
+ case 0x08: { // vertikal
+ i0=y1;
+ i=y1;
+ while (i<=y2) {
+ b=Int1+INT16((INT32)(Int2-Int1)*(INT32)(i-y1) /(INT32)(y2-y1+1));
+ if (b!=b0) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)b0,rOut);
+ rOut.DrawRect(Rectangle(x1,i0,x2,i-1));
+ i0=i; b0=b;
+ }
+ i++;
+ }
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int2,rOut);
+ rOut.DrawRect(Rectangle(x1,i0,x2,y2));
+ } break;
+ case 0x28: { // horizontal
+ i0=x1;
+ i=x1;
+ while (i<=x2) {
+ b=Int1+INT16((INT32)(Int2-Int1)*(INT32)(i-x1) /(INT32)(x2-x1+1));
+ if (b!=b0) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)b0,rOut);
+ rOut.DrawRect(Rectangle(i0,y1,i-1,y2));
+ i0=i; b0=b;
+ }
+ i++;
+ }
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int2,rOut);
+ rOut.DrawRect(Rectangle(i0,y1,x2,y2));
+ } break;
+
+ case 0x18: case 0x38: { // Kreis
+ Region ClipMerk=rOut.GetClipRegion();
+ double a;
+
+ rOut.SetClipRegion(Region(Rectangle(x1,y1,x2,y2)));
+ cx=(x1+x2) /2;
+ cy=(y1+y2) /2;
+ dx=x2-x1+1;
+ dy=y2-y1+1;
+ a=sqrt((double)(dx*dx+dy*dy));
+ MaxR=INT16(a) /2 +1;
+ b0=Int2;
+ i0=MaxR; if (MaxR<1) MaxR=1;
+ i=MaxR;
+ while (i>=0) {
+ b=Int1+INT16((INT32(Int2-Int1)*INT32(i)) /INT32(MaxR));
+ if (b!=b0) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)b0,rOut);
+ //if (i0>200 || (Col1 & $80)!=0 || (Col2 & $80)!=0) {
+ // then begin { Fallunterscheidung fuer etwas bessere Performance }
+ // s2:=i0-i+2;
+ // SetPenSize(s2);
+ // s2:=s2 div 2;
+ // Circle(cx,cy,i0-s2,i0-s2);{}
+ // else
+ rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
+ i0=i; b0=b;
+ }
+ i--;
+ }
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int1,rOut);
+ rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
+ rOut.SetClipRegion(ClipMerk);
+ } break; // Kreis
+ }
+ }
+}
+
+
+void RectType::Draw(OutputDevice& rOut)
+{
+ if (L.LMuster!=0) L.LMuster=1; // keine Linienmuster hier, nur an oder aus
+ SetArea(F,rOut);
+ if (DrehWink==0) {
+ if ((F.FBFarbe & 0x38)==0 || Radius!=0) {
+ SetLine(L,rOut);
+ rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y),Radius,Radius);
+ } else {
+ DrawSlideRect(Pos1.x,Pos1.y,Pos2.x,Pos2.y,F,rOut);
+ if (L.LMuster!=0) {
+ SetLine(L,rOut);
+ rOut.SetFillColor();
+ rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y));
+ }
+ }
+ } else {
+ Point aPts[4];
+ USHORT i;
+ double sn,cs;
+ sn=sin(double(DrehWink)*3.14159265359/18000);
+ cs=cos(double(DrehWink)*3.14159265359/18000);
+ aPts[0]=Point(Pos1.x,Pos1.y);
+ aPts[1]=Point(Pos2.x,Pos1.y);
+ aPts[2]=Point(Pos2.x,Pos2.y);
+ aPts[3]=Point(Pos1.x,Pos2.y);
+ for (i=0;i<4;i++) {
+ RotatePoint(aPts[i],Pos1.x,Pos1.y,sn,cs);
+ }
+ SetLine(L,rOut);
+ Polygon aPoly(4,aPts);
+ rOut.DrawPolygon(aPoly);
+ }
+}
+
+/*************************************************************************
+|*
+|* PolyType::Draw()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void PolyType::Draw(OutputDevice& rOut)
+{
+ if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
+ SetLine(L,rOut);
+ Polygon aPoly(nPoints);
+ USHORT i;
+ for(i=0;i<nPoints;i++) aPoly.SetPoint(Point(EckP[i].x,EckP[i].y),i);
+ if ((Flags & PolyClosBit) !=0) {
+ rOut.DrawPolygon(aPoly);
+ } else {
+ rOut.DrawPolyLine(aPoly);
+ }
+}
+
+/*************************************************************************
+|*
+|* SplnType::Draw()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void SplnType::Draw(OutputDevice& rOut)
+{
+ if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
+ SetLine(L,rOut);
+ Polygon aPoly(0);
+ Polygon aSpln(nPoints);
+ USHORT i;
+ for(i=0;i<nPoints;i++) aSpln.SetPoint(Point(EckP[i].x,EckP[i].y),i);
+ if ((Flags & PolyClosBit) !=0) {
+ Spline2Poly(aSpln,TRUE,aPoly);
+ if (aPoly.GetSize()>0) rOut.DrawPolygon(aPoly);
+ } else {
+ Spline2Poly(aSpln,FALSE,aPoly);
+ if (aPoly.GetSize()>0) rOut.DrawPolyLine(aPoly);
+ }
+}
+
+/*************************************************************************
+|*
+|* CircType::Draw()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void DrawSlideCirc(INT16 cx, INT16 cy, INT16 rx, INT16 ry, ObjAreaType& F, OutputDevice& rOut)
+{
+ INT16 x1=cx-rx;
+ INT16 y1=cy-ry;
+ INT16 x2=cx+rx;
+ INT16 y2=cy+ry;
+
+ INT16 i,i0,b,b0;
+ INT16 Int1,Int2;
+ INT16 Col1,Col2;
+
+ rOut.SetLineColor();
+ Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
+ Int1=100-F.FIntens; Int2=F.FIntens;
+ if (Int1==Int2) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int2,rOut);
+ rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
+ } else {
+ b0=Int1;
+ switch (F.FBFarbe & 0x38) {
+ case 0x08: { // vertikal
+ Region ClipMerk=rOut.GetClipRegion();
+ i0=y1;
+ i=y1;
+ while (i<=y2) {
+ b=Int1+INT16((INT32)(Int2-Int1)*(INT32)(i-y1) /(INT32)(y2-y1+1));
+ if (b!=b0) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)b0,rOut);
+ rOut.SetClipRegion(Rectangle(x1,i0,x2,i-1));
+ rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
+ i0=i; b0=b;
+ }
+ i++;
+ }
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int2,rOut);
+ rOut.SetClipRegion(Rectangle(x1,i0,x2,y2));
+ rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
+ rOut.SetClipRegion(ClipMerk);
+ } break;
+ case 0x28: { // horizontal
+ Region ClipMerk=rOut.GetClipRegion();
+ i0=x1;
+ i=x1;
+ while (i<=x2) {
+ b=Int1+INT16((INT32)(Int2-Int1)*(INT32)(i-x1) /(INT32)(x2-x1+1));
+ if (b!=b0) {
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)b0,rOut);
+ rOut.SetClipRegion(Rectangle(i0,y1,i-1,y2));
+ rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
+ i0=i; b0=b;
+ }
+ i++;
+ }
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int2,rOut);
+ rOut.SetClipRegion(Rectangle(i0,y1,x2,y2));
+ rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
+ rOut.SetClipRegion(ClipMerk);
+ } break;
+
+ case 0x18: case 0x38: { // Kreis
+ INT16 MaxR;
+
+ if (rx<1) rx=1;
+ if (ry<1) ry=1;
+ MaxR=rx;
+ b0=Int2;
+ i0=MaxR; if (MaxR<1) MaxR=1;
+ i=MaxR;
+ while (i>=0) {
+ b=Int1+INT16((INT32(Int2-Int1)*INT32(i)) /INT32(MaxR));
+ if (b!=b0) {
+ INT32 temp=INT32(i0)*INT32(ry)/INT32(rx);
+ INT16 j0=INT16(temp);
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)b0,rOut);
+ rOut.DrawEllipse(Rectangle(cx-i0,cy-j0,cx+i0,cy+j0));
+ i0=i; b0=b;
+ }
+ i--;
+ }
+ SgfAreaColorIntens(F.FMuster,(BYTE)Col1,(BYTE)Col2,(BYTE)Int1,rOut);
+ rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
+ } break; // Kreis
+ }
+ }
+}
+
+
+void CircType::Draw(OutputDevice& rOut)
+{
+ Rectangle aRect(Center.x-Radius.x,Center.y-Radius.y,Center.x+Radius.x,Center.y+Radius.y);
+
+ if (L.LMuster!=0) L.LMuster=1; // keine Linienmuster hier, nur an oder aus
+ SetArea(F,rOut);
+ if ((Flags & 0x03)==CircFull) {
+ if ((F.FBFarbe & 0x38)==0) {
+ SetLine(L,rOut);
+ rOut.DrawEllipse(aRect);
+ } else {
+ DrawSlideCirc(Center.x,Center.y,Radius.x,Radius.y,F,rOut);
+ if (L.LMuster!=0) {
+ SetLine(L,rOut);
+ rOut.SetFillColor();
+ rOut.DrawEllipse(aRect);
+ }
+ }
+ } else {
+ PointType a,b;
+ Point aStrt,aEnde;
+ double sn,cs;
+
+ a.x=Center.x+Radius.x; a.y=Center.y; b=a;
+ sn=sin(double(StartWink)*3.14159265359/18000);
+ cs=cos(double(StartWink)*3.14159265359/18000);
+ RotatePoint(a,Center.x,Center.y,sn,cs);
+ sn=sin(double(StartWink+RelWink)*3.14159265359/18000);
+ cs=cos(double(StartWink+RelWink)*3.14159265359/18000);
+ RotatePoint(b,Center.x,Center.y,sn,cs);
+ if (Radius.x!=Radius.y) {
+ if (Radius.x<1) Radius.x=1;
+ if (Radius.y<1) Radius.y=1;
+ a.y = a.y - Center.y;
+ b.y = b.y - Center.y;
+ a.y=iMulDiv(a.y,Radius.y,Radius.x);
+ b.y=iMulDiv(b.y,Radius.y,Radius.x);
+ a.y = a.y + Center.y;
+ b.y = b.y + Center.y;
+ }
+ aStrt=Point(a.x,a.y);
+ aEnde=Point(b.x,b.y);
+ SetLine(L,rOut);
+ switch (Flags & 0x03) {
+ case CircArc : rOut.DrawArc(aRect,aEnde,aStrt); break;
+ case CircSect:
+ case CircAbsn: rOut.DrawPie(aRect,aEnde,aStrt); break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* BmapType::Draw()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+
+void BmapType::Draw(OutputDevice& rOut)
+{
+ //ifstream aInp;
+ unsigned char nSgfTyp;
+ USHORT nVersion;
+ String aStr(
+ reinterpret_cast< char const * >(&Filename[ 1 ]),
+ (xub_StrLen)Filename[ 0 ], RTL_TEXTENCODING_UTF8 );
+ INetURLObject aFNam( aStr );
+
+ SvStream* pInp = ::utl::UcbStreamHelper::CreateStream( aFNam.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
+ if ( pInp )
+ {
+ nSgfTyp=CheckSgfTyp( *pInp,nVersion);
+ switch(nSgfTyp) {
+ case SGF_BITIMAGE: {
+ GraphicFilter aFlt;
+ Graphic aGrf;
+ USHORT nRet;
+ nRet=aFlt.ImportGraphic(aGrf,aFNam);
+ aGrf.Draw(&rOut,Point(Pos1.x,Pos1.y),Size(Pos2.x-Pos1.x,Pos2.y-Pos1.y));
+ } break;
+ case SGF_SIMPVECT: {
+ GDIMetaFile aMtf;
+ SgfVectXofs=Pos1.x;
+ SgfVectYofs=Pos1.y;
+ SgfVectXmul=Pos2.x-Pos1.x;
+ SgfVectYmul=Pos2.y-Pos1.y;
+ SgfVectXdiv=0;
+ SgfVectYdiv=0;
+ SgfVectScal=TRUE;
+ SgfVectFilter(*pInp,aMtf);
+ SgfVectXofs=0;
+ SgfVectYofs=0;
+ SgfVectXmul=0;
+ SgfVectYmul=0;
+ SgfVectXdiv=0;
+ SgfVectYdiv=0;
+ SgfVectScal=FALSE;
+ aMtf.Play(&rOut);
+ } break;
+ }
+ delete pInp;
+ }
+}
+
+
+/*************************************************************************
+|*
+|* GrupType::...
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+UINT32 GrupType::GetSubPtr()
+{
+ return UINT32(SbLo)+0x00010000*UINT32(SbHi);
+}
+
+/*************************************************************************
+|*
+|* DrawObjkList()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void DrawObjkList( SvStream& rInp, OutputDevice& rOut )
+{
+ ObjkType aObjk;
+ USHORT nGrpCnt=0;
+ BOOL bEnde=FALSE;
+ do {
+ rInp>>aObjk;
+ if (!rInp.GetError()) {
+ switch(aObjk.Art) {
+ case ObjStrk: { StrkType aStrk; rInp>>aStrk; if (!rInp.GetError()) aStrk.Draw(rOut); } break;
+ case ObjRect: { RectType aRect; rInp>>aRect; if (!rInp.GetError()) aRect.Draw(rOut); } break;
+ case ObjCirc: { CircType aCirc; rInp>>aCirc; if (!rInp.GetError()) aCirc.Draw(rOut); } break;
+ case ObjText: {
+ TextType aText;
+ rInp>>aText;
+ if (!rInp.GetError()) {
+ aText.Buffer=new UCHAR[aText.BufSize+1]; // Ein mehr fuer LookAhead bei CK-Trennung
+ rInp.Read((char* )aText.Buffer,aText.BufSize);
+ if (!rInp.GetError()) aText.Draw(rOut);
+ delete[] aText.Buffer;
+ }
+ } break;
+ case ObjBmap: {
+ BmapType aBmap;
+ rInp>>aBmap;
+ if (!rInp.GetError()) {
+ aBmap.Draw(rOut);
+ }
+ } break;
+ case ObjPoly: {
+ PolyType aPoly;
+ rInp>>aPoly;
+ if (!rInp.GetError()) {
+ aPoly.EckP=new PointType[aPoly.nPoints];
+ rInp.Read((char*)aPoly.EckP,4*aPoly.nPoints);
+#if defined OSL_BIGENDIAN
+ for(short i=0;i<aPoly.nPoints;i++) SWAPPOINT(aPoly.EckP[i]);
+#endif
+ if (!rInp.GetError()) aPoly.Draw(rOut);
+ delete[] aPoly.EckP;
+ }
+ } break;
+ case ObjSpln: {
+ SplnType aSpln;
+ rInp>>aSpln;
+ if (!rInp.GetError()) {
+ aSpln.EckP=new PointType[aSpln.nPoints];
+ rInp.Read((char*)aSpln.EckP,4*aSpln.nPoints);
+#if defined OSL_BIGENDIAN
+ for(short i=0;i<aSpln.nPoints;i++) SWAPPOINT(aSpln.EckP[i]);
+#endif
+ if (!rInp.GetError()) aSpln.Draw(rOut);
+ delete[] aSpln.EckP;
+ }
+ } break;
+ case ObjGrup: {
+ GrupType aGrup;
+ rInp>>aGrup;
+ if (!rInp.GetError()) {
+ rInp.Seek(rInp.Tell()+aGrup.Last); // Obj-Anhaengsel
+ if(aGrup.GetSubPtr()!=0L) nGrpCnt++;// DrawObjkList(rInp,rOut );
+ }
+ } break;
+ default: {
+ aObjk.Draw(rOut); // Objektbezeichnung auf 2. Screen
+ ObjkOverSeek(rInp,aObjk); // zum naechsten Objekt
+ }
+ }
+ } // if rInp
+ if (!rInp.GetError()) {
+ if (aObjk.Next==0L) {
+ if (nGrpCnt==0) bEnde=TRUE;
+ else nGrpCnt--;
+ }
+ } else {
+ bEnde=TRUE; // Lesefehler
+ }
+ } while (!bEnde);
+}
+
+/*************************************************************************
+|*
+|* SkipObjkList()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+void SkipObjkList(SvStream& rInp)
+{
+ ObjkType aObjk;
+ do
+ {
+ rInp>>aObjk;
+ if(aObjk.Art==ObjGrup) {
+ GrupType aGrup;
+ rInp>>aGrup;
+ rInp.Seek(rInp.Tell()+aGrup.Last); // Obj-Anhaengsel
+ if(aGrup.GetSubPtr()!=0L) SkipObjkList(rInp);
+ } else {
+ ObjkOverSeek(rInp,aObjk); // zum naechsten Objekt
+ }
+ } while (aObjk.Next!=0L && !rInp.GetError());
+}
+
+/*************************************************************************
+|*
+|* SgfFilterSDrw()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfFilterSDrw( SvStream& rInp, SgfHeader&, SgfEntry&, GDIMetaFile& rMtf )
+{
+ BOOL bRet = FALSE;
+ PageType aPage;
+ VirtualDevice aOutDev;
+ OutputDevice* pOutDev;
+ ULONG nStdPos;
+ ULONG nZchPos;
+ USHORT Num;
+
+ pOutDev=&aOutDev;
+ DtHdOverSeek(rInp); // DataHeader weglesen
+
+ nStdPos=rInp.Tell();
+ do { // Standardseiten weglesen
+ rInp>>aPage;
+ if (aPage.nList!=0) SkipObjkList(rInp);
+ } while (aPage.Next!=0L && !rInp.GetError());
+
+// ShowMsg("Zeichnungseite(n)\n");
+ nZchPos=rInp.Tell();
+ rInp>>aPage;
+
+ rMtf.Record(pOutDev);
+ Num=aPage.StdPg;
+ if (Num!=0) {
+ rInp.Seek(nStdPos);
+ while(Num>1 && aPage.Next!=0L && !rInp.GetError()) { // Standardseite suchen
+ rInp>>aPage;
+ if (aPage.nList!=0) SkipObjkList(rInp);
+ Num--;
+ }
+ rInp>>aPage;
+ if(Num==1 && aPage.nList!=0L) DrawObjkList( rInp,*pOutDev );
+ rInp.Seek(nZchPos);
+ nZchPos=rInp.Tell();
+ rInp>>aPage;
+ }
+ if (aPage.nList!=0L) DrawObjkList(rInp,*pOutDev );
+
+ rMtf.Stop();
+ rMtf.WindStart();
+ MapMode aMap(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4));
+ rMtf.SetPrefMapMode(aMap);
+ rMtf.SetPrefSize(Size((INT16)aPage.Paper.Size.x,(INT16)aPage.Paper.Size.y));
+ bRet=TRUE;
+ return bRet;
+}
+
+
+
+/*************************************************************************
+|*
+|* SgfSDrwFilter()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL SgfSDrwFilter(SvStream& rInp, GDIMetaFile& rMtf, INetURLObject aIniPath )
+{
+#if OSL_DEBUG_LEVEL > 1 // Recordgroessen checken. Neuer Compiler hat vielleichte anderes Alignment!
+ if (sizeof(ObjTextType)!=ObjTextTypeSize) return FALSE;
+#endif
+
+ ULONG nFileStart; // Offset des SgfHeaders. Im allgemeinen 0.
+ SgfHeader aHead;
+ SgfEntry aEntr;
+ ULONG nNext;
+ BOOL bRdFlag=FALSE; // Grafikentry gelesen ?
+ BOOL bRet=FALSE; // Returncode
+
+ aIniPath.Append( String::CreateFromAscii( "sgf.ini", 7 ) );
+// aIniPath.ToAbs();
+
+ pSgfFonts = new SgfFontLst;
+
+ pSgfFonts->AssignFN( aIniPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ nFileStart=rInp.Tell();
+ rInp>>aHead;
+ if (aHead.ChkMagic() && aHead.Typ==SgfStarDraw && aHead.Version==SGV_VERSION) {
+ nNext=aHead.GetOffset();
+ while (nNext && !bRdFlag && !rInp.GetError()) {
+ rInp.Seek(nFileStart+nNext);
+ rInp>>aEntr;
+ nNext=aEntr.GetOffset();
+ if (aEntr.Typ==aHead.Typ) {
+ bRet=SgfFilterSDrw( rInp,aHead,aEntr,rMtf );
+ }
+ } // while(nNext)
+ if (bRdFlag) {
+ if (!rInp.GetError()) bRet=TRUE; // Scheinbar Ok
+ }
+ }
+ delete pSgfFonts;
+ return(bRet);
+}
+
+/*
+Bitmap Dither(BYTE Intens)
+{
+ Bitmap aBmp;
+ BmpInfoHeader Info;
+
+
+const dmatrix: array[0..7,0..7] of byte =
+ (( 0, 48, 12, 60, 3, 51, 15, 63 ),
+ ( 32, 16, 44, 28, 35, 19, 47, 31 ),
+ ( 8, 56, 4, 52, 11, 59, 7, 55 ),
+ ( 40, 24, 36, 20, 43, 27, 39, 23 ),
+ ( 2, 50, 14, 62, 1, 49, 13, 61 ),
+ ( 34, 18, 46, 30, 33, 17, 45, 29 ),
+ ( 10, 58, 6, 54, 9, 57, 5, 53 ),
+ ( 42, 26, 38, 22, 41, 25, 37, 21 ));
+
+
+ cmatrix: array[0..7,0..7] of byte;
+ dmatrixn,dmatrixi: array[0..7] of byte;
+
+
+procedure SetColorIntens(col0,col1,bal: integer);
+var cmatrix0: array[0..63] of byte absolute cmatrix;
+ dmatrix0: array[0..63] of byte absolute dmatrix;
+ n,i: integer;
+ b,bit: byte;
+begin
+if col0=col1 then bal:=0;
+if bal<=32 then
+ begin
+ plotcolor0:=col0 and $1F; plotcolor1:=col1 and $1F;
+ plotbal:=bal;
+ end
+else
+ begin
+ plotcolor0:=col1 and $1F; plotcolor1:=col0 and $1F;
+ plotbal:=64-bal;
+ end;
+for n:=0 to 63 do
+ if plotbal<=dmatrix0[n] then cmatrix0[n]:=col0 else cmatrix0[n]:=col1;
+end;
+*/
+
+#if defined( WIN ) && defined( MSC )
+#pragma code_seg( "svtools", "AUTO_CODE" )
+#endif
+
diff --git a/svtools/source/filter.vcl/filter/sgvspln.cxx b/svtools/source/filter.vcl/filter/sgvspln.cxx
new file mode 100644
index 000000000000..7a23e85f4dbe
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/sgvspln.cxx
@@ -0,0 +1,895 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <math.h>
+
+
+#include <tools/poly.hxx>
+
+#if defined( WIN ) && defined( MSC )
+#pragma code_seg( "SVTOOLS_FILTER2", "SVTOOLS_CODE" )
+#pragma optimize( "", off )
+#endif
+
+#if defined( PM2 ) && defined( __BORLANDC__ )
+#pragma option -Od
+#endif
+
+extern "C" {
+
+/*.pn 277 */
+/*.hlAnhang: C - Programme*/
+/*.hrKonstanten- und Macro-Definitionen*/
+/*.fe Die Include-Datei u_const.h ist in das Verzeichnis zu stellen, */
+/*.fe wo der Compiler nach Include-Dateien sucht. */
+
+
+/*----------------------- FILE u_const.h ---------------------------*/
+
+#define IEEE
+
+/* IEEE - Norm fuer die Darstellung von Gleitkommazahlen:
+
+ 8 Byte lange Gleitkommazahlen, mit
+
+ 53 Bit Mantisse ==> Mantissenbereich: 2 hoch 52 versch. Zahlen
+ mit 0.1 <= Zahl < 1.0,
+ 1 Vorzeichen-Bit
+ 11 Bit Exponent ==> Exponentenbereich: -1024...+1023
+
+ Die 1. Zeile ( #define IEEE ) ist zu loeschen, falls die Maschine
+ bzw. der Compiler keine Gleitpunktzahlen gemaess der IEEE-Norm
+ benutzt. Zusaetzlich muessen die Zahlen MAXEXPON, MINEXPON
+ (s.u.) angepasst werden.
+ */
+
+#ifdef IEEE /*----------- Falls IEEE Norm --------------------*/
+
+#define MACH_EPS 2.220446049250313e-016 /* Maschinengenauigkeit */
+ /* IBM-AT: = 2 hoch -52 */
+/* MACH_EPS ist die kleinste positive, auf der Maschine darstellbare
+ Zahl x, die der Bedingung genuegt: 1.0 + x > 1.0 */
+
+#define EPSQUAD 4.930380657631324e-032
+#define EPSROOT 1.490116119384766e-008
+
+#define POSMAX 8.98846567431158e+307 /* groesste positive Zahl */
+#define POSMIN 5.56268464626800e-309 /* kleinste positive Zahl */
+#define MAXROOT 9.48075190810918e+153
+
+#define BASIS 2 /* Basis der Zahlendarst. */
+#ifndef PI
+#define PI 3.141592653589793e+000
+#endif
+#define EXP_1 2.718281828459045e+000
+
+#else /*------------------ sonst -----------------------*/
+
+double exp (double);
+double atan (double);
+double pow (double,double);
+double sqrt (double);
+
+double masch() /* MACH_EPS maschinenunabhaengig bestimmen */
+{
+ double eps = 1.0, x = 2.0, y = 1.0;
+ while ( y < x )
+ { eps *= 0.5;
+ x = 1.0 + eps;
+ }
+ eps *= 2.0; return (eps);
+}
+
+short basis() /* BASIS maschinenunabhaengig bestimmen */
+{
+ double x = 1.0, one = 1.0, b = 1.0;
+
+ while ( (x + one) - x == one ) x *= 2.0;
+ while ( (x + b) == x ) b *= 2.0;
+
+ return ( (short) ((x + b) - x) );
+}
+
+#define BASIS basis() /* Basis der Zahlendarst. */
+
+/* Falls die Maschine (der Compiler) keine IEEE-Darstellung fuer
+ Gleitkommazahlen nutzt, muessen die folgenden 2 Konstanten an-
+ gepasst werden.
+ */
+
+#define MAXEXPON 1023.0 /* groesster Exponent */
+#define MINEXPON -1024.0 /* kleinster Exponent */
+
+
+#define MACH_EPS masch()
+#define EPSQUAD MACH_EPS * MACH_EPS
+#define EPSROOT sqrt(MACH_EPS)
+
+#define POSMAX pow ((double) BASIS, MAXEXPON)
+#define POSMIN pow ((double) BASIS, MINEXPON)
+#define MAXROOT sqrt(POSMAX)
+
+#define PI 4.0 * atan (1.0)
+#define EXP_1 exp(1.0)
+
+#endif /*-------------- ENDE ifdef ----------------------*/
+
+
+#define NEGMAX -POSMIN /* groesste negative Zahl */
+#define NEGMIN -POSMAX /* kleinste negative Zahl */
+
+#define TRUE 1
+#define FALSE 0
+
+
+/* Definition von Funktionsmakros:
+ */
+
+#define abs(X) ((X) >= 0 ? (X) : -(X)) /* Absolutbetrag von X */
+#define sign(X, Y) (Y < 0 ? -abs(X) : abs(X)) /* Vorzeichen von */
+ /* Y mal abs(X) */
+#define sqr(X) ((X) * (X)) /* Quadrat von X */
+
+/*------------------- ENDE FILE u_const.h --------------------------*/
+
+
+
+
+
+
+
+
+
+/*.HL Anhang: C - Programme*/
+/*.HRGleichungssysteme fuer Tridiagonalmatrizen*/
+
+/*.FE P 3.7 TRIDIAGONALE GLEICHUNGSSYSTEME*/
+
+
+/*---------------------- MODUL TRIDIAGONAL ------------------------*/
+
+USHORT TriDiagGS(BOOL rep, USHORT n, double* lower,
+ double* diag, double* upper, double* b)
+ /************************/
+ /* GAUSS-Verfahren fuer */
+ /* Tridiagonalmatrizen */
+ /************************/
+
+/*====================================================================*/
+/* */
+/* trdiag bestimmt die Loesung x des linearen Gleichungssystems */
+/* A * x = b mit tridiagonaler n x n Koeffizientenmatrix A, die in */
+/* den 3 Vektoren lower, upper und diag wie folgt abgespeichert ist: */
+/* */
+/* ( diag[0] upper[0] 0 0 . . . 0 ) */
+/* ( lower[1] diag[1] upper[1] 0 . . . ) */
+/* ( 0 lower[2] diag[2] upper[2] 0 . ) */
+/* A = ( . 0 lower[3] . . . ) */
+/* ( . . . . . 0 ) */
+/* ( . . . . . ) */
+/* ( . . . upper[n-2] ) */
+/* ( 0 . . . 0 lower[n-1] diag[n-1] ) */
+/* */
+/*====================================================================*/
+/* */
+/* Anwendung: */
+/* ========= */
+/* Vorwiegend fuer diagonaldominante Tridiagonalmatrizen, wie */
+/* sie bei der Spline-Interpolation auftreten. */
+/* Fuer diagonaldominante Matrizen existiert immer eine LU- */
+/* Zerlegung; fuer nicht diagonaldominante Tridiagonalmatrizen */
+/* sollte die Funktion band vorgezogen werden, da diese mit */
+/* Spaltenpivotsuche arbeitet und daher numerisch stabiler ist. */
+/* */
+/*====================================================================*/
+/* */
+/* Eingabeparameter: */
+/* ================ */
+/* n Dimension der Matrix ( > 1 ) USHORT n */
+/* */
+/* lower untere Nebendiagonale double lower[n] */
+/* diag Hauptdiagonale double diag[n] */
+/* upper obere Nebendiagonale double upper[n] */
+/* */
+/* bei rep != 0 enthalten lower, diag und upper die */
+/* Dreieckzerlegung der Ausgangsmatrix. */
+/* */
+/* b rechte Seite des Systems double b[n] */
+/* rep = 0 erstmaliger Aufruf BOOL rep */
+/* !=0 wiederholter Aufruf */
+/* fuer gleiche Matrix, */
+/* aber verschiedenes b. */
+/* */
+/* Ausgabeparameter: */
+/* ================ */
+/* b Loesungsvektor des Systems; double b[n] */
+/* die urspruengliche rechte Seite wird ueberspeichert */
+/* */
+/* lower ) enthalten bei rep = 0 die Zerlegung der Matrix; */
+/* diag ) die urspruenglichen Werte von lower u. diag werden */
+/* upper ) ueberschrieben */
+/* */
+/* Die Determinante der Matrix ist bei rep = 0 durch */
+/* det A = diag[0] * ... * diag[n-1] bestimmt. */
+/* */
+/* Rueckgabewert: */
+/* ============= */
+/* = 0 alles ok */
+/* = 1 n < 2 gewaehlt */
+/* = 2 Die Dreieckzerlegung der Matrix existiert nicht */
+/* */
+/*====================================================================*/
+/* */
+/* Benutzte Funktionen: */
+/* =================== */
+/* */
+/* Aus der C Bibliothek: fabs() */
+/* */
+/*====================================================================*/
+
+/*.cp 5 */
+{
+ USHORT i;
+ short j;
+
+// double fabs(double);
+
+ if ( n < 2 ) return(1); /* n mindestens 2 */
+
+ /* Wenn rep = 0 ist, */
+ /* Dreieckzerlegung der */
+ if (rep == 0) /* Matrix u. det be- */
+ { /* stimmen */
+ for (i = 1; i < n; i++)
+ { if ( fabs(diag[i-1]) < MACH_EPS ) /* Wenn ein diag[i] = 0 */
+ return(2); /* ist, ex. keine Zerle- */
+ lower[i] /= diag[i-1]; /* gung. */
+ diag[i] -= lower[i] * upper[i-1];
+ }
+ }
+
+ if ( fabs(diag[n-1]) < MACH_EPS ) return(2);
+
+ for (i = 1; i < n; i++) /* Vorwaertselimination */
+ b[i] -= lower[i] * b[i-1];
+
+ b[n-1] /= diag[n-1]; /* Rueckwaertselimination */
+ for (j = n-2; j >= 0; j--) {
+ i=j;
+ b[i] = ( b[i] - upper[i] * b[i+1] ) / diag[i];
+ }
+ return(0);
+}
+
+/*----------------------- ENDE TRIDIAGONAL -------------------------*/
+
+
+
+
+
+
+
+
+
+/*.HL Anhang: C - Programme*/
+/*.HRGleichungssysteme mit zyklisch tridiagonalen Matrizen*/
+
+/*.FE P 3.8 SYSTEME MIT ZYKLISCHEN TRIDIAGONALMATRIZEN */
+
+
+/*---------------- MODUL ZYKLISCH TRIDIAGONAL ----------------------*/
+
+
+USHORT ZyklTriDiagGS(BOOL rep, USHORT n, double* lower, double* diag,
+ double* upper, double* lowrow, double* ricol, double* b)
+ /******************************/
+ /* Systeme mit zyklisch tri- */
+ /* diagonalen Matrizen */
+ /******************************/
+
+/*====================================================================*/
+/* */
+/* tzdiag bestimmt die Loesung x des linearen Gleichungssystems */
+/* A * x = b mit zyklisch tridiagonaler n x n Koeffizienten- */
+/* matrix A, die in den 5 Vektoren lower, upper, diag, lowrow und */
+/* ricol wie folgt abgespeichert ist: */
+/* */
+/* ( diag[0] upper[0] 0 0 . . 0 ricol[0] ) */
+/* ( lower[1] diag[1] upper[1] 0 . . 0 ) */
+/* ( 0 lower[2] diag[2] upper[2] 0 . ) */
+/* A = ( . 0 lower[3] . . . . ) */
+/* ( . . . . . 0 ) */
+/* ( . . . . . ) */
+/* ( 0 . . . upper[n-2] ) */
+/* ( lowrow[0] 0 . . 0 lower[n-1] diag[n-1] ) */
+/* */
+/* Speicherplatz fuer lowrow[1],..,lowrow[n-3] und ricol[1],..., */
+/* ricol[n-3] muss zusaetzlich bereitgestellt werden, da dieser */
+/* fuer die Aufnahme der Zerlegungsmatrix verfuegbar sein muss, die */
+/* auf die 5 genannten Vektoren ueberspeichert wird. */
+/* */
+/*====================================================================*/
+/* */
+/* Anwendung: */
+/* ========= */
+/* Vorwiegend fuer diagonaldominante zyklische Tridiagonalmatri- */
+/* zen wie sie bei der Spline-Interpolation auftreten. */
+/* Fuer diagonaldominante Matrizen existiert immer eine LU- */
+/* Zerlegung. */
+/* */
+/*====================================================================*/
+/* */
+/* Eingabeparameter: */
+/* ================ */
+/* n Dimension der Matrix ( > 2 ) USHORT n */
+/* lower untere Nebendiagonale double lower[n] */
+/* diag Hauptdiagonale double diag[n] */
+/* upper obere Nebendiagonale double upper[n] */
+/* b rechte Seite des Systems double b[n] */
+/* rep = 0 erstmaliger Aufruf BOOL rep */
+/* !=0 wiederholter Aufruf */
+/* fuer gleiche Matrix, */
+/* aber verschiedenes b. */
+/* */
+/* Ausgabeparameter: */
+/* ================ */
+/* b Loesungsvektor des Systems, double b[n] */
+/* die urspruengliche rechte Seite wird ueberspeichert */
+/* */
+/* lower ) enthalten bei rep = 0 die Zerlegung der Matrix; */
+/* diag ) die urspruenglichen Werte von lower u. diag werden */
+/* upper ) ueberschrieben */
+/* lowrow ) double lowrow[n-2] */
+/* ricol ) double ricol[n-2] */
+/* */
+/* Die Determinante der Matrix ist bei rep = 0 durch */
+/* det A = diag[0] * ... * diag[n-1] bestimmt. */
+/* */
+/* Rueckgabewert: */
+/* ============= */
+/* = 0 alles ok */
+/* = 1 n < 3 gewaehlt */
+/* = 2 Die Zerlegungsmatrix existiert nicht */
+/* */
+/*====================================================================*/
+/* */
+/* Benutzte Funktionen: */
+/* =================== */
+/* */
+/* Aus der C Bibliothek: fabs() */
+/* */
+/*====================================================================*/
+
+/*.cp 5 */
+{
+ double temp; // fabs(double);
+ USHORT i;
+ short j;
+
+ if ( n < 3 ) return(1);
+
+ if (rep == 0) /* Wenn rep = 0 ist, */
+ { /* Zerlegung der */
+ lower[0] = upper[n-1] = 0.0; /* Matrix berechnen. */
+
+ if ( fabs (diag[0]) < MACH_EPS ) return(2);
+ /* Ist ein Diagonalelement */
+ temp = 1.0 / diag[0]; /* betragsmaessig kleiner */
+ upper[0] *= temp; /* MACH_EPS, so ex. keine */
+ ricol[0] *= temp; /* Zerlegung. */
+
+ for (i = 1; i < n-2; i++)
+ { diag[i] -= lower[i] * upper[i-1];
+ if ( fabs(diag[i]) < MACH_EPS ) return(2);
+ temp = 1.0 / diag[i];
+ upper[i] *= temp;
+ ricol[i] = -lower[i] * ricol[i-1] * temp;
+ }
+
+ diag[n-2] -= lower[n-2] * upper[n-3];
+ if ( fabs(diag[n-2]) < MACH_EPS ) return(2);
+
+ for (i = 1; i < n-2; i++)
+ lowrow[i] = -lowrow[i-1] * upper[i-1];
+
+ lower[n-1] -= lowrow[n-3] * upper[n-3];
+ upper[n-2] = ( upper[n-2] - lower[n-2] * ricol[n-3] ) / diag[n-2];
+
+ for (temp = 0.0, i = 0; i < n-2; i++)
+ temp -= lowrow[i] * ricol[i];
+ diag[n-1] += temp - lower[n-1] * upper[n-2];
+
+ if ( fabs(diag[n-1]) < MACH_EPS ) return(2);
+ } /* end if ( rep == 0 ) */
+
+ b[0] /= diag[0]; /* Vorwaertselemination */
+ for (i = 1; i < n-1; i++)
+ b[i] = ( b[i] - b[i-1] * lower[i] ) / diag[i];
+
+ for (temp = 0.0, i = 0; i < n-2; i++)
+ temp -= lowrow[i] * b[i];
+
+ b[n-1] = ( b[n-1] + temp - lower[n-1] * b[n-2] ) / diag[n-1];
+
+ b[n-2] -= b[n-1] * upper[n-2]; /* Rueckwaertselimination */
+ for (j = n-3; j >= 0; j--) {
+ i=j;
+ b[i] -= upper[i] * b[i+1] + ricol[i] * b[n-1];
+ }
+ return(0);
+}
+
+/*------------------ ENDE ZYKLISCH TRIDIAGONAL ---------------------*/
+
+
+} // extern "C"
+
+
+/*************************************************************************
+|*
+|* NaturalSpline()
+|*
+|* Beschreibung Berechnet die Koeffizienten eines natuerlichen
+|* kubischen Polynomsplines mit n Stuetzstellen.
+|* Ersterstellung JOE 17-08.93
+|* Letzte Aenderung JOE 17-08.93
+|*
+*************************************************************************/
+
+USHORT NaturalSpline(USHORT n, double* x, double* y,
+ double Marg0, double MargN,
+ BYTE MargCond,
+ double* b, double* c, double* d)
+{
+ USHORT i;
+ double* a;
+ double* h;
+ USHORT error;
+
+ if (n<2) return 1;
+ if ( (MargCond & ~3) ) return 2;
+ a=new double[n+1];
+ h=new double[n+1];
+ for (i=0;i<n;i++) {
+ h[i]=x[i+1]-x[i];
+ if (h[i]<=0.0) { delete[] a; delete[] h; return 1; }
+ }
+ for (i=0;i<n-1;i++) {
+ a[i]=3.0*((y[i+2]-y[i+1])/h[i+1]-(y[i+1]-y[i])/h[i]);
+ b[i]=h[i];
+ c[i]=h[i+1];
+ d[i]=2.0*(h[i]+h[i+1]);
+ }
+ switch (MargCond) {
+ case 0: {
+ if (n==2) {
+ a[0]=a[0]/3.0;
+ d[0]=d[0]*0.5;
+ } else {
+ a[0] =a[0]*h[1]/(h[0]+h[1]);
+ a[n-2]=a[n-2]*h[n-2]/(h[n-1]+h[n-2]);
+ d[0] =d[0]-h[0];
+ d[n-2]=d[n-2]-h[n-1];
+ c[0] =c[0]-h[0];
+ b[n-2]=b[n-2]-h[n-1];
+ }
+ }
+ case 1: {
+ a[0] =a[0]-1.5*((y[1]-y[0])/h[0]-Marg0);
+ a[n-2]=a[n-2]-1.5*(MargN-(y[n]-y[n-1])/h[n-1]);
+ d[0] =d[0]-h[0]*0.5;
+ d[n-2]=d[n-2]-h[n-1]*0.5;
+ }
+ case 2: {
+ a[0] =a[0]-h[0]*Marg0*0.5;
+ a[n-2]=a[n-2]-h[n-1]*MargN*0.5;
+ }
+ case 3: {
+ a[0] =a[0]+Marg0*h[0]*h[0]*0.5;
+ a[n-2]=a[n-2]-MargN*h[n-1]*h[n-1]*0.5;
+ d[0] =d[0]+h[0];
+ d[n-2]=d[n-2]+h[n-1];
+ }
+ } // switch MargCond
+ if (n==2) {
+ c[1]=a[0]/d[0];
+ } else {
+ error=TriDiagGS(FALSE,n-1,b,d,c,a);
+ if (error!=0) { delete[] a; delete[] h; return error+2; }
+ for (i=0;i<n-1;i++) c[i+1]=a[i];
+ }
+ switch (MargCond) {
+ case 0: {
+ if (n==2) {
+ c[2]=c[1];
+ c[0]=c[1];
+ } else {
+ c[0]=c[1]+h[0]*(c[1]-c[2])/h[1];
+ c[n]=c[n-1]+h[n-1]*(c[n-1]-c[n-2])/h[n-2];
+ }
+ }
+ case 1: {
+ c[0]=1.5*((y[1]-y[0])/h[0]-Marg0);
+ c[0]=(c[0]-c[1]*h[0]*0.5)/h[0];
+ c[n]=1.5*((y[n]-y[n-1])/h[n-1]-MargN);
+ c[n]=(c[n]-c[n-1]*h[n-1]*0.5)/h[n-1];
+ }
+ case 2: {
+ c[0]=Marg0*0.5;
+ c[n]=MargN*0.5;
+ }
+ case 3: {
+ c[0]=c[1]-Marg0*h[0]*0.5;
+ c[n]=c[n-1]+MargN*h[n-1]*0.5;
+ }
+ } // switch MargCond
+ for (i=0;i<n;i++) {
+ b[i]=(y[i+1]-y[i])/h[i]-h[i]*(c[i+1]+2.0*c[i])/3.0;
+ d[i]=(c[i+1]-c[i])/(3.0*h[i]);
+ }
+ delete[] a;
+ delete[] h;
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* PeriodicSpline()
+|*
+|* Beschreibung Berechnet die Koeffizienten eines periodischen
+|* kubischen Polynomsplines mit n Stuetzstellen.
+|* Ersterstellung JOE 17-08.93
+|* Letzte Aenderung JOE 17-08.93
+|*
+*************************************************************************/
+
+
+USHORT PeriodicSpline(USHORT n, double* x, double* y,
+ double* b, double* c, double* d)
+{ // Arrays muessen von [0..n] dimensioniert sein!
+ USHORT Error;
+ USHORT i,im1,nm1; //integer
+ double hr,hl;
+ double* a;
+ double* lowrow;
+ double* ricol;
+
+ if (n<2) return 4;
+ nm1=n-1;
+ for (i=0;i<=nm1;i++) if (x[i+1]<=x[i]) return 2; // muss streng nonoton fallend sein!
+ if (y[n]!=y[0]) return 3; // Anfang muss gleich Ende sein!
+
+ a =new double[n+1];
+ lowrow=new double[n+1];
+ ricol =new double[n+1];
+
+ if (n==2) {
+ c[1]=3.0*((y[2]-y[1])/(x[2]-x[1]));
+ c[1]=c[1]-3.0*((y[i]-y[0])/(x[1]-x[0]));
+ c[1]=c[1]/(x[2]-x[0]);
+ c[2]=-c[1];
+ } else {
+ for (i=1;i<=nm1;i++) {
+ im1=i-1;
+ hl=x[i]-x[im1];
+ hr=x[i+1]-x[i];
+ b[im1]=hl;
+ d[im1]=2.0*(hl+hr);
+ c[im1]=hr;
+ a[im1]=3.0*((y[i+1]-y[i])/hr-(y[i]-y[im1])/hl);
+ }
+ hl=x[n]-x[nm1];
+ hr=x[1]-x[0];
+ b[nm1]=hl;
+ d[nm1]=2.0*(hl+hr);
+ lowrow[0]=hr;
+ ricol[0]=hr;
+ a[nm1]=3.0*((y[1]-y[0])/hr-(y[n]-y[nm1])/hl);
+ Error=ZyklTriDiagGS(FALSE,n,b,d,c,lowrow,ricol,a);
+ if ( Error != 0 )
+ {
+ delete[] a;
+ delete[] lowrow;
+ delete[] ricol;
+ return(Error+4);
+ }
+ for (i=0;i<=nm1;i++) c[i+1]=a[i];
+ }
+ c[0]=c[n];
+ for (i=0;i<=nm1;i++) {
+ hl=x[i+1]-x[i];
+ b[i]=(y[i+1]-y[i])/hl;
+ b[i]=b[i]-hl*(c[i+1]+2.0*c[i])/3.0;
+ d[i]=(c[i+1]-c[i])/hl/3.0;
+ }
+ delete[] a;
+ delete[] lowrow;
+ delete[] ricol;
+ return 0;
+}
+
+
+
+/*************************************************************************
+|*
+|* ParaSpline()
+|*
+|* Beschreibung Berechnet die Koeffizienten eines parametrischen
+|* natuerlichen oder periodischen kubischen
+|* Polynomsplines mit n Stuetzstellen.
+|* Ersterstellung JOE 17-08.93
+|* Letzte Aenderung JOE 17-08.93
+|*
+*************************************************************************/
+
+USHORT ParaSpline(USHORT n, double* x, double* y, BYTE MargCond,
+ double Marg01, double Marg02,
+ double MargN1, double MargN2,
+ BOOL CondT, double* T,
+ double* bx, double* cx, double* dx,
+ double* by, double* cy, double* dy)
+{
+ USHORT Error,Marg;
+ USHORT i;
+ double deltX,deltY,delt,
+ alphX = 0,alphY = 0,
+ betX = 0,betY = 0;
+
+ if (n<2) return 1;
+ if ((MargCond & ~3) && (MargCond != 4)) return 2; // ungueltige Randbedingung
+ if (CondT==FALSE) {
+ T[0]=0.0;
+ for (i=0;i<n;i++) {
+ deltX=x[i+1]-x[i]; deltY=y[i+1]-y[i];
+ delt =deltX*deltX+deltY*deltY;
+ if (delt<=0.0) return 3; // zwei identische Punkte nacheinander!
+ T[i+1]=T[i]+sqrt(delt);
+ }
+ }
+ switch (MargCond) {
+ case 0: Marg=0; break;
+ case 1: case 2: {
+ Marg=MargCond;
+ alphX=Marg01; betX=MargN1;
+ alphY=Marg02; betY=MargN2;
+ } break;
+ case 3: {
+ if (x[n]!=x[0]) return 3;
+ if (y[n]!=y[0]) return 4;
+ } break;
+ case 4: {
+ Marg=1;
+ if (abs(Marg01)>=MAXROOT) {
+ alphX=0.0;
+ alphY=sign(1.0,y[1]-y[0]);
+ } else {
+ alphX=sign(sqrt(1.0/(1.0+Marg01*Marg01)),x[1]-x[0]);
+ alphY=alphX*Marg01;
+ }
+ if (abs(MargN1)>=MAXROOT) {
+ betX=0.0;
+ betY=sign(1.0,y[n]-y[n-1]);
+ } else {
+ betX=sign(sqrt(1.0/(1.0+MargN1*MargN1)),x[n]-x[n-1]);
+ betY=betX*MargN1;
+ }
+ }
+ } // switch MargCond
+ if (MargCond==3) {
+ Error=PeriodicSpline(n,T,x,bx,cx,dx);
+ if (Error!=0) return(Error+4);
+ Error=PeriodicSpline(n,T,y,by,cy,dy);
+ if (Error!=0) return(Error+10);
+ } else {
+ Error=NaturalSpline(n,T,x,alphX,betX,MargCond,bx,cx,dx);
+ if (Error!=0) return(Error+4);
+ Error=NaturalSpline(n,T,y,alphY,betY,MargCond,by,cy,dy);
+ if (Error!=0) return(Error+9);
+ }
+ return 0;
+}
+
+
+
+/*************************************************************************
+|*
+|* CalcSpline()
+|*
+|* Beschreibung Berechnet die Koeffizienten eines parametrischen
+|* natuerlichen oder periodischen kubischen
+|* Polynomsplines. Die Eckpunkte des uebergebenen
+|* Polygons werden als Stuetzstellen angenommen.
+|* n liefert die Anzahl der Teilpolynome.
+|* Ist die Berechnung fehlerfrei verlaufen, so
+|* liefert die Funktion TRUE. Nur in diesem Fall
+|* ist Speicher fuer die Koeffizientenarrays
+|* allokiert, der dann spaeter vom Aufrufer mittels
+|* delete freizugeben ist.
+|* Ersterstellung JOE 17-08.93
+|* Letzte Aenderung JOE 17-08.93
+|*
+*************************************************************************/
+
+BOOL CalcSpline(Polygon& rPoly, BOOL Periodic, USHORT& n,
+ double*& ax, double*& ay, double*& bx, double*& by,
+ double*& cx, double*& cy, double*& dx, double*& dy, double*& T)
+{
+ BYTE Marg;
+ double Marg01,Marg02;
+ double MargN1,MargN2;
+ USHORT i;
+ Point P0(-32768,-32768);
+ Point Pt;
+
+ n=rPoly.GetSize();
+ ax=new double[rPoly.GetSize()+2];
+ ay=new double[rPoly.GetSize()+2];
+
+ n=0;
+ for (i=0;i<rPoly.GetSize();i++) {
+ Pt=rPoly.GetPoint(i);
+ if (i==0 || Pt!=P0) {
+ ax[n]=Pt.X();
+ ay[n]=Pt.Y();
+ n++;
+ P0=Pt;
+ }
+ }
+
+ if (Periodic) {
+ Marg=3;
+ ax[n]=ax[0];
+ ay[n]=ay[0];
+ n++;
+ } else {
+ Marg=2;
+ }
+
+ bx=new double[n+1];
+ by=new double[n+1];
+ cx=new double[n+1];
+ cy=new double[n+1];
+ dx=new double[n+1];
+ dy=new double[n+1];
+ T =new double[n+1];
+
+ Marg01=0.0;
+ Marg02=0.0;
+ MargN1=0.0;
+ MargN2=0.0;
+ if (n>0) n--; // n Korregieren (Anzahl der Teilpolynome)
+
+ BOOL bRet = FALSE;
+ if ( ( Marg == 3 && n >= 3 ) || ( Marg == 2 && n >= 2 ) )
+ {
+ bRet = ParaSpline(n,ax,ay,Marg,Marg01,Marg01,MargN1,MargN2,FALSE,T,bx,cx,dx,by,cy,dy) == 0;
+ }
+ if ( bRet == FALSE )
+ {
+ delete[] ax;
+ delete[] ay;
+ delete[] bx;
+ delete[] by;
+ delete[] cx;
+ delete[] cy;
+ delete[] dx;
+ delete[] dy;
+ delete[] T;
+ n=0;
+ }
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|* Spline2Poly()
+|*
+|* Beschreibung Konvertiert einen parametrichen kubischen
+|* Polynomspline Spline (natuerlich oder periodisch)
+|* in ein angenaehertes Polygon.
+|* Die Funktion liefert FALSE, wenn ein Fehler bei
+|* der Koeffizientenberechnung aufgetreten ist oder
+|* das Polygon zu gross wird (>PolyMax=16380). Im 1.
+|* Fall hat das Polygon 0, im 2. Fall PolyMax Punkte.
+|* Um Koordinatenueberlaeufe zu vermeiden werden diese
+|* auf +/-32000 begrenzt.
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL Spline2Poly(Polygon& rSpln, BOOL Periodic, Polygon& rPoly)
+{
+ short MinKoord=-32000; // zur Vermeidung
+ short MaxKoord=32000; // von Ueberlaeufen
+
+ double* ax; // Koeffizienten der Polynome
+ double* ay;
+ double* bx;
+ double* by;
+ double* cx;
+ double* cy;
+ double* dx;
+ double* dy;
+ double* tv;
+
+ double Step; // Schrittweite fuer t
+ double dt1,dt2,dt3; // Delta t, y, ^3
+ double t;
+ BOOL bEnde; // Teilpolynom zu Ende?
+ USHORT n; // Anzahl der zu zeichnenden Teilpolynome
+ USHORT i; // aktuelles Teilpolynom
+ BOOL bOk; // noch alles ok?
+ USHORT PolyMax=16380;// Maximale Anzahl von Polygonpunkten
+ long x,y;
+
+ bOk=CalcSpline(rSpln,Periodic,n,ax,ay,bx,by,cx,cy,dx,dy,tv);
+ if (bOk) {
+ Step =10;
+
+ rPoly.SetSize(1);
+ rPoly.SetPoint(Point(short(ax[0]),short(ay[0])),0); // erster Punkt
+ i=0;
+ while (i<n) { // n Teilpolynome malen
+ t=tv[i]+Step;
+ bEnde=FALSE;
+ while (!bEnde) { // ein Teilpolynom interpolieren
+ bEnde=t>=tv[i+1];
+ if (bEnde) t=tv[i+1];
+ dt1=t-tv[i]; dt2=dt1*dt1; dt3=dt2*dt1;
+ x=long(ax[i]+bx[i]*dt1+cx[i]*dt2+dx[i]*dt3);
+ y=long(ay[i]+by[i]*dt1+cy[i]*dt2+dy[i]*dt3);
+ if (x<MinKoord) x=MinKoord; if (x>MaxKoord) x=MaxKoord;
+ if (y<MinKoord) y=MinKoord; if (y>MaxKoord) y=MaxKoord;
+ if (rPoly.GetSize()<PolyMax) {
+ rPoly.SetSize(rPoly.GetSize()+1);
+ rPoly.SetPoint(Point(short(x),short(y)),rPoly.GetSize()-1);
+ } else {
+ bOk=FALSE; // Fehler: Polygon wird zu gross
+ }
+ t=t+Step;
+ } // Ende von Teilpolynom
+ i++; // naechstes Teilpolynom
+ }
+ delete[] ax;
+ delete[] ay;
+ delete[] bx;
+ delete[] by;
+ delete[] cx;
+ delete[] cy;
+ delete[] dx;
+ delete[] dy;
+ delete[] tv;
+ return bOk;
+ } // Ende von if (bOk)
+ rPoly.SetSize(0);
+ return FALSE;
+}
diff --git a/svtools/source/filter.vcl/filter/sgvtext.cxx b/svtools/source/filter.vcl/filter/sgvtext.cxx
new file mode 100644
index 000000000000..4a0be80b55be
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/sgvtext.cxx
@@ -0,0 +1,1338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <rtl/math.h>
+#include <tools/config.hxx>
+#include <svtools/filter.hxx>
+#include "sgffilt.hxx"
+#include "sgfbram.hxx"
+#include "sgvmain.hxx"
+// #include "Debug.c"
+
+extern SgfFontLst* pSgfFonts;
+
+#if defined( WIN ) && defined( MSC )
+#pragma code_seg( "SVTOOLS_FILTER1", "SVTOOLS_CODE" )
+#endif
+
+#ifndef abs
+#define abs(x) ((x)<0 ? -(x) : (x))
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Einschraenkungen: Schatten nur grau, 2D und mit fixem Abstand.
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// AbsBase.Pas
+
+// die folgenden Werte sind in % vom maximalen Schriftgrad der Zeile */
+#define UndlSpace 5 /* Untersteichungsabstand von der Baseline */
+#define UndlWidth 6 /* Untersteichungsdicke */
+#define UndlSpac2 7 /* Zwischenraum bei doppelter Unterstreichung */
+#define StrkSpace 25 /* Abstand der Durchstreichlinie von der Baseline*/
+#define StrkWidth 5 /* Durchstreichungsliniendicke */
+#define StrkSpac2 7 /* Zwischenraum bei doppelter Durchstreichung */
+#define OutlWidth 2 /* Strichstaerke ist 2% vom Schriftgrad */
+
+// vvv Sonderzeichen im TextBuffer vvv
+#define TextEnd 0 /* ^@ Ende der Zeichenkette */
+#define HardSpace 6 /* ^F Hartspace (wird nicht umbrochen) ,' ' */
+#define GrafText 7 /* ^G Im Text eingebundene Grafik (future) */
+#define Tabulator 9 /* ^I Tabulatorzeichen, Pfeil */
+#define LineFeed 10 /* ^J Neue Zeile */
+#define SoftTrennK 11 /* ^K Zeichen fuer k-c-Austausch bei Trennung, 'k' */
+#define AbsatzEnd 13 /* ^M Neuer Absatz =CR */
+#define HardTrenn 16 /* ^P Hartes Trennzeichen (wird nicht umbrochen), '-' */
+#define SoftTrennAdd 19 /* ^S Zusatz-Zeichen Trennung von z.b."Schiff-fahrt" */
+#define Paragraf 21 /* ^U Zeichen welches fuer Paragraf-Zeichen */
+#define Escape 27 /* ^[ Escapesequenz einleiten */
+#define SoftTrenn 31 /* ^_ Weiches Trennzeichen, '-' nur Zeilenende */
+#define MaxEscValLen 8
+#define MaxEscLen (MaxEscValLen+3)
+
+//==============================================================================
+// Escapesequenzen: [Esc]<Ident><Value>[Esc] also mind. 4 Char
+// Max. Laenge von Value soll sein: 8 Char (7+Vorzeichen). Demnach max. Laenge
+// einer Escapesequenz: 11 Char.
+// Identifer:
+
+#define EscFont 'F' /* FontID, z.B. 92500 fuer CG Times */
+#define EscGrad 'G' /* Schriftgrad 1..255 fuer <<Pt-127<<Pt */
+#define EscBreit 'B' /* Breite 1..255% des Schriftgrades */
+#define EscKaptS 'K' /* Kapitaelchengroesse 1..255% des Schriftgrades */
+#define EscLFeed 'L' /* Zeilenabstand 1..32767% vom max. Schriftgrad der Zeile */
+ // oder 1..32767 fuer 1..16383<<Pt absolut (Wenn Bit 15=1)
+#define EscSlant 'S' /* Kursiv(Winkel) 1..8999 fuer 0.01deg..89.99deg */
+#define EscVPos 'V' /* Zeichen Vertikal-Position 1..255 fuer <<Pt..127<<Pt */
+#define EscZAbst 'Z' /* Zeichenabstand -128..127% */
+#define EscHJust 'A' /* H-Justify Absatz: Links, Zentr, Rechts, Block, Austreibend, Gesperrt (0..5)*/
+
+#define EscFarbe 'C' /* Farbe 0..7 */
+#define EscBFarb 'U' /* BackFarbe 0..7 */
+#define EscInts 'I' /* Farbintensitaet 0..100% */
+#define EscMustr 'M' /* Muster 0..? inkl. Transp... */
+#define EscMFarb 'O' /* Musterfarbe 0..7 */
+#define EscMBFrb 'P' /* 2. Musterfarbe 0..7 */
+#define EscMInts 'W' /* Musterintensitaet 0..7 */
+
+#define EscSMstr 'E' /* Schattenmuster 0..? inkl. Transp... */
+#define EscSFarb 'R' /* Schattenfarbe 0..7 */
+#define EscSBFrb 'T' /* 2. Schattenfarbe 0..7 */
+#define EscSInts 'Q' /* Schattenintensitaet 0..7 */
+
+#define EscSXDst 'X' /* Schattenversatz X 0..100% */
+#define EscSYDst 'Y' /* Schattenversatz Y 0..100% */
+#define EscSDist 'D' /* Schattenversatz X-Y 0..100% */
+
+#define EscBold 'f' /* Fett */
+#define EscLSlnt 'l' /* LKursiv */
+#define EscRSlnt 'r' /* RKursiv */
+#define EscUndln 'u' /* Unterstrichen */
+#define EscDbUnd 'p' /* doppelt Unterstrichen */
+#define EscKaptF 'k' /* Kapitaelchenflag */
+#define EscStrik 'd' /* Durchgestrichen */
+#define EscDbStk 'e' /* doppelt Durchgestrichen */
+#define EscSupSc 'h' /* Hochgestellt */
+#define EscSubSc 't' /* Tiefgestellt */
+#define Esc2DShd 's' /* 2D-Schatten */
+#define Esc3DShd 'j' /* 3D-Schatten */
+#define Esc4DShd 'i' /* 4D-Schatten */
+#define EscEbShd 'b' /* Embossed */
+
+// AllEscIdent =[EscFont, EscGrad, EscBreit,EscKaptS,EscLFeed,EscSlant,EscVPos, EscZAbst,EscHJust,
+// EscFarbe,EscBFarb,EscInts, EscMustr,EscMFarb,EscMBFrb,EscMInts,
+// EscSMstr,EscSFarb,EscSBFrb,EscSInts,EscSXDst,EscSYDst,EscSDist,
+// EscBold, EscLSlnt,EscRSlnt,EscUndln,EscDbUnd,EscKaptF,EscStrik,EscDbStk,
+// EscSupSc,EscSubSc,Esc2DShd,Esc3DShd,Esc4DShd];
+// Justify muss spaetestens am Anfang des Absatzes stehen
+#define EscSet '' /* Flag setzen */
+#define EscReset '' /* Flag loeschen */
+#define EscDeflt '\x11' /* Flag auf default setzen */
+#define EscToggl '' /* Flag Toggeln */
+#define EscRelat '%'
+#define EscNoFlg 0
+#define EscNoVal -2147483647 /* -MaxLongInt */
+//==============================================================================
+#define NoTrenn 0xFFFF /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn auf keinen Fall getrennt werden soll */
+#define DoTrenn 0xFFFE /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn getrennt werden soll */
+
+#define MaxLineChars 1024
+
+#define ChrXPosArrSize (MaxLineChars+1+1) /* 2k - Beginnt mit 0 im gegensatz zu StarDraw */
+#define CharLineSize (MaxLineChars+1+1)
+#define EscStr (UCHAR[MaxEscLen+1]);
+
+#define MinChar 32
+#define MaxChar 255
+
+
+//==============================================================================
+
+#define DefaultCharWidth 4800
+#define GradDiv 2
+#define CharTopToBase 100 /* wegen Apostrophe und Umlaute mehr als 75% */
+#define CharTopToBtm 120 /* Zeilenhoehe ist groesser als Schriftgrad */
+ // bei Avanti-Bold 'ue' eigentlich sogar 130%
+
+// end of AbsBase.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// DefBase.Pas
+
+#define TextBoldBit 0x0001 /* Fett */
+#define TextRSlnBit 0x0002 /* Kursiv */
+#define TextUndlBit 0x0004 /* Unterstrichen */
+#define TextStrkBit 0x0008 /* Durchgesteichen */
+#define TextSupSBit 0x0010 /* Hocgestellt */
+#define TextSubSBit 0x0020 /* Tiefgestellt */
+#define TextKaptBit 0x0040 /* Kapitaelchen */
+#define TextLSlnBit 0x0080 /* Linkskursiv */
+#define TextDbUnBit 0x0100 /* Doppelt unterstrichen */
+#define TextDbStBit 0x0200 /* Doppelt durchgestrichen */
+#define TextSh2DBit 0x0400 /* 2D-Schatten 2.0 */
+#define TextSh3DBit 0x0800 /* 3D-Schatten 2.0 */
+#define TextSh4DBit 0x1000 /* 4D-Schatten 2.0 */
+#define TextShEbBit 0x2000 /* Embossed-Schatten 2.0 */
+#define FontAtrBits (TextBoldBit | TextRSlnBit)
+
+#define THJustLeft 0x00
+#define THJustCenter 0x01
+#define THJustRight 0x02
+#define THJustBlock 0x03
+#define THJustDrvOut 0x04 /* Austreibend Formatiert */
+#define THJustLocked 0x05 /* A l s S p e r r s c h r i f t */
+#define TVJustTop 0x00 /* Future */
+#define TVJustCenter 0x10 /* Future */
+#define TVJustBottom 0x20 /* Future */
+#define TVJustBlock 0x30 /* Future */
+
+#define MaxCharSlant 4200 /* Maximal 42deg kursiv ! */
+
+// end of DefBase.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+
+BOOL CheckTextOutl(ObjAreaType& F, ObjLineType& L);
+
+BOOL CheckTextOutl(ObjAreaType& F, ObjLineType& L)
+{
+ return (F.FIntens!=L.LIntens) ||
+ ((F.FFarbe!=L.LFarbe) && (F.FIntens>0)) ||
+ ((F.FBFarbe!=L.LBFarbe) && (F.FIntens<100));
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// Misc.Pas
+
+short hPoint2Sgf(short a)
+{
+ long b;
+ b=long(a)*127*SgfDpmm/(144*5);
+ return short(b);
+}
+
+short Sgf2hPoint(short a)
+{
+ long b;
+ b=long(a)*5*144/(127*SgfDpmm);
+ return short(b);
+}
+
+// End of Misc.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// AbsRead.Pas
+
+// ======================================================================
+// Function GetTopToBaseLine() Function GetBaseLineToBtm()
+//
+// Abstand von Zeilenoberkante bis BaseLine bzw. von BaseLine bis
+// Unterkante berechnen. Alles in SGF-Units.
+// ======================================================================
+
+USHORT GetTopToBaseLine(USHORT MaxGrad)
+{
+ long ret;
+ ret=long(MaxGrad)*long(CharTopToBase) /long(100);
+ return USHORT(ret);
+}
+
+// ======================================================================
+// Function GetTextChar() Function GetTextCharConv()
+//
+// Liest ein Zeichen aus dem Textbuffer, wertet dabei eventuell
+// auftretende Escapesequenzen aus und setzt dementsprechend den
+// Ein-/Ausgabeparameter AktAtr. Index wird entsprechend erhoeht.
+// Der Parameter Rest muss immer die Anzahl der Zeichen beinhalten,
+// den angeforderten Zeichen in der aktuellen Zeile noch folgen.
+// Ansonsten funktioniert die Silbentrennung nicht richtig. Gibt man
+// stattdessen die Konstante NoTrenn an, wird in keinem Fall
+// getrennt, die Konstante DoTrenn bewirkt dagegen, dass ueberall dort
+// getrennt wird, wo ein SoftTrenner vorkommt.
+//
+// SoftTrenner werden immer in ein Minuszeichen konvertiert.
+// GetTextCharConv() konvertiert zusaetzlich HardSpace und AbsatzEnde
+// in Spaces sowie HardTrenner in Minuszeichen. TextEnde wird immer
+// als Char(0) geliefert.
+// ======================================================================
+
+
+
+UCHAR ConvertTextChar(UCHAR c)
+{
+ if (c<32) {
+ switch (c) {
+ case HardSpace : c=' '; break;
+ case AbsatzEnd : c=' '; break;
+ case SoftTrenn : c='-'; break;
+ case HardTrenn : c='-'; break;
+ case SoftTrennK : c='-'; break;
+ case SoftTrennAdd: c='-';
+ }
+ }
+ return c;
+}
+
+
+
+USHORT GetSchnittBit(UCHAR c)
+{
+ USHORT r=0;
+ switch (c) {
+ case EscBold : r=TextBoldBit; break;
+ case EscRSlnt: r=TextRSlnBit; break;
+ case EscUndln: r=TextUndlBit; break;
+ case EscStrik: r=TextStrkBit; break;
+ case EscDbUnd: r=TextDbUnBit; break;
+ case EscDbStk: r=TextDbStBit; break;
+ case EscSupSc: r=TextSupSBit; break;
+ case EscSubSc: r=TextSubSBit; break;
+ case EscKaptF: r=TextKaptBit; break;
+ case EscLSlnt: r=TextLSlnBit; break;
+ case Esc2DShd: r=TextSh2DBit; break;
+ case Esc3DShd: r=TextSh3DBit; break;
+ case Esc4DShd: r=TextSh4DBit; break;
+ case EscEbShd: r=TextShEbBit;
+ }
+ return r;
+}
+
+
+
+long ChgValue(long Def, long Min, long Max, UCHAR FlgVal, long NumVal)
+{
+ long r=0;
+
+ if (FlgVal==EscDeflt) {
+ r=Def; // zurueck auf Default
+ } else {
+ if (NumVal!=EscNoVal) r=NumVal; // Hart setzen
+ }
+
+ if (Min!=0 || Max!=0) {
+ if (r>Max) r=Max;
+ if (r<Min) r=Min;
+ }
+ return r;
+}
+
+
+
+void ChgSchnittBit(USHORT Bit, USHORT Radio1, USHORT Radio2, USHORT Radio3,
+ UCHAR FlgVal, USHORT Schnitt0, USHORT& Schnitt)
+{
+ USHORT All,Rad;
+
+ Rad=Radio1 | Radio2 | Radio3;
+ All=Bit | Rad;
+
+ switch (FlgVal) {
+ case EscSet : Schnitt=(Schnitt & ~All) | Bit; break;
+ case EscReset: Schnitt=(Schnitt & ~All); break;
+ case EscDeflt: Schnitt=(Schnitt & ~All) | (Schnitt0 & All); break;
+ case EscToggl: Schnitt=(Schnitt & ~Rad) ^ Bit;
+ }
+}
+
+
+
+UCHAR GetNextChar(UCHAR* TBuf, USHORT Index)
+{
+ USHORT Cnt;
+ while (TBuf[Index]==Escape) {
+ Index++;
+ Cnt=0;
+ while (TBuf[Index]!=Escape && Cnt<=MaxEscLen) {
+ Index++; Cnt++; }
+ Index++;
+ }
+ return TBuf[Index];
+}
+
+
+
+UCHAR ProcessOne(UCHAR* TBuf, USHORT& Index,
+ ObjTextType& Atr0, ObjTextType& AktAtr,
+ BOOL ScanEsc)
+{
+ UCHAR c;
+ UCHAR Ident;
+ BOOL Ende;
+ BOOL q;
+ UCHAR FlgVal;
+ long NumVal;
+ long Sgn;
+ short i;
+ BOOL EoVal;
+
+ do {
+ c=TBuf[Index]; Index++;
+ Ende=(c!=Escape);
+ if (Ende==FALSE) {
+ c=TBuf[Index]; Index++;
+ Ident=c; // Identifer merken
+ FlgVal=EscNoFlg;
+ NumVal=EscNoVal;
+ c=TBuf[Index]; Index++; // Hier faengt der Wert an
+ if (c==EscSet || c==EscReset || c==EscDeflt || c==EscToggl) FlgVal=c; else {
+ if (c=='-') Sgn=-1; else Sgn=1;
+ if (c=='+' || c=='-') { c=TBuf[Index]; Index++; }
+ i=MaxEscValLen;
+ NumVal=0;
+ do {
+ NumVal=10*NumVal+c-'0';
+ EoVal=(TBuf[Index]<'0' || TBuf[Index]>'9');
+ if (EoVal==FALSE) { c=TBuf[Index]; Index++; }
+ i--;
+ } while (i>0 && EoVal==FALSE);
+ NumVal=Sgn*NumVal;
+ }
+ q=!CheckTextOutl(AktAtr.F,AktAtr.L);
+
+ switch (Ident) {
+ case EscFont : AktAtr.SetFont(ULONG (ChgValue(Atr0.GetFont(),0,0 ,FlgVal,NumVal)));break;
+ case EscGrad : AktAtr.Grad =USHORT(ChgValue(Atr0.Grad, 2,2000 ,FlgVal,NumVal)); break;
+ case EscBreit: AktAtr.Breite =USHORT(ChgValue(Atr0.Breite, 1,1000 ,FlgVal,NumVal)); break;
+ case EscKaptS: AktAtr.Kapit =(BYTE)(ChgValue(Atr0.Kapit, 1,255 ,FlgVal,NumVal)); break;
+ case EscLFeed: AktAtr.LnFeed =USHORT(ChgValue(Atr0.LnFeed, 1,65535 ,FlgVal,NumVal)); break;
+ case EscSlant: AktAtr.Slant =USHORT(ChgValue(Atr0.Slant, 1,MaxCharSlant ,FlgVal,NumVal)); break;
+ case EscVPos : AktAtr.ChrVPos=char (ChgValue(Atr0.ChrVPos,-128,127 ,FlgVal,NumVal)); break;
+ case EscZAbst: AktAtr.ZAbst =(BYTE)(ChgValue(Atr0.ZAbst, 1,255 ,FlgVal,NumVal)); break;
+ case EscHJust: AktAtr.Justify=(BYTE)(ChgValue(Atr0.Justify & 0x0F,0,5 ,FlgVal,NumVal)); break;
+ case EscFarbe: { AktAtr.L.LFarbe =(BYTE)(ChgValue(Atr0.L.LFarbe,0,7 ,FlgVal,NumVal)); if (q) AktAtr.F.FFarbe =AktAtr.L.LFarbe; } break;
+ case EscBFarb: { AktAtr.L.LBFarbe=(BYTE)(ChgValue(Atr0.L.LBFarbe,0,255,FlgVal,NumVal)); if (q) AktAtr.F.FBFarbe=AktAtr.L.LBFarbe; } break;
+ case EscInts : { AktAtr.L.LIntens=(BYTE)(ChgValue(Atr0.L.LIntens,0,100,FlgVal,NumVal)); if (q) AktAtr.F.FIntens=AktAtr.L.LIntens; } break;
+
+ case EscMustr: { AktAtr.F.FMuster=USHORT(ChgValue(Atr0.F.FMuster,0,65535,FlgVal,NumVal)); } break;
+ case EscMFarb: { AktAtr.F.FFarbe =(BYTE)(ChgValue(Atr0.F.FFarbe,0,7 ,FlgVal,NumVal)); } break;
+ case EscMBFrb: { AktAtr.F.FBFarbe=(BYTE)(ChgValue(Atr0.F.FBFarbe,0,255,FlgVal,NumVal)); } break;
+ case EscMInts: { AktAtr.F.FIntens=(BYTE)(ChgValue(Atr0.F.FIntens,0,100,FlgVal,NumVal)); } break;
+
+ case EscSMstr: { AktAtr.ShdF.FMuster=USHORT(ChgValue(Atr0.ShdF.FMuster,0,65535,FlgVal,NumVal)); } break;
+ case EscSFarb: { AktAtr.ShdL.LFarbe =(BYTE)(ChgValue(Atr0.ShdL.LFarbe,0,7 ,FlgVal,NumVal)); AktAtr.ShdF.FFarbe =AktAtr.ShdL.LFarbe; } break;
+ case EscSBFrb: { AktAtr.ShdL.LBFarbe=(BYTE)(ChgValue(Atr0.ShdL.LBFarbe,0,255,FlgVal,NumVal)); AktAtr.ShdF.FBFarbe=AktAtr.ShdL.LBFarbe; } break;
+ case EscSInts: { AktAtr.ShdL.LIntens=(BYTE)(ChgValue(Atr0.ShdL.LIntens,0,100,FlgVal,NumVal)); AktAtr.ShdF.FIntens=AktAtr.ShdL.LIntens; } break;
+ case EscSDist: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); AktAtr.ShdVers.y=AktAtr.ShdVers.x; } break;
+ case EscSXDst: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); } break;
+ case EscSYDst: { AktAtr.ShdVers.y=(short)ChgValue(Atr0.ShdVers.y,0,30000,FlgVal,NumVal); } break;
+
+ case EscBold : ChgSchnittBit(TextBoldBit,0,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscRSlnt: ChgSchnittBit(TextRSlnBit,TextLSlnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscUndln: ChgSchnittBit(TextUndlBit,TextDbUnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscStrik: ChgSchnittBit(TextStrkBit,TextDbStBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscDbUnd: ChgSchnittBit(TextDbUnBit,TextUndlBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscDbStk: ChgSchnittBit(TextDbStBit,TextStrkBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscSupSc: ChgSchnittBit(TextSupSBit,TextSubSBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscSubSc: ChgSchnittBit(TextSubSBit,TextSupSBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscKaptF: ChgSchnittBit(TextKaptBit,0,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscLSlnt: ChgSchnittBit(TextLSlnBit,TextRSlnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case Esc2DShd: ChgSchnittBit(TextSh2DBit,TextSh3DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case Esc3DShd: ChgSchnittBit(TextSh3DBit,TextSh2DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case Esc4DShd: ChgSchnittBit(TextSh4DBit,TextSh2DBit,TextSh3DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ case EscEbShd: ChgSchnittBit(TextShEbBit,TextSh2DBit,TextSh3DBit,TextSh4DBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
+ } //endcase
+ if (TBuf[Index]==Escape) Index++; // zweites Esc weglesen }
+ } // if Ende==FALSE
+ } while (Ende==FALSE && ScanEsc==FALSE);
+ if (Ende==FALSE) c=Escape;
+ return c;
+} // end of ProcessOne
+
+
+UCHAR GetTextChar(UCHAR* TBuf, USHORT& Index,
+ ObjTextType& Atr0, ObjTextType& AktAtr,
+ USHORT Rest, BOOL ScanEsc)
+{
+ UCHAR c,c0,nc;
+
+ c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc);
+ if (ScanEsc==FALSE) {
+ if (c==SoftTrennAdd || c==SoftTrennK || c==SoftTrenn) {
+ nc=GetNextChar(TBuf,Index);
+ c0=c;
+ if (Rest==0 || Rest==DoTrenn ||
+ nc==' ' || nc==AbsatzEnd || nc==TextEnd) c='-';
+ else {
+ c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // den Trenner ueberspringen
+ if (c0==SoftTrennAdd) {
+ if (c>=32) c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // und hier noch 'nen Buchstaben ueberspringen
+ }
+ }
+ }
+ if ((Rest==1 || Rest==DoTrenn) && GetNextChar(TBuf,Index)==SoftTrennK) {
+ if (c=='c') c='k';
+ else if (c=='C') c='K';
+ }
+ }
+ return c;
+}
+
+ // HardSpace und HardTrenn muessen explizit konvertiert werden ! }
+ // if AktAtr.Schnitt and TextKaptBit =TextKaptBit then c:=UpCase(c);(explizit) }
+
+ // Bei der Trennmethode SoftTrennAdd wird davon ausgegangen, dass der zu }
+ // trennende Konsonant bereits 3x mal im TextBuf vorhanden ist, z.b.: }
+ // "Schiff-fahrt". Wenn nicht getrennt, dann wird "-f" entfernt. }
+
+
+
+UCHAR GetTextCharConv(UCHAR* TBuf, USHORT& Index,
+ ObjTextType& Atr0, ObjTextType& AktAtr,
+ USHORT Rest, BOOL ScanEsc)
+{
+ UCHAR c;
+
+ c=GetTextChar(TBuf,Index,Atr0,AktAtr,Rest,ScanEsc);
+ if (c<32) {
+ switch (c) {
+ case HardSpace : c=' '; break;
+ case AbsatzEnd : c=' '; break;
+ case HardTrenn : c='-';
+ }
+ }
+ return c;
+}
+
+
+// ======================================================================
+// Function GetLineFeed()
+//
+// Benoetigter Zeilenabstand in SGF-Units. ChrVPos wird beruecksichtigt.
+// ======================================================================
+USHORT GetLineFeed(UCHAR* TBuf, USHORT Index, ObjTextType Atr0, ObjTextType AktAtr,
+ USHORT nChar, USHORT& LF, USHORT& MaxGrad)
+{
+ UCHAR c=0;
+ BOOL AbsEnd=FALSE;
+ ULONG LF100=0;
+ ULONG MaxLF100=0;
+ BOOL LFauto=0;
+ BOOL First=TRUE;
+ USHORT Grad;
+ USHORT i=0;
+ USHORT r=1;
+
+ MaxGrad=0;
+ while (!AbsEnd && nChar>0) {
+ nChar--;
+ c=GetTextChar(TBuf,Index,Atr0,AktAtr,nChar,FALSE);
+ i++;
+ AbsEnd=(c==TextEnd || c==AbsatzEnd);
+ if (First || (!AbsEnd && c!=' ' && c!=HardTrenn)) {
+ LFauto=(AktAtr.LnFeed & 0x8000)==0;
+ LF100=AktAtr.LnFeed & 0x7FFF;
+ if (LFauto) LF100=LF100*AktAtr.Grad; else LF100*=LF100;
+ if (AktAtr.ChrVPos>0) LF100-=AktAtr.ChrVPos*100;
+ if (LF100>MaxLF100) MaxLF100=LF100;
+ Grad=AktAtr.Grad;
+ if (AktAtr.ChrVPos>0) Grad=Grad-AktAtr.ChrVPos;
+ if (Grad>MaxGrad) MaxGrad=Grad;
+ First=FALSE;
+ }
+ if (!AbsEnd && c!=' ') r=i;
+ }
+ MaxGrad=hPoint2Sgf(MaxGrad);
+ if (MaxLF100<=4000) { // sonst Overflowgefahr
+ LF=USHORT(hPoint2Sgf(short(MaxLF100)) /100);
+ } else {
+ LF=USHORT(hPoint2Sgf(short(MaxLF100) /100));
+ }
+
+ return r;
+}
+
+// End of AbsRead.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// iFont.Pas
+
+#define DefaultSlant 1500 /* Default: Italic ist 15deg */
+#define SuperSubFact 60 /* SuperScript/SubScript: 60% vom Schriftgrad */
+#define DefaultSpace 40 /* Default: Space ist 40% vom SchriftGrad */
+
+USHORT SetTextContext(OutputDevice& rOut, ObjTextType& Atr, BOOL Kapt, USHORT Dreh,
+ USHORT FitXMul, USHORT FitXDiv, USHORT FitYMul, USHORT FitYDiv)
+{
+ SgfFontOne* pSgfFont; // Font aus dem IniFile
+ Font aFont;
+ Color aColor;
+ ULONG Grad;
+ ULONG Brei;
+ String FNam;
+ USHORT StdBrei=50; // Durchschnittliche Zeichenbreite in % von Schriftgrad
+ BOOL bFit=(FitXMul!=1 || FitXDiv!=1 || FitYMul!=1 || FitYDiv!=1);
+
+ pSgfFont = pSgfFonts->GetFontDesc(Atr.GetFont());
+
+ if ( pSgfFont!=NULL )
+ {
+ FNam =pSgfFont->SVFName;
+ StdBrei=pSgfFont->SVWidth;
+ if (pSgfFont->Fixd) aFont.SetPitch(PITCH_FIXED); else aFont.SetPitch(PITCH_VARIABLE);
+ aFont.SetFamily(pSgfFont->SVFamil);
+ aFont.SetCharSet(pSgfFont->SVChSet);
+ aFont.SetName(FNam);
+ }
+ else
+ { // Falls nich im Inifile, sind hier einige Fonts hart kodiert
+ aFont.SetPitch(PITCH_VARIABLE);
+ switch (Atr.GetFont()) {
+ case 92500: case 92501: case 92504: case 92505:
+ {
+#if defined(WIN) || defined(WNT) || defined(PM2)
+ FNam=String::CreateFromAscii( "Times New Roman" ); // CG Times ist unter Windows und OS/2 Times New Roman
+#else
+ FNam=String::CreateFromAscii( "Times" ); // ansonsten ist das einfach Times
+#endif
+ StdBrei=40;
+ aFont.SetFamily(FAMILY_ROMAN);
+ } break;
+ case 94021: case 94022: case 94023: case 94024: {
+#if defined(WIN) || defined(WNT)
+ FNam=String::CreateFromAscii( "Arial", 5 ); // Univers ist unter Windows Arial
+#else
+ FNam=String::CreateFromAscii( "Helvetica" ); // und ansonsten Helvetica
+#endif
+ aFont.SetFamily(FAMILY_SWISS);
+ StdBrei=47;
+ } break;
+ case 93950: case 93951: case 93952: case 93953: {
+#if defined(WIN) || defined(WNT)
+ FNam=String::CreateFromAscii( "Courier New" ); // Der Vector-Courierfont unter Windows heisst Courier New
+#else
+ FNam=String::CreateFromAscii( "Courier" ); // ansonsten ist und bleibt Courier immer Courier
+#endif
+ aFont.SetFamily(FAMILY_ROMAN);
+ aFont.SetPitch(PITCH_FIXED);
+ } break;
+ default: FNam=String::CreateFromAscii( "Helvetica", 9 );
+ }
+ aFont.SetName(FNam);
+ //aFont.SetCharSet(CHARSET_SYSTEM);
+ }
+
+ Grad=ULONG(Atr.Grad);
+ if ((Atr.Schnitt & TextKaptBit) !=0 && Kapt) Grad=Grad*ULONG(Atr.Kapit)/100;
+ if ((Atr.Schnitt & TextSupSBit) !=0 || (Atr.Schnitt & TextSubSBit) !=0) Grad=Grad*SuperSubFact/100;
+ Brei=Grad;
+ if (Atr.Breite!=100 || bFit) {
+ if (bFit) {
+ Grad=Grad*ULONG(FitYMul)/ULONG(FitYDiv);
+ Brei=Brei*ULONG(FitXMul)/ULONG(FitXDiv);
+ }
+ Brei=Brei*ULONG(Atr.Breite)/100;
+ Brei=Brei*ULONG(StdBrei)/100;
+ aFont.SetSize(Size(hPoint2Sgf(USHORT(Brei)),hPoint2Sgf(USHORT(Grad))));
+ } else {
+ aFont.SetSize(Size(0,hPoint2Sgf(USHORT(Grad))));
+ }
+
+ aColor=Sgv2SvFarbe(Atr.L.LFarbe,Atr.L.LBFarbe,Atr.L.LIntens); aFont.SetColor(aColor);
+ aColor=Sgv2SvFarbe(Atr.F.FFarbe,Atr.F.FBFarbe,Atr.F.FIntens); aFont.SetFillColor(aColor);
+ aFont.SetTransparent(TRUE);
+ aFont.SetAlign(ALIGN_BASELINE);
+
+ Dreh/=10; Dreh=3600-Dreh; if (Dreh==3600) Dreh=0;
+ aFont.SetOrientation(Dreh);
+
+ if ((Atr.Schnitt & TextBoldBit) !=0) aFont.SetWeight(WEIGHT_BOLD);
+ if ((Atr.Schnitt & TextRSlnBit) !=0) aFont.SetItalic(ITALIC_NORMAL);
+ if ((Atr.Schnitt & TextUndlBit) !=0) aFont.SetUnderline(UNDERLINE_SINGLE);
+ if ((Atr.Schnitt & TextDbUnBit) !=0) aFont.SetUnderline(UNDERLINE_DOUBLE);
+ if ((Atr.Schnitt & TextStrkBit) !=0) aFont.SetStrikeout(STRIKEOUT_SINGLE);
+ if ((Atr.Schnitt & TextDbStBit) !=0) aFont.SetStrikeout(STRIKEOUT_DOUBLE);
+ if ((Atr.Schnitt & TextSh2DBit) !=0) aFont.SetShadow(TRUE);
+ if ((Atr.Schnitt & TextSh3DBit) !=0) aFont.SetShadow(TRUE);
+ if ((Atr.Schnitt & TextSh4DBit) !=0) aFont.SetShadow(TRUE);
+ if ((Atr.Schnitt & TextShEbBit) !=0) aFont.SetShadow(TRUE);
+ if (CheckTextOutl(Atr.F,Atr.L)) aFont.SetOutline(TRUE);
+
+ if (aFont!=rOut.GetFont()) rOut.SetFont(aFont);
+
+ return 0;
+}
+
+// iFont.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// Absatz.Pas
+
+struct ProcChrSta {
+ USHORT Index;
+ USHORT ChrXP;
+ UCHAR OutCh;
+ BOOL Kapt;
+ ObjTextType Attrib;
+};
+
+void InitProcessCharState(ProcChrSta& State, ObjTextType& AktAtr, USHORT IndexA)
+{
+ State.Attrib=AktAtr;
+ State.OutCh=0;
+ State.Index=IndexA;
+ State.ChrXP=0;
+ State.Kapt=FALSE;
+}
+
+BOOL UpcasePossible(UCHAR c)
+{
+ if ((c>='a' && c<='z') || c == 0xe4 || c == 0xf6 || c == 0xfc ) return TRUE;
+ else return FALSE;
+}
+
+UCHAR Upcase(UCHAR c)
+{
+ if ((c>=(UCHAR)'a' && c<=(UCHAR)'z')) c=(c-(UCHAR)'a')+(UCHAR)'A';
+ else if ( c == 0xe4 ) c = 0xc4;
+ else if ( c == 0xf6 ) c = 0xd6;
+ else if ( c == 0xfc ) c = 0xdc;
+ return c;
+}
+
+USHORT GetCharWidth(OutputDevice& rOut, UCHAR c)
+{
+ UCHAR c1;
+ USHORT ChrWidth;
+
+ c1 = ByteString::Convert((char)c,RTL_TEXTENCODING_IBM_437, gsl_getSystemTextEncoding() );
+ if (c==' ')
+ {
+ ChrWidth=(USHORT)rOut.GetTextWidth( String('A') );
+ if (rOut.GetFont().GetPitch()!=PITCH_FIXED) {
+ ChrWidth=MulDiv(ChrWidth,DefaultSpace,100);
+ }
+ } else {
+ // with MaxChar == 255 c cannot be greater than MaxChar
+ // assert if MaxChar is ever changed
+ OSL_ENSURE( MaxChar == 255, "MaxChar not 255" );
+ if (c>=MinChar /*&& c<=MaxChar*/)
+ {
+ ChrWidth=(USHORT)rOut.GetTextWidth(String((char)c1));
+ }
+ else
+ {
+ ChrWidth=(USHORT)rOut.GetTextWidth(String('A'));
+ }
+ }
+ return ChrWidth;
+}
+
+UCHAR ProcessChar(OutputDevice& rOut, UCHAR* TBuf, ProcChrSta& R, ObjTextType& Atr0,
+ USHORT& nChars, USHORT Rest,
+ short* Line, UCHAR* cLine)
+{
+ USHORT KernDist=0; // Wert fuer Kerning
+ USHORT ChrWidth;
+ UCHAR c;
+ UCHAR c1;
+ BOOL AbsEnd;
+
+ c=GetTextChar(TBuf,R.Index,Atr0,R.Attrib,Rest,FALSE); // versucht evtl. zu trennen, wenn Rest entsprechenden Wert besitzt
+
+ AbsEnd=(c==AbsatzEnd || c==TextEnd);
+ if (AbsEnd==FALSE) {
+ R.OutCh=ConvertTextChar(c); // von HardTrenn nach '-', ...
+ R.Kapt=(R.Attrib.Schnitt & TextKaptBit) !=0 && UpcasePossible(R.OutCh);
+ if (R.Kapt) R.OutCh=Upcase(R.OutCh);
+ SetTextContext(rOut,R.Attrib,R.Kapt,0,1,1,1,1);
+
+ if (R.Kapt) c1=Upcase(c); else c1=c;
+ ChrWidth=GetCharWidth(rOut,c1);
+
+ if (R.Attrib.ZAbst!=100) { // Spezial-Zeichenabstand ?
+ ULONG Temp;
+ Temp=ULONG(ChrWidth)*ULONG(R.Attrib.ZAbst)/100;
+ ChrWidth=USHORT(Temp);
+ }
+ nChars++;
+ if (R.ChrXP>32000) R.ChrXP=32000;
+ Line[nChars]=R.ChrXP-KernDist;
+ cLine[nChars]=c;
+ R.ChrXP+=ChrWidth-KernDist; // Position fuer den naechsten Character
+ }
+ return c;
+}
+
+void FormatLine(UCHAR* TBuf, USHORT& Index, ObjTextType& Atr0, ObjTextType& AktAtr,
+ USHORT UmbWdt, USHORT AdjWdt,
+ short* Line, USHORT& nChars,
+ double, double,
+ UCHAR* cLine, BOOL TextFit)
+{
+ VirtualDevice vOut;
+ UCHAR c,c0;
+ UCHAR ct;
+ BOOL First; // erster Char ?
+ BYTE Just = 0; // Absatzformatierung
+ BOOL Border; // Rand der Box erreicht ?
+ BOOL Border0;
+ BOOL AbsEnd; // Ende des Absatzes erreicht ?
+ ProcChrSta* R=new ProcChrSta;
+ ProcChrSta* R0=new ProcChrSta;
+ ProcChrSta* WErec=new ProcChrSta;
+ USHORT WEnChar;
+ ProcChrSta* WErec0=new ProcChrSta;
+ USHORT WEnChar0;
+ ProcChrSta* TRrec=new ProcChrSta;
+ USHORT TRnChar;
+
+ USHORT WordEndCnt; // Justieren und Trennen
+ BOOL WordEnd;
+ BOOL Trenn;
+
+ short BoxRest; // zum Quetschen und formatieren
+ USHORT i,j,k,h;
+ USHORT re,li;
+
+ vOut.SetMapMode(MapMode(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4)));
+
+ nChars=0;
+ SetTextContext(vOut,AktAtr,FALSE,0,1,1,1,1);
+ InitProcessCharState(*R,AktAtr,Index);
+ (*R0)=(*R); (*WErec)=(*R); WEnChar=0; c0=0; Border0=FALSE;
+ Border=FALSE; First=TRUE;
+ WordEndCnt=0;
+
+ do { // mal schauen, wieviele Worte so in die Zeile passen
+ if (Border) c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,DoTrenn,Line,cLine);
+ else c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine);
+ AbsEnd=(c==AbsatzEnd || c==TextEnd);
+ //if not AbsEnd then
+ {
+ if (First) {
+ Just=R->Attrib.Justify & 0x0F; // Absatzformat steht wenn, dann am Anfang
+ }
+ Border=R->ChrXP>UmbWdt;
+ WordEnd=(AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0);
+ Trenn=c=='-';
+ if (WordEnd && !Border0) {
+ WordEndCnt++;
+ (*WErec)=(*R0);
+ WEnChar=nChars-1;
+ }
+ if (Trenn && !Border) {
+ WordEndCnt++;
+ (*WErec)=(*R);
+ WEnChar=nChars;
+ }
+ }
+ (*R0)=(*R); c0=c;
+ Border0=Border;
+ First=FALSE;
+ AbsEnd=AbsEnd || (nChars>=MaxLineChars);
+ } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn))));
+
+ if (Border) { // Trennen und Quetschen
+ (*WErec0)=(*WErec); WEnChar0=WEnChar;
+ AbsEnd=FALSE; c0=0;
+ (*R)=(*WErec); nChars=WEnChar;
+ (*TRrec)=(*R); TRnChar=nChars;
+ Border0=FALSE; Border=FALSE;
+ do { // erst mal gucken wieviele Silben noch reinpassen
+ ct=ProcessChar(vOut,TBuf,*TRrec,Atr0,TRnChar,DoTrenn,Line,cLine);
+ c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine);
+ AbsEnd=(ct==AbsatzEnd) || (ct==TextEnd) || (nChars>=MaxLineChars);
+
+ Border=TRrec->ChrXP>UmbWdt;
+ WordEnd=AbsEnd || ((AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0));
+ Trenn=ct=='-';
+ if (WordEnd && (!Border0 || (WordEndCnt==0))) {
+ WordEndCnt++;
+ (*WErec)=(*R0);
+ if (AbsEnd) WEnChar=nChars; else WEnChar=nChars-1;
+ (*TRrec)=(*R); TRnChar=nChars; // zum weitersuchen
+ }
+ if (Trenn && (!Border || (WordEndCnt==0))) {
+ WordEndCnt++; // merken, dass man hier trennen kann
+ (*WErec)=(*TRrec);
+ WEnChar=TRnChar;
+ (*TRrec)=(*R); TRnChar=nChars; // zum weitersuchen
+ }
+ (*R0)=(*R); c0=c;
+ Border0=Border;
+ Border=R->ChrXP>UmbWdt;
+ } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn))));
+
+ while (WErec0->Index<WErec->Index) { // damit Line[] auch garantiert stimmt }
+ c=ProcessChar(vOut,TBuf,*WErec0,Atr0,WEnChar0,WEnChar-WEnChar0-1,Line,cLine);
+ }
+
+ (*R)=(*WErec); nChars=WEnChar;
+
+ if (UmbWdt>=R->ChrXP) {
+ BoxRest=UmbWdt-R->ChrXP;
+ } else { // Zusammenquetschen
+ BoxRest=R->ChrXP-UmbWdt; // um soviel muss gequetscht werden
+ for (i=2;i<=nChars;i++) { // 1. CharPosition bleibt !
+ Line[i]-=(i-1)*(BoxRest) /(nChars-1);
+ }
+ R->ChrXP=UmbWdt;
+ Line[nChars+1]=UmbWdt;
+ }
+ }
+
+ if (!AbsEnd) {
+ do { // Leerzeichen weglesen
+ (*WErec)=(*R);
+ c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,FALSE);
+ nChars++;
+ Line[nChars]=R->ChrXP;
+ cLine[nChars]=c;
+ } while (c==' ');
+ if (c!=' ' && c!=AbsatzEnd && c!=TextEnd) {
+ nChars--;
+ (*R)=(*WErec);
+ }
+ }
+
+ if (AbsEnd && nChars<MaxLineChars) { // Ausrichten, statt Blocksatz aber linksbuendig
+ if (Just==3) Just=0;
+ nChars++; Line[nChars]=R->ChrXP; // Damit AbsatzEnde auch weggelesen wird
+ Line[nChars+1]=R->ChrXP; // denn die Breite von CR oder #0 ist nun mal sehr klein
+ if (TBuf[R->Index-1]!=AbsatzEnd && TBuf[R->Index-1]!=TextEnd) {
+ c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,FALSE); // Kleine Korrektur. Notig, wenn nur 1 Wort in
+ }
+ }
+
+ BoxRest=AdjWdt-R->ChrXP;
+ if (TextFit) Just=THJustLeft;
+
+ switch (Just) {
+ case THJustLeft: break; // Links
+ case THJustCenter: {
+ BoxRest=BoxRest /2; // Mitte
+ for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest;
+ } break;
+ case THJustRight: { // Rechts
+ for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest;
+ } break;
+ case THJustDrvOut:
+ case THJustBlock: { // Block und Austreibend
+ re=nChars;
+ if (Just==THJustDrvOut) re--;
+ while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--;
+ li=1;
+ while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++;
+ if (Just==THJustDrvOut) BoxRest=AdjWdt-Line[re+1];
+
+ j=0; // Anzahl der Spaces ermitteln
+ for (i=li;i<=re;i++) {
+ if (cLine[i]==' ') {
+ j++;
+ }
+ }
+
+ if (j==0) { // nur 1 Wort ? -> Strecken !
+ for (i=li+1;i<=re;i++) { // von links nach rechts
+ Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1);
+ }
+ } else {
+ k=0; h=0;
+ for (i=li;i<=re;i++) { // j Spaces aufbohren !
+ if (cLine[i]==' ') { // Space gefunden !
+ k++;
+ h=MulDiv(k,BoxRest,j);
+ }
+ Line[i]=Line[i]+h;
+ }
+ }
+ for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // und den Rest anpassen
+ Line[nChars+1]=AdjWdt;
+ } break;
+ case THJustLocked: { //Gesperrt
+ re=nChars-1;
+ while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--;
+ li=1;
+ while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++;
+ BoxRest=AdjWdt-Line[re+1];
+ for (i=li+1;i<=re;i++) { // Strecken von links nach rechts
+ Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1);
+ }
+ for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // und den Rest anpassen
+ Line[nChars+1]=AdjWdt;
+ } break;
+ }
+ Index=R->Index;
+ AktAtr=R->Attrib;
+ delete R;
+ delete R0;
+ delete WErec;
+ delete WErec0;
+ delete TRrec;
+}
+
+
+
+// End of Absatz.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// DrawText.Pas
+
+void DrawChar(OutputDevice& rOut, UCHAR c, ObjTextType T, PointType Pos, USHORT DrehWink,
+ USHORT FitXMul, USHORT FitXDiv, USHORT FitYMul, USHORT FitYDiv)
+{
+ SetTextContext(rOut,T,UpcasePossible(c),DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv);
+ if ((T.Schnitt & TextKaptBit)!=0 && UpcasePossible(c)) c=Upcase(c);
+ String s( (char)c, RTL_TEXTENCODING_IBM_437 );
+ rOut.DrawText( Point( Pos.x, Pos.y ), s );
+}
+
+/*************************************************************************
+|*
+|* TextType::Draw()
+|*
+|* Beschreibung
+|* Ersterstellung JOE 09.08.93
+|* Letzte Aenderung JOE 09.08.93
+|*
+*************************************************************************/
+void TextType::Draw(OutputDevice& rOut)
+{
+ if ((Flags & TextOutlBit)!=0) return; // Sourcetext fuer Outliner !!
+
+ ObjTextType T1,T2;
+ USHORT Index1;
+ USHORT Index2;
+ UCHAR c = TextEnd;
+ USHORT l; // Anzahl der Zeichen in der Zeile
+ USHORT i;
+ short yPos0;
+ short xPos;
+ short yPos;
+ USHORT LF;
+ USHORT MaxGrad;
+ short xSize;
+ short xSAdj;
+ short ySize;
+ double sn,cs;
+ USHORT TopToBase;
+ BOOL Ende = 0;
+ USHORT lc;
+ BOOL LineFit; // FitSize.x=0? oder Flags -> jede Zeile stretchen
+ BOOL TextFit;
+ short* xLine;
+ UCHAR* cLine; // Buffer fuer FormatLine
+ USHORT FitXMul;
+ USHORT FitXDiv;
+ USHORT FitYMul;
+ USHORT FitYDiv;
+ BOOL Fehler;
+ UCHAR* Buf=Buffer; // Zeiger auf die Buchstaben
+
+ pSgfFonts->ReadList();
+ xLine=new short[ChrXPosArrSize];
+ cLine=new UCHAR[CharLineSize];
+
+ TextFit=(Flags & TextFitBits)!=0;
+ LineFit=FALSE;
+ LineFit=((Flags & TextFitZBit)!=0);
+ if (TextFit && FitSize.x==0) LineFit=TRUE;
+
+ if (DrehWink==0) {
+ sn=0.0;
+ cs=1.0;
+ } else {
+ sn=sin(double(DrehWink)*3.14159265359/18000);
+ cs=cos(double(DrehWink)*3.14159265359/18000);
+ }
+
+ T1=T; Index1=0; yPos=0; xPos=0;
+ if (TextFit) {
+ ySize=Pos2.y-Pos1.y;
+ xSize=32000 /2; // Umbruch
+ xSAdj=Pos2.x-Pos1.x; // zum Ausrichten bei Zentriert/Blocksatz
+ //if (xSize<=0) { xSize=32000 /2; LineFit=TRUE; }
+ FitXMul=sal::static_int_cast< USHORT >(abs(Pos2.x-Pos1.x)); FitXDiv=FitSize.x; if (FitXDiv==0) FitXDiv=1;
+ FitYMul=sal::static_int_cast< USHORT >(abs(Pos2.y-Pos1.y)); FitYDiv=FitSize.y; if (FitYDiv==0) FitYDiv=1;
+ } else {
+ xSize=Pos2.x-Pos1.x;
+ xSAdj=xSize;
+ ySize=Pos2.y-Pos1.y;
+ FitXMul=1; FitXDiv=1;
+ FitYMul=1; FitYDiv=1;
+ }
+ if (xSize<0) xSize=0;
+ if (xSAdj<0) xSAdj=0;
+
+ do {
+ T2=T1; Index2=Index1;
+ FormatLine(Buf,Index2,T,T2,xSize,xSAdj,xLine,l,sn,cs,cLine,LineFit);
+ Fehler=(Index2==Index1);
+ if (!Fehler) {
+ lc=GetLineFeed(Buf,Index1,T,T1,l,LF,MaxGrad);
+ if (TextFit) {
+ if (LineFit) FitXDiv=xLine[lc+1];
+ if (FitXDiv>0) {
+ long Temp;
+ for (i=1;i<=l+1;i++) {
+ Temp=long(xLine[i])*long(FitXMul) /long(FitXDiv);
+ xLine[i]=short(Temp);
+ }
+ LF=MulDiv(LF,FitYMul,FitYDiv);
+ MaxGrad=MulDiv(MaxGrad,FitYMul,FitYDiv);
+ } else {
+ FitXDiv=1; // 0 gibts nicht
+ }
+ }
+ yPos0=yPos;
+ TopToBase=GetTopToBaseLine(MaxGrad);
+ yPos=yPos+TopToBase;
+ Ende=(yPos0+short(MulDiv(MaxGrad,CharTopToBtm,100))>ySize) && !TextFit;
+ if (!Ende) {
+ T2=T1; Index2=Index1;
+ i=1;
+ while (i<=l) {
+ c=GetTextCharConv(Buf,Index2,T,T2,l-i,FALSE);
+ long xp1,yp1; // wegen Overflowgefahr
+ PointType Pos;
+ xp1=long(Pos1.x)+xPos+long(xLine[i]);
+ yp1=long(Pos1.y)+yPos;
+ if (xp1>32000) xp1=32000; if (xp1<-12000) xp1=-12000;
+ if (yp1>32000) yp1=32000; if (yp1<-12000) yp1=-12000;
+ Pos.x=short(xp1);
+ Pos.y=short(yp1);
+
+ if (DrehWink!=0) RotatePoint(Pos,Pos1.x,Pos1.y,sn,cs);
+ DrawChar(rOut,c,T2,Pos,DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv);
+ i++;
+ } // while i<=l
+ yPos=yPos0+LF;
+ T1=T2; Index1=Index2; // Fuer die naechste Zeile
+ } // if ObjMin.y+yPos<=Obj_Max.y
+ } // if !Fehler
+ } while (c!=TextEnd && !Ende && !Fehler);
+ delete[] cLine;
+ delete[] xLine;
+}
+
+// End of DrawText.Pas
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+// nicht mehr benoetigt, da der Pointer nun extra gefuehrt wird
+// (DEC Alpha hat naemlich 64Bit-Pointer!)
+//UCHAR* TextType::GetBufPtr()
+//{
+// ULONG Temp;
+// Temp=ULONG(BufLo)+0x00010000*ULONG(BufHi);
+// return (UCHAR*)Temp;
+//}
+//
+//void TextType::SetBufPtr(UCHAR* Ptr)
+//{
+// ULONG Temp=(ULONG)Ptr;
+// BufLo=USHORT(Temp & 0x0000FFFF);
+// BufHi=USHORT((Temp & 0xFFFF0000)>>16);
+//}
+
+UINT32 ObjTextType::GetFont()
+{
+ return ULONG(FontLo)+0x00010000*ULONG(FontHi);
+}
+
+void ObjTextType::SetFont(UINT32 FontID)
+{
+ FontLo=USHORT(FontID & 0x0000FFFF);
+ FontHi=USHORT((FontID & 0xFFFF0000)>>16);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// SGF.Ini lesen ////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+SgfFontOne::SgfFontOne()
+{
+ Next=NULL;
+ IFID=0;
+ Bold=FALSE;
+ Ital=FALSE;
+ Sans=FALSE;
+ Serf=FALSE;
+ Fixd=FALSE;
+ SVFamil=FAMILY_DONTKNOW;
+ SVChSet=RTL_TEXTENCODING_DONTKNOW;
+ SVWidth=40;
+}
+
+void SgfFontOne::ReadOne( ByteString& ID, ByteString& Dsc )
+{
+ USHORT i,j,n;
+ ByteString s;
+
+ if ( Dsc.Len() < 4 || ( Dsc.GetChar( 0 ) != '(' ) )
+ return;
+ i=1; // Erster Buchstabe des IF-Fontnamen. Davor ist eine '('
+ while ( i < Dsc.Len() && ( Dsc.GetChar( i ) !=')' ) )
+ i++;
+ Dsc.Erase(0,i+1); // IF-Fontname loeschen inkl. ()
+
+ if ( Dsc.Len() < 2 || ( Dsc.GetChar( Dsc.Len() - 1 ) !=')' ) )
+ return;
+ i=Dsc.Len()-2; // hier ist die ')' des SV-Fontnames
+ j=0;
+ while ( i > 0 && ( Dsc.GetChar( i ) != '(' ) )
+ {
+ i--;
+ j++;
+ }
+ SVFName=String(Dsc,i+1,j); // SV-Fontname rausholen
+ Dsc.Erase(i,j);
+
+ IFID = (UINT32)ID.ToInt32();
+ n=Dsc.GetTokenCount(' ');
+ for (i=0;i<n;i++)
+ {
+ s = Dsc.GetToken( i,' ' );
+ if ( s.Len() )
+ {
+ s.ToUpperAscii();
+ if ( s.CompareTo( "BOLD", 4 ) == COMPARE_EQUAL ) Bold=TRUE;
+ else if ( s.CompareTo( "ITAL", 4 ) == COMPARE_EQUAL ) Ital=TRUE;
+ else if ( s.CompareTo( "SERF", 4 ) == COMPARE_EQUAL ) Serf=TRUE;
+ else if ( s.CompareTo( "SANS", 4 ) == COMPARE_EQUAL ) Sans=TRUE;
+ else if ( s.CompareTo( "FIXD", 4 ) == COMPARE_EQUAL ) Fixd=TRUE;
+ else if ( s.CompareTo( "ROMAN", 5 ) == COMPARE_EQUAL ) SVFamil=FAMILY_ROMAN;
+ else if ( s.CompareTo( "SWISS", 5 ) == COMPARE_EQUAL ) SVFamil=FAMILY_SWISS;
+ else if ( s.CompareTo( "MODERN", 6 ) == COMPARE_EQUAL ) SVFamil=FAMILY_MODERN;
+ else if ( s.CompareTo( "SCRIPT", 6 ) == COMPARE_EQUAL ) SVFamil=FAMILY_SCRIPT;
+ else if ( s.CompareTo( "DECORA", 6 ) == COMPARE_EQUAL ) SVFamil=FAMILY_DECORATIVE;
+ else if ( s.CompareTo( "ANSI", 4 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_MS_1252;
+ else if ( s.CompareTo( "IBMPC", 5 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_IBM_850;
+ else if ( s.CompareTo( "MAC", 3 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_APPLE_ROMAN;
+ else if ( s.CompareTo( "SYMBOL", 6 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_SYMBOL;
+ else if ( s.CompareTo( "SYSTEM", 6 ) == COMPARE_EQUAL ) SVChSet = gsl_getSystemTextEncoding();
+ else if ( s.IsNumericAscii() ) SVWidth=sal::static_int_cast< USHORT >(s.ToInt32());
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+SgfFontLst::SgfFontLst()
+{
+ pList=NULL;
+ Last=NULL;
+ LastID=0;
+ LastLn=NULL;
+ Tried=FALSE;
+}
+
+SgfFontLst::~SgfFontLst()
+{
+ RausList();
+}
+
+void SgfFontLst::RausList()
+{
+ SgfFontOne* P;
+ SgfFontOne* P1;
+ P=pList;
+ while (P!=NULL) {
+ P1=P->Next;
+ delete P;
+ P=P1;
+ }
+ pList=NULL;
+ Last=NULL;
+ Tried=FALSE;
+ LastID=0;
+ LastLn=NULL;
+}
+
+void SgfFontLst::AssignFN(const String& rFName)
+{ FNam=rFName; }
+
+void SgfFontLst::ReadList()
+{
+ if (!Tried) {
+ Tried=TRUE;
+ LastID=0;
+ LastLn=NULL;
+ SgfFontOne* P,P1;
+ Config aCfg(FNam);
+ aCfg.SetGroup("SGV Fonts fuer StarView");
+ USHORT Anz=aCfg.GetKeyCount();
+ USHORT i;
+ ByteString FID,Dsc;
+
+ for (i=0;i<Anz;i++)
+ {
+ FID = aCfg.GetKeyName( i );
+ FID = FID.EraseAllChars(); // Leerzeichen weg
+ Dsc = aCfg.ReadKey( i );
+ if ( FID.IsNumericAscii() )
+ {
+ P=new SgfFontOne; // neuer Eintrag
+ if (Last!=NULL) Last->Next=P; else pList=P; Last=P; // einklinken
+ P->ReadOne(FID,Dsc); // und Zeile interpretieren
+ }
+ }
+ }
+}
+
+SgfFontOne* SgfFontLst::GetFontDesc(UINT32 ID)
+{
+ if (ID!=LastID) {
+ SgfFontOne* P;
+ P=pList;
+ while (P!=NULL && P->IFID!=ID) P=P->Next;
+ LastID=ID;
+ LastLn=P;
+ }
+ return LastLn;
+}
diff --git a/svtools/source/filter.vcl/filter/strings.hrc b/svtools/source/filter.vcl/filter/strings.hrc
new file mode 100644
index 000000000000..0eea67fb2338
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/strings.hrc
@@ -0,0 +1,27 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <svtools/svtools.hrc>
diff --git a/svtools/source/filter.vcl/filter/strings.src b/svtools/source/filter.vcl/filter/strings.src
new file mode 100644
index 000000000000..60e628ee0b5c
--- /dev/null
+++ b/svtools/source/filter.vcl/filter/strings.src
@@ -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.
+ *
+ ************************************************************************/
+
+#include "strings.hrc"
+
+String EXPORT_DIALOG_TITLE
+{
+ Text [ en-US ] = " Options" ;
+};
+
+String KEY_MODE
+{
+ Text = "ExportMode" ;
+};
+
+String KEY_RES
+{
+ Text = "Resolution" ;
+};
+
+String KEY_SIZE
+{
+ Text = "Size" ;
+};
+
+String KEY_COLORS
+{
+ Text = "Color" ;
+};
+
+String KEY_RLE_CODING
+{
+ Text = "RLE_Coding" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svtools/source/filter.vcl/igif/decode.cxx b/svtools/source/filter.vcl/igif/decode.cxx
new file mode 100644
index 000000000000..bfe77319b81a
--- /dev/null
+++ b/svtools/source/filter.vcl/igif/decode.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_svtools.hxx"
+
+#include "decode.hxx"
+
+// ------------------------------------------------------------------------
+
+struct GIFLZWTableEntry
+{
+ GIFLZWTableEntry* pPrev;
+ GIFLZWTableEntry* pFirst;
+ BYTE nData;
+};
+
+// ------------------------------------------------------------------------
+
+GIFLZWDecompressor::GIFLZWDecompressor( BYTE cDataSize ) :
+ nInputBitsBuf ( 0 ),
+ nOutBufDataLen ( 0 ),
+ nInputBitsBufSize ( 0 ),
+ bEOIFound ( FALSE ),
+ nDataSize ( cDataSize )
+{
+ pOutBuf = new BYTE[ 4096 ];
+
+ nClearCode = 1 << nDataSize;
+ nEOICode = nClearCode + 1;
+ nTableSize = nEOICode + 1;
+ nCodeSize = nDataSize + 1;
+ nOldCode = 0xffff;
+ pOutBufData = pOutBuf + 4096;
+
+ pTable = new GIFLZWTableEntry[ 4098 ];
+
+ for( USHORT i = 0; i < nTableSize; i++ )
+ {
+ pTable[i].pPrev = NULL;
+ pTable[i].pFirst = pTable + i;
+ pTable[i].nData = (BYTE) i;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+GIFLZWDecompressor::~GIFLZWDecompressor()
+{
+ delete[] pOutBuf;
+ delete[] pTable;
+}
+
+// ------------------------------------------------------------------------
+
+HPBYTE GIFLZWDecompressor::DecompressBlock( HPBYTE pSrc, BYTE cBufSize,
+ ULONG& rCount, BOOL& rEOI )
+{
+ ULONG nTargetSize = 4096;
+ ULONG nCount = 0;
+ HPBYTE pTarget = (HPBYTE) rtl_allocateMemory( nTargetSize );
+ HPBYTE pTmpTarget = pTarget;
+
+ nBlockBufSize = cBufSize;
+ nBlockBufPos = 0;
+ pBlockBuf = pSrc;
+
+ while( ProcessOneCode() )
+ {
+ nCount += nOutBufDataLen;
+
+ if( nCount > nTargetSize )
+ {
+ ULONG nNewSize = nTargetSize << 1;
+ ULONG nOffset = pTmpTarget - pTarget;
+ HPBYTE pTmp = (HPBYTE) rtl_allocateMemory( nNewSize );
+
+ memcpy( pTmp, pTarget, nTargetSize );
+ rtl_freeMemory( pTarget );
+
+ nTargetSize = nNewSize;
+ pTmpTarget = ( pTarget = pTmp ) + nOffset;
+ }
+
+ memcpy( pTmpTarget, pOutBufData, nOutBufDataLen );
+ pTmpTarget += nOutBufDataLen;
+ pOutBufData += nOutBufDataLen;
+ nOutBufDataLen = 0;
+
+ if ( bEOIFound )
+ break;
+ }
+
+ rCount = nCount;
+ rEOI = bEOIFound;
+
+ return pTarget;
+}
+
+// ------------------------------------------------------------------------
+
+void GIFLZWDecompressor::AddToTable( USHORT nPrevCode, USHORT nCodeFirstData )
+{
+ GIFLZWTableEntry* pE;
+
+ if( nTableSize < 4096 )
+ {
+ pE = pTable + nTableSize;
+ pE->pPrev = pTable + nPrevCode;
+ pE->pFirst = pE->pPrev->pFirst;
+ pE->nData = pTable[ nCodeFirstData ].pFirst->nData;
+ nTableSize++;
+
+ if ( ( nTableSize == (USHORT) (1 << nCodeSize) ) && ( nTableSize < 4096 ) )
+ nCodeSize++;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GIFLZWDecompressor::ProcessOneCode()
+{
+ GIFLZWTableEntry* pE;
+ USHORT nCode;
+ BOOL bRet = FALSE;
+ BOOL bEndOfBlock = FALSE;
+
+ while( nInputBitsBufSize < nCodeSize )
+ {
+ if( nBlockBufPos >= nBlockBufSize )
+ {
+ bEndOfBlock = TRUE;
+ break;
+ }
+
+ nInputBitsBuf |= ( (ULONG) pBlockBuf[ nBlockBufPos++ ] ) << nInputBitsBufSize;
+ nInputBitsBufSize += 8;
+ }
+
+ if ( !bEndOfBlock )
+ {
+ // Einen Code aus dem Eingabe-Buffer holen:
+ nCode = sal::static_int_cast< USHORT >(
+ ( (USHORT) nInputBitsBuf ) & ( ~( 0xffff << nCodeSize ) ));
+ nInputBitsBuf >>= nCodeSize;
+ nInputBitsBufSize = nInputBitsBufSize - nCodeSize;
+
+ if ( nCode < nClearCode )
+ {
+ if ( nOldCode != 0xffff )
+ AddToTable( nOldCode, nCode );
+ }
+ else if ( ( nCode > nEOICode ) && ( nCode <= nTableSize ) )
+ {
+ if ( nCode == nTableSize )
+ AddToTable( nOldCode, nOldCode );
+ else
+ AddToTable( nOldCode, nCode );
+ }
+ else
+ {
+ if ( nCode == nClearCode )
+ {
+ nTableSize = nEOICode + 1;
+ nCodeSize = nDataSize + 1;
+ nOldCode = 0xffff;
+ nOutBufDataLen = 0;
+ }
+ else
+ bEOIFound = TRUE;
+
+ return TRUE;
+ }
+
+ nOldCode = nCode;
+
+ // Zeichen(/-folge) des Codes nCode in den Ausgabe-Buffer schreiben:
+ pE = pTable + nCode;
+ do
+ {
+ nOutBufDataLen++;
+ *(--pOutBufData) = pE->nData;
+ pE = pE->pPrev;
+ }
+ while( pE );
+
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
diff --git a/svtools/source/filter.vcl/igif/decode.hxx b/svtools/source/filter.vcl/igif/decode.hxx
new file mode 100644
index 000000000000..3c6a61e7508d
--- /dev/null
+++ b/svtools/source/filter.vcl/igif/decode.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 _DECODE_HXX
+#define _DECODE_HXX
+
+#ifndef _BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+
+struct GIFLZWTableEntry;
+
+class GIFLZWDecompressor
+{
+ GIFLZWTableEntry* pTable;
+ HPBYTE pOutBuf;
+ HPBYTE pOutBufData;
+ HPBYTE pBlockBuf;
+ ULONG nInputBitsBuf;
+ USHORT nTableSize;
+ USHORT nClearCode;
+ USHORT nEOICode;
+ USHORT nCodeSize;
+ USHORT nOldCode;
+ USHORT nOutBufDataLen;
+ USHORT nInputBitsBufSize;
+ BOOL bEOIFound;
+ BYTE nDataSize;
+ BYTE nBlockBufSize;
+ BYTE nBlockBufPos;
+
+ void AddToTable(USHORT nPrevCode, USHORT nCodeFirstData);
+ BOOL ProcessOneCode();
+
+
+public:
+
+ GIFLZWDecompressor( BYTE cDataSize );
+ ~GIFLZWDecompressor();
+
+ HPBYTE DecompressBlock( HPBYTE pSrc, BYTE cBufSize, ULONG& rCount, BOOL& rEOI );
+};
+
+#endif
diff --git a/svtools/source/filter.vcl/igif/gifread.cxx b/svtools/source/filter.vcl/igif/gifread.cxx
new file mode 100644
index 000000000000..e4020c727ff4
--- /dev/null
+++ b/svtools/source/filter.vcl/igif/gifread.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_svtools.hxx"
+
+#define _GIFPRIVATE
+
+#include "decode.hxx"
+#include "gifread.hxx"
+
+// -----------
+// - Defines -
+// -----------
+
+#define NO_PENDING( rStm ) ( ( rStm ).GetError() != ERRCODE_IO_PENDING )
+
+// -------------
+// - GIFReader -
+// -------------
+
+GIFReader::GIFReader( SvStream& rStm ) :
+ aGPalette ( 256 ),
+ aLPalette ( 256 ),
+ rIStm ( rStm ),
+ pAcc8 ( NULL ),
+ pAcc1 ( NULL ),
+ nLastPos ( rStm.Tell() ),
+ nLogWidth100 ( 0UL ),
+ nLogHeight100 ( 0UL ),
+ nLoops ( 1 ),
+ eActAction ( GLOBAL_HEADER_READING ),
+ bGCTransparent ( FALSE ),
+ bImGraphicReady ( FALSE )
+{
+ maUpperName = UniString::CreateFromAscii( "SVIGIF", 6 );
+ pSrcBuf = new BYTE[ 256 ];
+ ClearImageExtensions();
+}
+
+// ------------------------------------------------------------------------
+
+GIFReader::~GIFReader()
+{
+ aImGraphic.SetContext( NULL );
+
+ if( pAcc1 )
+ aBmp1.ReleaseAccess( pAcc1 );
+
+ if( pAcc8 )
+ aBmp8.ReleaseAccess( pAcc8 );
+
+ delete[] pSrcBuf;
+}
+
+// ------------------------------------------------------------------------
+
+void GIFReader::ClearImageExtensions()
+{
+ nGCDisposalMethod = 0;
+ bGCTransparent = FALSE;
+ nTimer = 0;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GIFReader::CreateBitmaps( long nWidth, long nHeight, BitmapPalette* pPal,
+ BOOL bWatchForBackgroundColor )
+{
+ const Size aSize( nWidth, nHeight );
+
+ if( bGCTransparent )
+ {
+ const Color aWhite( COL_WHITE );
+
+ aBmp1 = Bitmap( aSize, 1 );
+
+ if( !aAnimation.Count() )
+ aBmp1.Erase( aWhite );
+
+ pAcc1 = aBmp1.AcquireWriteAccess();
+
+ if( pAcc1 )
+ {
+ cTransIndex1 = (BYTE) pAcc1->GetBestPaletteIndex( aWhite );
+ cNonTransIndex1 = cTransIndex1 ? 0 : 1;
+ }
+ else
+ bStatus = FALSE;
+ }
+
+ if( bStatus )
+ {
+ aBmp8 = Bitmap( aSize, 8, pPal );
+
+ if( !!aBmp8 && bWatchForBackgroundColor && aAnimation.Count() )
+ aBmp8.Erase( (*pPal)[ nBackgroundColor ] );
+ else
+ aBmp8.Erase( Color( COL_WHITE ) );
+
+ pAcc8 = aBmp8.AcquireWriteAccess();
+ bStatus = ( pAcc8 != NULL );
+ }
+
+ return bStatus;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GIFReader::ReadGlobalHeader()
+{
+ char pBuf[ 7 ];
+ BYTE nRF;
+ BYTE nAspect;
+ BOOL bRet = FALSE;
+
+ rIStm.Read( pBuf, 6 );
+ if( NO_PENDING( rIStm ) )
+ {
+ pBuf[ 6 ] = 0;
+ if( !strcmp( pBuf, "GIF87a" ) || !strcmp( pBuf, "GIF89a" ) )
+ {
+ rIStm.Read( pBuf, 7 );
+ if( NO_PENDING( rIStm ) )
+ {
+ SvMemoryStream aMemStm;
+
+ aMemStm.SetBuffer( pBuf, 7, FALSE, 7 );
+ aMemStm >> nGlobalWidth;
+ aMemStm >> nGlobalHeight;
+ aMemStm >> nRF;
+ aMemStm >> nBackgroundColor;
+ aMemStm >> nAspect;
+
+ bGlobalPalette = (BOOL) ( nRF & 0x80 );
+
+ if( bGlobalPalette )
+ ReadPaletteEntries( &aGPalette, 1 << ( ( nRF & 7 ) + 1 ) );
+ else
+ nBackgroundColor = 0;
+
+ if( NO_PENDING( rIStm ) )
+ bRet = TRUE;
+ }
+ }
+ else
+ bStatus = FALSE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void GIFReader::ReadPaletteEntries( BitmapPalette* pPal, ULONG nCount )
+{
+ const ULONG nLen = 3UL * nCount;
+ BYTE* pBuf = new BYTE[ nLen ];
+
+ rIStm.Read( pBuf, nLen );
+ if( NO_PENDING( rIStm ) )
+ {
+ BYTE* pTmp = pBuf;
+
+ for( ULONG i = 0UL; i < nCount; )
+ {
+ BitmapColor& rColor = (*pPal)[ (USHORT) i++ ];
+
+ rColor.SetRed( *pTmp++ );
+ rColor.SetGreen( *pTmp++ );
+ rColor.SetBlue( *pTmp++ );
+ }
+
+ // nach Moeglichkeit noch einige Standardfarben unterbringen
+ if( nCount < 256UL )
+ {
+ (*pPal)[ 255UL ] = Color( COL_WHITE );
+
+ if( nCount < 255UL )
+ (*pPal)[ 254UL ] = Color( COL_BLACK );
+ }
+ }
+
+ delete[] pBuf;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GIFReader::ReadExtension()
+{
+ BYTE cFunction;
+ BYTE cSize;
+ BYTE cByte;
+ BOOL bRet = FALSE;
+ BOOL bOverreadDataBlocks = FALSE;
+
+ // Extension-Label
+ rIStm >> cFunction;
+ if( NO_PENDING( rIStm ) )
+ {
+ // Block-Laenge
+ rIStm >> cSize;
+
+ switch( cFunction )
+ {
+ // 'Graphic Control Extension'
+ case( 0xf9 ) :
+ {
+ BYTE cFlags;
+
+ rIStm >> cFlags;
+ rIStm >> nTimer;
+ rIStm >> nGCTransparentIndex;
+ rIStm >> cByte;
+
+ if ( NO_PENDING( rIStm ) )
+ {
+ nGCDisposalMethod = ( cFlags >> 2) & 7;
+ bGCTransparent = ( cFlags & 1 ) ? TRUE : FALSE;
+ bStatus = ( cSize == 4 ) && ( cByte == 0 );
+ bRet = TRUE;
+ }
+ }
+ break;
+
+ // Application-Extension
+ case ( 0xff ) :
+ {
+ if ( NO_PENDING( rIStm ) )
+ {
+ // default diese Extension ueberlesen
+ bOverreadDataBlocks = TRUE;
+
+ // Appl.-Extension hat Laenge 11
+ if ( cSize == 0x0b )
+ {
+ ByteString aAppId;
+ ByteString aAppCode;
+
+ rIStm.Read( aAppId.AllocBuffer( 8 ), 8 );
+ rIStm.Read( aAppCode.AllocBuffer( 3 ), 3 );
+ rIStm >> cSize;
+
+ // NetScape-Extension
+ if( aAppId == "NETSCAPE" && aAppCode == "2.0" && cSize == 3 )
+ {
+ rIStm >> cByte;
+
+ // Loop-Extension
+ if ( cByte == 0x01 )
+ {
+ rIStm >> cByte;
+ nLoops = cByte;
+ rIStm >> cByte;
+ nLoops |= ( (USHORT) cByte << 8 );
+ rIStm >> cByte;
+
+ bStatus = ( cByte == 0 );
+ bRet = NO_PENDING( rIStm );
+ bOverreadDataBlocks = FALSE;
+
+ // Netscape interpretiert den LoopCount
+ // als reine Anzahl der _Wiederholungen_;
+ // bei uns ist es die Gesamtanzahl der
+ // Durchlaeufe
+ if( nLoops )
+ nLoops++;
+ }
+ else
+ rIStm.SeekRel( -1 );
+ }
+ else if ( aAppId == "STARDIV " && aAppCode == "5.0" && cSize == 9 )
+ {
+ rIStm >> cByte;
+
+ // Loop-Extension
+ if ( cByte == 0x01 )
+ {
+ rIStm >> nLogWidth100 >> nLogHeight100;
+ rIStm >> cByte;
+ bStatus = ( cByte == 0 );
+ bRet = NO_PENDING( rIStm );
+ bOverreadDataBlocks = FALSE;
+ }
+ else
+ rIStm.SeekRel( -1 );
+ }
+
+ }
+ }
+ }
+ break;
+
+ // alles andere ueberlesen
+ default:
+ bOverreadDataBlocks = TRUE;
+ break;
+ }
+
+ // Sub-Blocks ueberlesen
+ if ( bOverreadDataBlocks )
+ {
+ bRet = TRUE;
+ while( cSize && bStatus && !rIStm.IsEof() )
+ {
+ USHORT nCount = (USHORT) cSize + 1;
+ char* pBuffer = new char[ nCount ];
+
+ bRet = FALSE;
+ rIStm.Read( pBuffer, nCount );
+ if( NO_PENDING( rIStm ) )
+ {
+ cSize = (BYTE) pBuffer[ cSize ];
+ bRet = TRUE;
+ }
+ else
+ cSize = 0;
+
+ delete[] pBuffer;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GIFReader::ReadLocalHeader()
+{
+ BYTE pBuf[ 9 ];
+ BOOL bRet = FALSE;
+
+ rIStm.Read( pBuf, 9 );
+ if( NO_PENDING( rIStm ) )
+ {
+ SvMemoryStream aMemStm;
+ BitmapPalette* pPal;
+ BYTE nFlags;
+
+ aMemStm.SetBuffer( (char*) pBuf, 9, FALSE, 9 );
+ aMemStm >> nImagePosX;
+ aMemStm >> nImagePosY;
+ aMemStm >> nImageWidth;
+ aMemStm >> nImageHeight;
+ aMemStm >> nFlags;
+
+ // Falls Interlaced, ersten Startwert vorgeben
+ bInterlaced = ( ( nFlags & 0x40 ) == 0x40 );
+ nLastInterCount = 7;
+ nLastImageY = 0;
+
+ if( nFlags & 0x80 )
+ {
+ pPal = &aLPalette;
+ ReadPaletteEntries( pPal, 1 << ( (nFlags & 7 ) + 1 ) );
+ }
+ else
+ pPal = &aGPalette;
+
+ // Falls alles soweit eingelesen werden konnte, kann
+ // nun das lokale Bild angelegt werden;
+ // es wird uebergeben, ob der BackgroundColorIndex evtl.
+ // beruecksichtigt werden soll ( wenn Globale Farbtab. und
+ // diese auch fuer dieses Bild gilt )
+ if( NO_PENDING( rIStm ) )
+ {
+ CreateBitmaps( nImageWidth, nImageHeight, pPal, bGlobalPalette && ( pPal == &aGPalette ) );
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GIFReader::ReadNextBlock()
+{
+ ULONG nRet = 0UL;
+ ULONG nRead;
+ BYTE cBlockSize;
+
+ rIStm >> cBlockSize;
+
+ if ( rIStm.IsEof() )
+ nRet = 4UL;
+ else if ( NO_PENDING( rIStm ) )
+ {
+ if ( cBlockSize == 0 )
+ nRet = 2UL;
+ else
+ {
+ rIStm.Read( pSrcBuf, cBlockSize );
+
+ if( NO_PENDING( rIStm ) )
+ {
+ if( bOverreadBlock )
+ nRet = 3UL;
+ else
+ {
+ BOOL bEOI;
+ HPBYTE pTarget = pDecomp->DecompressBlock( pSrcBuf, cBlockSize, nRead, bEOI );
+
+ nRet = ( bEOI ? 3 : 1 );
+
+ if( nRead && !bOverreadBlock )
+ FillImages( pTarget, nRead );
+
+ rtl_freeMemory( pTarget );
+ }
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+void GIFReader::FillImages( HPBYTE pBytes, ULONG nCount )
+{
+ for( ULONG i = 0UL; i < nCount; i++ )
+ {
+ if( nImageX >= nImageWidth )
+ {
+ if( bInterlaced )
+ {
+ long nT1, nT2;
+
+ // falls Interlaced, werden die Zeilen kopiert
+ if( nLastInterCount )
+ {
+ long nMinY = Min( (long) nLastImageY + 1, (long) nImageHeight - 1 );
+ long nMaxY = Min( (long) nLastImageY + nLastInterCount, (long) nImageHeight - 1 );
+
+ // letzte gelesene Zeile kopieren, wenn Zeilen
+ // nicht zusanmmenfallen ( kommt vorm wenn wir am Ende des Bildes sind )
+ if( ( nMinY > nLastImageY ) && ( nLastImageY < ( nImageHeight - 1 ) ) )
+ {
+ HPBYTE pScanline8 = pAcc8->GetScanline( nYAcc );
+ ULONG nSize8 = pAcc8->GetScanlineSize();
+ HPBYTE pScanline1 = 0;
+ ULONG nSize1 = 0;
+
+ if( bGCTransparent )
+ {
+ pScanline1 = pAcc1->GetScanline( nYAcc );
+ nSize1 = pAcc1->GetScanlineSize();
+ }
+
+ for( long j = nMinY; j <= nMaxY; j++ )
+ {
+ memcpy( pAcc8->GetScanline( j ), pScanline8, nSize8 );
+
+ if( bGCTransparent )
+ memcpy( pAcc1->GetScanline( j ), pScanline1, nSize1 );
+ }
+ }
+ }
+
+ nT1 = ( ++nImageY ) << 3;
+ nLastInterCount = 7;
+
+ if( nT1 >= nImageHeight )
+ {
+ nT2 = nImageY - ( ( nImageHeight + 7 ) >> 3 );
+ nT1 = ( nT2 << 3 ) + 4;
+ nLastInterCount = 3;
+
+ if( nT1 >= nImageHeight )
+ {
+ nT2 -= ( nImageHeight + 3 ) >> 3;
+ nT1 = ( nT2 << 2 ) + 2;
+ nLastInterCount = 1;
+
+ if( nT1 >= nImageHeight )
+ {
+ nT2 -= ( nImageHeight + 1 ) >> 2;
+ nT1 = ( nT2 << 1 ) + 1;
+ nLastInterCount = 0;
+ }
+ }
+ }
+
+ nLastImageY = (USHORT) nT1;
+ nYAcc = nT1;
+ }
+ else
+ {
+ nLastImageY = ++nImageY;
+ nYAcc = nImageY;
+ }
+
+ // Zeile faengt von vorne an
+ nImageX = 0;
+ }
+
+ if( nImageY < nImageHeight )
+ {
+ const BYTE cTmp = pBytes[ i ];
+
+ if( bGCTransparent )
+ {
+ if( cTmp == nGCTransparentIndex )
+ pAcc1->SetPixel( nYAcc, nImageX++, cTransIndex1 );
+ else
+ {
+ pAcc8->SetPixel( nYAcc, nImageX, cTmp );
+ pAcc1->SetPixel( nYAcc, nImageX++, cNonTransIndex1 );
+ }
+ }
+ else
+ pAcc8->SetPixel( nYAcc, nImageX++, cTmp );
+ }
+ else
+ {
+ bOverreadBlock = TRUE;
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GIFReader::CreateNewBitmaps()
+{
+ AnimationBitmap aAnimBmp;
+
+ aBmp8.ReleaseAccess( pAcc8 );
+ pAcc8 = NULL;
+
+ if( bGCTransparent )
+ {
+ aBmp1.ReleaseAccess( pAcc1 );
+ pAcc1 = NULL;
+ aAnimBmp.aBmpEx = BitmapEx( aBmp8, aBmp1 );
+ }
+ else
+ aAnimBmp.aBmpEx = BitmapEx( aBmp8 );
+
+ aAnimBmp.aPosPix = Point( nImagePosX, nImagePosY );
+ aAnimBmp.aSizePix = Size( nImageWidth, nImageHeight );
+ aAnimBmp.nWait = ( nTimer != 65535 ) ? nTimer : ANIMATION_TIMEOUT_ON_CLICK;
+ aAnimBmp.bUserInput = FALSE;
+
+ if( nGCDisposalMethod == 2 )
+ aAnimBmp.eDisposal = DISPOSE_BACK;
+ else if( nGCDisposalMethod == 3 )
+ aAnimBmp.eDisposal = DISPOSE_PREVIOUS;
+ else
+ aAnimBmp.eDisposal = DISPOSE_NOT;
+
+ aAnimation.Insert( aAnimBmp );
+
+ if( aAnimation.Count() == 1 )
+ {
+ aAnimation.SetDisplaySizePixel( Size( nGlobalWidth, nGlobalHeight ) );
+ aAnimation.SetLoopCount( nLoops );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+const Graphic& GIFReader::GetIntermediateGraphic()
+{
+ // Intermediate-Graphic nur erzeugen, wenn schon
+ // Daten vorliegen, aber die Graphic noch nicht
+ // vollstaendig eingelesen wurde
+ if ( bImGraphicReady && !aAnimation.Count() )
+ {
+ Bitmap aBmp;
+
+ aBmp8.ReleaseAccess( pAcc8 );
+
+ if ( bGCTransparent )
+ {
+ aBmp1.ReleaseAccess( pAcc1 );
+ aImGraphic = BitmapEx( aBmp8, aBmp1 );
+
+ pAcc1 = aBmp1.AcquireWriteAccess();
+ bStatus = bStatus && ( pAcc1 != NULL );
+ }
+ else
+ aImGraphic = aBmp8;
+
+ pAcc8 = aBmp8.AcquireWriteAccess();
+ bStatus = bStatus && ( pAcc8 != NULL );
+ }
+
+ return aImGraphic;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GIFReader::ProcessGIF()
+{
+ BOOL bRead = FALSE;
+ BOOL bEnd = FALSE;
+
+ if ( !bStatus )
+ eActAction = ABORT_READING;
+
+ // Stream an die richtige Stelle bringen
+ rIStm.Seek( nLastPos );
+
+ switch( eActAction )
+ {
+ // naechsten Marker lesen
+ case( MARKER_READING ):
+ {
+ BYTE cByte;
+
+ rIStm >> cByte;
+
+ if( rIStm.IsEof() )
+ eActAction = END_READING;
+ else if( NO_PENDING( rIStm ) )
+ {
+ bRead = TRUE;
+
+ if( cByte == '!' )
+ eActAction = EXTENSION_READING;
+ else if( cByte == ',' )
+ eActAction = LOCAL_HEADER_READING;
+ else if( cByte == ';' )
+ eActAction = END_READING;
+ else
+ eActAction = ABORT_READING;
+ }
+ }
+ break;
+
+ // ScreenDescriptor lesen
+ case( GLOBAL_HEADER_READING ):
+ {
+ if( ( bRead = ReadGlobalHeader() ) == TRUE )
+ {
+ ClearImageExtensions();
+ eActAction = MARKER_READING;
+ }
+ }
+ break;
+
+
+ // Extension lesen
+ case( EXTENSION_READING ):
+ {
+ if( ( bRead = ReadExtension() ) == TRUE )
+ eActAction = MARKER_READING;
+ }
+ break;
+
+
+ // Image-Descriptor lesen
+ case( LOCAL_HEADER_READING ):
+ {
+ if( ( bRead = ReadLocalHeader() ) == TRUE )
+ {
+ nYAcc = nImageX = nImageY = 0;
+ eActAction = FIRST_BLOCK_READING;
+ }
+ }
+ break;
+
+
+ // ersten Datenblock lesen
+ case( FIRST_BLOCK_READING ):
+ {
+ BYTE cDataSize;
+
+ rIStm >> cDataSize;
+
+ if( rIStm.IsEof() )
+ eActAction = ABORT_READING;
+ else if( cDataSize > 12 )
+ bStatus = FALSE;
+ else if( NO_PENDING( rIStm ) )
+ {
+ bRead = TRUE;
+ pDecomp = new GIFLZWDecompressor( cDataSize );
+ eActAction = NEXT_BLOCK_READING;
+ bOverreadBlock = FALSE;
+ }
+ else
+ eActAction = FIRST_BLOCK_READING;
+ }
+ break;
+
+ // naechsten Datenblock lesen
+ case( NEXT_BLOCK_READING ):
+ {
+ USHORT nLastX = nImageX;
+ USHORT nLastY = nImageY;
+ ULONG nRet = ReadNextBlock();
+
+ // Return: 0:Pending / 1:OK; / 2:OK und letzter Block: / 3:EOI / 4:HardAbort
+ if( nRet )
+ {
+ bRead = TRUE;
+
+ if ( nRet == 1UL )
+ {
+ bImGraphicReady = TRUE;
+ eActAction = NEXT_BLOCK_READING;
+ bOverreadBlock = FALSE;
+ }
+ else
+ {
+ if( nRet == 2UL )
+ {
+ delete pDecomp;
+ CreateNewBitmaps();
+ eActAction = MARKER_READING;
+ ClearImageExtensions();
+ }
+ else if( nRet == 3UL )
+ {
+ eActAction = NEXT_BLOCK_READING;
+ bOverreadBlock = TRUE;
+ }
+ else
+ {
+ delete pDecomp;
+ CreateNewBitmaps();
+ eActAction = ABORT_READING;
+ ClearImageExtensions();
+ }
+ }
+ }
+ else
+ {
+ nImageX = nLastX;
+ nImageY = nLastY;
+ }
+ }
+ break;
+
+ // ein Fehler trat auf
+ case( ABORT_READING ):
+ {
+ bEnd = TRUE;
+ eActAction = END_READING;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Stream an die richtige Stelle bringen,
+ // falls Daten gelesen werden konnten
+ // entweder alte Position oder aktuelle Position
+ if( bRead || bEnd )
+ nLastPos = rIStm.Tell();
+
+ return bRead;
+}
+
+// ------------------------------------------------------------------------
+
+ReadState GIFReader::ReadGIF( Graphic& rGraphic )
+{
+ ReadState eReadState;
+
+ bStatus = TRUE;
+
+ while( ProcessGIF() && ( eActAction != END_READING ) ) {}
+
+ if( !bStatus )
+ eReadState = GIFREAD_ERROR;
+ else if( eActAction == END_READING )
+ eReadState = GIFREAD_OK;
+ else
+ {
+ if ( rIStm.GetError() == ERRCODE_IO_PENDING )
+ rIStm.ResetError();
+
+ eReadState = GIFREAD_NEED_MORE;
+ }
+
+ if( aAnimation.Count() == 1 )
+ {
+ rGraphic = aAnimation.Get( 0 ).aBmpEx;
+
+ if( nLogWidth100 && nLogHeight100 )
+ {
+ rGraphic.SetPrefSize( Size( nLogWidth100, nLogHeight100 ) );
+ rGraphic.SetPrefMapMode( MAP_100TH_MM );
+ }
+ }
+ else
+ rGraphic = aAnimation;
+
+ return eReadState;
+}
+
+
+// -------------
+// - ImportGIF -
+// -------------
+
+BOOL ImportGIF( SvStream & rStm, Graphic& rGraphic )
+{
+ GIFReader* pGIFReader = (GIFReader*) rGraphic.GetContext();
+ USHORT nOldFormat = rStm.GetNumberFormatInt();
+ ReadState eReadState;
+ BOOL bRet = TRUE;
+
+ rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ if( !pGIFReader )
+ pGIFReader = new GIFReader( rStm );
+
+ rGraphic.SetContext( NULL );
+ eReadState = pGIFReader->ReadGIF( rGraphic );
+
+ if( eReadState == GIFREAD_ERROR )
+ {
+ bRet = FALSE;
+ delete pGIFReader;
+ }
+ else if( eReadState == GIFREAD_OK )
+ delete pGIFReader;
+ else
+ {
+ rGraphic = pGIFReader->GetIntermediateGraphic();
+ rGraphic.SetContext( pGIFReader );
+ }
+
+ rStm.SetNumberFormatInt( nOldFormat );
+
+ return bRet;
+}
diff --git a/svtools/source/filter.vcl/igif/makefile.mk b/svtools/source/filter.vcl/igif/makefile.mk
new file mode 100644
index 000000000000..0821591e0178
--- /dev/null
+++ b/svtools/source/filter.vcl/igif/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=svtools
+TARGET=igif
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+SOLARINC+=-I../../inc
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/gifread.obj \
+ $(SLO)$/decode.obj
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/filter.vcl/ixbm/makefile.mk b/svtools/source/filter.vcl/ixbm/makefile.mk
new file mode 100644
index 000000000000..55708d2f2630
--- /dev/null
+++ b/svtools/source/filter.vcl/ixbm/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=svtools
+TARGET=ixbm
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+SOLARINC+=-I../../inc
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/xbmread.obj
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/filter.vcl/ixbm/xbmread.cxx b/svtools/source/filter.vcl/ixbm/xbmread.cxx
new file mode 100644
index 000000000000..9c7faaafa88c
--- /dev/null
+++ b/svtools/source/filter.vcl/ixbm/xbmread.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_svtools.hxx"
+
+#define XBMMINREAD 512
+
+#define _XBMPRIVATE
+#include <ctype.h>
+#include "xbmread.hxx"
+
+// -------------
+// - XBMReader -
+// -------------
+
+XBMReader::XBMReader( SvStream& rStm ) :
+ rIStm ( rStm ),
+ pAcc1 ( NULL ),
+ nLastPos ( rStm.Tell() ),
+ nWidth ( 0 ),
+ nHeight ( 0 ),
+ bStatus ( TRUE )
+{
+ pHexTable = new short[ 256 ];
+ maUpperName = String::CreateFromAscii( "SVIXBM", 6 );
+ InitTable();
+}
+
+// ------------------------------------------------------------------------
+
+XBMReader::~XBMReader()
+{
+ delete[] pHexTable;
+
+ if( pAcc1 )
+ aBmp1.ReleaseAccess( pAcc1 );
+}
+
+// ------------------------------------------------------------------------
+
+void XBMReader::InitTable()
+{
+ memset( pHexTable, 0, sizeof( short ) );
+
+ pHexTable['0'] = 0;
+ pHexTable['1'] = 1;
+ pHexTable['2'] = 2;
+ pHexTable['3'] = 3;
+ pHexTable['4'] = 4;
+ pHexTable['5'] = 5;
+ pHexTable['6'] = 6;
+ pHexTable['7'] = 7;
+ pHexTable['8'] = 8;
+ pHexTable['9'] = 9;
+ pHexTable['A'] = 10;
+ pHexTable['B'] = 11;
+ pHexTable['C'] = 12;
+ pHexTable['D'] = 13;
+ pHexTable['E'] = 14;
+ pHexTable['F'] = 15;
+ pHexTable['X'] = 0;
+ pHexTable['a'] = 10;
+ pHexTable['b'] = 11;
+ pHexTable['c'] = 12;
+ pHexTable['d'] = 13;
+ pHexTable['e'] = 14;
+ pHexTable['f'] = 15;
+ pHexTable['x'] = 0;
+ pHexTable[' '] = -1;
+ pHexTable[','] = -1;
+ pHexTable['}'] = -1;
+ pHexTable['\n'] = -1;
+ pHexTable['\t'] = -1;
+ pHexTable['\0'] = -1;
+}
+
+// ------------------------------------------------------------------------
+
+ByteString XBMReader::FindTokenLine( SvStream* pInStm, const char* pTok1,
+ const char* pTok2, const char* pTok3 )
+{
+ ByteString aRet;
+ long nPos1;
+ long nPos2;
+ long nPos3;
+
+ bStatus = FALSE;
+
+ do
+ {
+ if( !pInStm->ReadLine( aRet ) )
+ break;
+
+ if( pTok1 )
+ {
+ if( ( nPos1 = aRet.Search( pTok1 ) ) != STRING_NOTFOUND )
+ {
+ bStatus = TRUE;
+
+ if( pTok2 )
+ {
+ bStatus = FALSE;
+
+ if( ( ( nPos2 = aRet.Search( pTok2 ) ) != STRING_NOTFOUND ) &&
+ ( nPos2 > nPos1 ) )
+ {
+ bStatus = TRUE;
+
+ if( pTok3 )
+ {
+ bStatus = FALSE;
+
+ if( ( ( nPos3 = aRet.Search( pTok3 ) ) != STRING_NOTFOUND ) && ( nPos3 > nPos2 ) )
+ bStatus = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ while( !bStatus );
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------
+
+long XBMReader::ParseDefine( const sal_Char* pDefine )
+{
+ long nRet = 0;
+ char* pTmp = (char*) pDefine;
+ unsigned char cTmp;
+
+ // bis zum Ende gehen
+ pTmp += ( strlen( pDefine ) - 1 );
+ cTmp = *pTmp--;
+
+ // letzte Ziffer suchen
+ while( pHexTable[ cTmp ] == -1 )
+ cTmp = *pTmp--;
+
+ // bis vor die Zahl laufen
+ while( pHexTable[ cTmp ] != -1 )
+ cTmp = *pTmp--;
+
+ // auf Anfang der Zahl gehen
+ pTmp += 2;
+
+ // Hex lesen
+ if( ( pTmp[0] == '0' ) && ( ( pTmp[1] == 'X' ) || ( pTmp[1] == 'x' ) ) )
+ {
+ pTmp += 2;
+ cTmp = *pTmp++;
+
+ while ( pHexTable[ cTmp ] != -1 )
+ {
+ nRet = ( nRet << 4 ) + pHexTable[ cTmp ];
+ cTmp = *pTmp++;
+ }
+ }
+ // Dezimal lesen
+ else
+ {
+ cTmp = *pTmp++;
+ while( ( cTmp >= '0' ) && ( cTmp <= '9' ) )
+ {
+ nRet = nRet * 10 + ( cTmp - '0' );
+ cTmp = *pTmp++;
+ }
+ }
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL XBMReader::ParseData( SvStream* pInStm, const ByteString& aLastLine, XBMFormat eFormat )
+{
+ ByteString aLine;
+ long nRow = 0;
+ long nCol = 0;
+ long nBits = ( eFormat == XBM10 ) ? 16 : 8;
+ long nBit;
+ USHORT nValue;
+ USHORT nDigits;
+ BOOL bFirstLine = TRUE;
+
+ while( nRow < nHeight )
+ {
+ if( bFirstLine )
+ {
+ xub_StrLen nPos;
+
+ // einfuehrende geschweifte Klammer loeschen
+ if( (nPos = ( aLine = aLastLine ).Search( '{' ) ) != STRING_NOTFOUND )
+ aLine.Erase( 0, nPos + 1 );
+
+ bFirstLine = FALSE;
+ }
+ else if( !pInStm->ReadLine( aLine ) )
+ break;
+
+ if( aLine.Len() )
+ {
+ const USHORT nCount = aLine.GetTokenCount( ',' );
+
+ for( USHORT i = 0; ( i < nCount ) && ( nRow < nHeight ); i++ )
+ {
+ const ByteString aToken( aLine.GetToken( i, ',' ) );
+ const xub_StrLen nLen = aToken.Len();
+ BOOL bProcessed = FALSE;
+
+ nBit = nDigits = nValue = 0;
+
+ for( xub_StrLen n = 0UL; n < nLen; n++ )
+ {
+ const unsigned char cChar = aToken.GetChar( n );
+ const short nTable = pHexTable[ cChar ];
+
+ if( isxdigit( cChar ) || !nTable )
+ {
+ nValue = ( nValue << 4 ) + nTable;
+ nDigits++;
+ bProcessed = TRUE;
+ }
+ else if( ( nTable < 0 ) && nDigits )
+ {
+ bProcessed = TRUE;
+ break;
+ }
+ }
+
+ if( bProcessed )
+ {
+ while( ( nCol < nWidth ) && ( nBit < nBits ) )
+ pAcc1->SetPixel( nRow, nCol++, ( nValue & ( 1 << nBit++ ) ) ? aBlack : aWhite );
+
+ if( nCol == nWidth )
+ nCol = 0, nRow++;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+// ------------------------------------------------------------------------
+
+ReadState XBMReader::ReadXBM( Graphic& rGraphic )
+{
+ ReadState eReadState;
+ BYTE cDummy;
+
+ // sehen, ob wir _alles_ lesen koennen
+ rIStm.Seek( STREAM_SEEK_TO_END );
+ rIStm >> cDummy;
+
+ // falls wir nicht alles lesen koennen
+ // kehren wir zurueck und warten auf neue Daten
+ if ( rIStm.GetError() != ERRCODE_IO_PENDING )
+ {
+ ByteString aLine;
+ int nValue;
+
+ rIStm.Seek( nLastPos );
+ bStatus = FALSE;
+ aLine = FindTokenLine( &rIStm, "#define", "_width" );
+
+ if ( bStatus )
+ {
+ if ( ( nValue = (int) ParseDefine( aLine.GetBuffer() ) ) > 0 )
+ {
+ nWidth = nValue;
+ aLine = FindTokenLine( &rIStm, "#define", "_height" );
+
+ // Falls die Hoehe nicht folgt, suchen wir noch
+ // einmal vom Anfang der Datei an
+ if ( !bStatus )
+ {
+ rIStm.Seek( nLastPos );
+ aLine = FindTokenLine( &rIStm, "#define", "_height" );
+ }
+ }
+ else
+ bStatus = FALSE;
+
+ if ( bStatus )
+ {
+ if ( ( nValue = (int) ParseDefine( aLine.GetBuffer() ) ) > 0 )
+ {
+ nHeight = nValue;
+ aLine = FindTokenLine( &rIStm, "static", "_bits" );
+
+ if ( bStatus )
+ {
+ XBMFormat eFormat = XBM10;
+
+ if ( aLine.Search( "short" ) != STRING_NOTFOUND )
+ eFormat = XBM10;
+ else if ( aLine.Search( "char" ) != STRING_NOTFOUND )
+ eFormat = XBM11;
+ else
+ bStatus = FALSE;
+
+ if ( bStatus && nWidth && nHeight )
+ {
+ aBmp1 = Bitmap( Size( nWidth, nHeight ), 1 );
+ pAcc1 = aBmp1.AcquireWriteAccess();
+
+ if( pAcc1 )
+ {
+ aWhite = pAcc1->GetBestMatchingColor( Color( COL_WHITE ) );
+ aBlack = pAcc1->GetBestMatchingColor( Color( COL_BLACK ) );
+ bStatus = ParseData( &rIStm, aLine, eFormat );
+ }
+ else
+ bStatus = FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ if( bStatus )
+ {
+ Bitmap aBlackBmp( Size( pAcc1->Width(), pAcc1->Height() ), 1 );
+
+ aBmp1.ReleaseAccess( pAcc1 ), pAcc1 = NULL;
+ aBlackBmp.Erase( Color( COL_BLACK ) );
+ rGraphic = BitmapEx( aBlackBmp, aBmp1 );
+ eReadState = XBMREAD_OK;
+ }
+ else
+ eReadState = XBMREAD_ERROR;
+ }
+ else
+ {
+ rIStm.ResetError();
+ eReadState = XBMREAD_NEED_MORE;
+ }
+
+ return eReadState;
+}
+
+// -------------
+// - ImportXBM -
+// -------------
+
+BOOL ImportXBM( SvStream& rStm, Graphic& rGraphic )
+{
+ XBMReader* pXBMReader = (XBMReader*) rGraphic.GetContext();
+ ReadState eReadState;
+ BOOL bRet = TRUE;
+
+ if( !pXBMReader )
+ pXBMReader = new XBMReader( rStm );
+
+ rGraphic.SetContext( NULL );
+ eReadState = pXBMReader->ReadXBM( rGraphic );
+
+ if( eReadState == XBMREAD_ERROR )
+ {
+ bRet = FALSE;
+ delete pXBMReader;
+ }
+ else if( eReadState == XBMREAD_OK )
+ delete pXBMReader;
+ else
+ rGraphic.SetContext( pXBMReader );
+
+ return bRet;
+}
diff --git a/svtools/source/filter.vcl/ixpm/makefile.mk b/svtools/source/filter.vcl/ixpm/makefile.mk
new file mode 100644
index 000000000000..98f93290d325
--- /dev/null
+++ b/svtools/source/filter.vcl/ixpm/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=svtools
+TARGET=ixpm
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+SOLARINC+=-I../../inc
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/xpmread.obj
+
+.INCLUDE : target.mk
diff --git a/svtools/source/filter.vcl/ixpm/rgbtable.hxx b/svtools/source/filter.vcl/ixpm/rgbtable.hxx
new file mode 100644
index 000000000000..afdab883b369
--- /dev/null
+++ b/svtools/source/filter.vcl/ixpm/rgbtable.hxx
@@ -0,0 +1,695 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+struct XPMRGBTab
+{
+ const char* name;
+ BYTE red;
+ BYTE green;
+ BYTE blue;
+};
+
+static XPMRGBTab pRGBTable[] = {
+{ "white", 255, 255, 255 },
+{ "black", 0, 0, 0 },
+{ "snow", 255, 250, 250 },
+{ "GhostWhite", 248, 248, 255 },
+{ "WhiteSmoke", 245, 245, 245 },
+{ "gainsboro", 220, 220, 220 },
+{ "FloralWhite", 255, 250, 240 },
+{ "OldLace", 253, 245, 230 },
+{ "linen", 250, 240, 230 },
+{ "AntiqueWhite", 250, 235, 215 },
+{ "PapayaWhip", 255, 239, 213 },
+{ "BlanchedAlmond", 255, 235, 205 },
+{ "bisque", 255, 228, 196 },
+{ "PeachPuff", 255, 218, 185 },
+{ "NavajoWhite", 255, 222, 173 },
+{ "moccasin", 255, 228, 181 },
+{ "cornsilk", 255, 248, 220 },
+{ "ivory", 255, 255, 240 },
+{ "LemonChiffon", 255, 250, 205 },
+{ "seashell", 255, 245, 238 },
+{ "honeydew", 240, 255, 240 },
+{ "MintCream", 245, 255, 250 },
+{ "azure", 240, 255, 255 },
+{ "AliceBlue", 240, 248, 255 },
+{ "lavender", 230, 230, 250 },
+{ "LavenderBlush", 255, 240, 245 },
+{ "MistyRose", 255, 228, 225 },
+{ "DarkSlateGray", 47, 79, 79 },
+{ "DarkSlateGrey", 47, 79, 79 },
+{ "DimGray", 105, 105, 105 },
+{ "DimGrey", 105, 105, 105 },
+{ "SlateGray", 112, 128, 144 },
+{ "SlateGrey", 112, 128, 144 },
+{ "LightSlateGray", 119, 136, 153 },
+{ "LightSlateGrey", 119, 136, 153 },
+{ "gray", 190, 190, 190 },
+{ "grey", 190, 190, 190 },
+{ "LightGrey", 211, 211, 211 },
+{ "LightGray", 211, 211, 211 },
+{ "MidnightBlue", 25, 25, 112 },
+{ "navy", 0, 0, 128 },
+{ "NavyBlue", 0, 0, 128 },
+{ "CornflowerBlue", 100, 149, 237 },
+{ "DarkSlateBlue", 72, 61, 139 },
+{ "SlateBlue", 106, 90, 205 },
+{ "MediumSlateBlue", 123, 104, 238 },
+{ "LightSlateBlue", 132, 112, 255 },
+{ "MediumBlue", 0, 0, 205 },
+{ "RoyalBlue", 65, 105, 225 },
+{ "blue", 0, 0, 255 },
+{ "DodgerBlue", 30, 144, 255 },
+{ "DeepSkyBlue", 0, 191, 255 },
+{ "SkyBlue", 135, 206, 235 },
+{ "LightSkyBlue", 135, 206, 250 },
+{ "SteelBlue", 70, 130, 180 },
+{ "LightSteelBlue", 176, 196, 222 },
+{ "LightBlue", 173, 216, 230 },
+{ "PowderBlue", 176, 224, 230 },
+{ "PaleTurquoise", 175, 238, 238 },
+{ "DarkTurquoise", 0, 206, 209 },
+{ "MediumTurquoise", 72, 209, 204 },
+{ "turquoise", 64, 224, 208 },
+{ "cyan", 0, 255, 255 },
+{ "LightCyan", 224, 255, 255 },
+{ "CadetBlue", 95, 158, 160 },
+{ "MediumAquamarine", 102, 205, 170 },
+{ "aquamarine", 127, 255, 212 },
+{ "DarkGreen", 0, 100, 0 },
+{ "DarkOliveGreen", 85, 107, 47 },
+{ "DarkSeaGreen", 143, 188, 143 },
+{ "SeaGreen", 46, 139, 87 },
+{ "MediumSeaGreen", 60, 179, 113 },
+{ "LightSeaGreen", 32, 178, 170 },
+{ "PaleGreen", 152, 251, 152 },
+{ "SpringGreen", 0, 255, 127 },
+{ "LawnGreen", 124, 252, 0 },
+{ "green", 0, 255, 0 },
+{ "chartreuse", 127, 255, 0 },
+{ "MediumSpringGreen", 0, 250, 154 },
+{ "GreenYellow", 173, 255 , 47 },
+{ "LimeGreen", 50, 205, 50 },
+{ "YellowGreen", 154, 205, 50 },
+{ "ForestGreen", 34, 139, 34 },
+{ "OliveDrab", 107, 142, 35 },
+{ "DarkKhaki", 189, 183, 107 },
+{ "khaki", 240, 230, 140 },
+{ "PaleGoldenrod", 238, 232, 170 },
+{ "LightGoldenrodYellow", 250, 250, 210 },
+{ "LightYellow", 255, 255, 224 },
+{ "yellow", 255, 255, 0 },
+{ "gold", 255, 215, 0 },
+{ "LightGoldenrod", 238, 221, 130 },
+{ "goldenrod", 218, 165, 32 },
+{ "DarkGoldenrod", 184, 134, 11 },
+{ "RosyBrown", 188, 143, 143 },
+{ "IndianRed", 205, 92, 92 },
+{ "SaddleBrown", 139, 69, 19 },
+{ "sienna", 160, 82, 45 },
+{ "peru", 205, 133, 63 },
+{ "burlywood", 222, 184, 135 },
+{ "beige", 245, 245, 220 },
+{ "wheat", 245, 222, 179 },
+{ "SandyBrown", 244, 164, 96 },
+{ "tan", 210, 180, 140 },
+{ "chocolate", 210, 105, 30 },
+{ "firebrick", 178, 34, 34 },
+{ "brown", 165, 42, 42 },
+{ "DarkSalmon", 233, 150, 122 },
+{ "salmon", 250, 128, 114 },
+{ "LightSalmon", 255, 160, 122 },
+{ "orange", 255, 165, 0 },
+{ "DarkOrange", 255, 140, 0 },
+{ "coral", 255, 127, 80 },
+{ "LightCoral", 240, 128, 128 },
+{ "tomato", 255, 99, 71 },
+{ "OrangeRed", 255, 69, 0 },
+{ "red", 255, 0, 0 },
+{ "HotPink", 255, 105, 180 },
+{ "DeepPink", 255, 20, 147 },
+{ "pink", 255, 192, 203 },
+{ "LightPink", 255, 182, 193 },
+{ "PaleVioletRed", 219, 112, 147 },
+{ "maroon", 176, 48, 96 },
+{ "MediumVioletRed", 199, 21, 133 },
+{ "VioletRed", 208, 32, 144 },
+{ "magenta", 255, 0, 255 },
+{ "violet", 238, 130, 238 },
+{ "plum", 221, 160, 221 },
+{ "orchid", 218, 112, 214 },
+{ "MediumOrchid", 186, 85, 211 },
+{ "DarkOrchid", 153, 50, 204 },
+{ "DarkViolet", 148, 0, 211 },
+{ "BlueViolet", 138, 43, 226 },
+{ "purple", 160, 32, 240 },
+{ "MediumPurple", 147, 112, 219 },
+{ "thistle", 216, 191, 216 },
+{ "snow1", 255, 250, 250 },
+{ "snow2", 238, 233, 233 },
+{ "snow3", 205, 201, 201 },
+{ "snow4", 139, 137, 137 },
+{ "seashell1", 255, 245, 238 },
+{ "seashell2", 238, 229, 222 },
+{ "seashell3", 205, 197, 191 },
+{ "seashell4", 139, 134, 130 },
+{ "AntiqueWhite1", 255, 239, 219 },
+{ "AntiqueWhite2", 238, 223, 204 },
+{ "AntiqueWhite3", 205, 192, 176 },
+{ "AntiqueWhite4", 139, 131, 120 },
+{ "bisque1", 255, 228, 196 },
+{ "bisque2", 238, 213, 183 },
+{ "bisque3", 205, 183, 158 },
+{ "bisque4", 139, 125, 107 },
+{ "PeachPuff1", 255, 218, 185 },
+{ "PeachPuff2", 238, 203, 173 },
+{ "PeachPuff3", 205, 175, 149 },
+{ "PeachPuff4", 139, 119, 101 },
+{ "NavajoWhite1", 255, 222, 173 },
+{ "NavajoWhite2", 238, 207, 161 },
+{ "NavajoWhite3", 205, 179, 139 },
+{ "NavajoWhite4", 139, 121, 94 },
+{ "LemonChiffon1", 255, 250, 205 },
+{ "LemonChiffon2", 238, 233, 191 },
+{ "LemonChiffon3", 205, 201, 165 },
+{ "LemonChiffon4", 139, 137, 112 },
+{ "cornsilk1", 255, 248, 220 },
+{ "cornsilk2", 238, 232, 205 },
+{ "cornsilk3", 205, 200, 177 },
+{ "cornsilk4", 139, 136, 120 },
+{ "ivory1", 255, 255, 240 },
+{ "ivory2", 238, 238, 224 },
+{ "ivory3", 205, 205, 193 },
+{ "ivory4", 139, 139, 131 },
+{ "honeydew1", 240, 255, 240 },
+{ "honeydew2", 224, 238, 224 },
+{ "honeydew3", 193, 205, 193 },
+{ "honeydew4", 131, 139, 131 },
+{ "LavenderBlush1", 255, 240, 245 },
+{ "LavenderBlush2", 238, 224, 229 },
+{ "LavenderBlush3", 205, 193, 197 },
+{ "LavenderBlush4", 139, 131, 134 },
+{ "MistyRose1", 255, 228, 225 },
+{ "MistyRose2", 238, 213, 210 },
+{ "MistyRose3", 205, 183, 181 },
+{ "MistyRose4", 139, 125, 123 },
+{ "azure1", 240, 255, 255 },
+{ "azure2", 224, 238, 238 },
+{ "azure3", 193, 205, 205 },
+{ "azure4", 131, 139, 139 },
+{ "SlateBlue1", 131, 111, 255 },
+{ "SlateBlue2", 122, 103, 238 },
+{ "SlateBlue3", 105, 89, 205 },
+{ "SlateBlue4", 71, 60, 139 },
+{ "RoyalBlue1", 72, 118, 255 },
+{ "RoyalBlue2", 67, 110, 238 },
+{ "RoyalBlue3", 58, 95, 205 },
+{ "RoyalBlue4", 39, 64, 139 },
+{ "blue1", 0, 0, 255 },
+{ "blue2", 0, 0, 238 },
+{ "blue3", 0, 0, 205 },
+{ "blue4", 0, 0, 139 },
+{ "DodgerBlue1", 30, 144, 255 },
+{ "DodgerBlue2", 28, 134, 238 },
+{ "DodgerBlue3", 24, 116, 205 },
+{ "DodgerBlue4", 16, 78, 139 },
+{ "SteelBlue1", 99, 184, 255 },
+{ "SteelBlue2", 92, 172, 238 },
+{ "SteelBlue3", 79, 148, 205 },
+{ "SteelBlue4", 54, 100, 139 },
+{ "DeepSkyBlue1", 0, 191, 255 },
+{ "DeepSkyBlue2", 0, 178, 238 },
+{ "DeepSkyBlue3", 0, 154, 205 },
+{ "DeepSkyBlue4", 0, 104, 139 },
+{ "SkyBlue1", 135, 206, 255 },
+{ "SkyBlue2", 126, 192, 238 },
+{ "SkyBlue3", 108, 166, 205 },
+{ "SkyBlue4", 74, 112, 139 },
+{ "LightSkyBlue1", 176, 226, 255 },
+{ "LightSkyBlue2", 164, 211, 238 },
+{ "LightSkyBlue3", 141, 182, 205 },
+{ "LightSkyBlue4", 96, 123, 139 },
+{ "SlateGray1", 198, 226, 255 },
+{ "SlateGray2", 185, 211, 238 },
+{ "SlateGray3", 159, 182, 205 },
+{ "SlateGray4", 108, 123, 139 },
+{ "LightSteelBlue1", 202, 225, 255 },
+{ "LightSteelBlue2", 188, 210, 238 },
+{ "LightSteelBlue3", 162, 181, 205 },
+{ "LightSteelBlue4", 110, 123, 139 },
+{ "LightBlue1", 191, 239, 255 },
+{ "LightBlue2", 178, 223, 238 },
+{ "LightBlue3", 154, 192, 205 },
+{ "LightBlue4", 104, 131, 139 },
+{ "LightCyan1", 224, 255, 255 },
+{ "LightCyan2", 209, 238, 238 },
+{ "LightCyan3", 180, 205, 205 },
+{ "LightCyan4", 122, 139, 139 },
+{ "PaleTurquoise1", 187, 255, 255 },
+{ "PaleTurquoise2", 174, 238, 238 },
+{ "PaleTurquoise3", 150, 205, 205 },
+{ "PaleTurquoise4", 102, 139, 139 },
+{ "CadetBlue1", 152, 245, 255 },
+{ "CadetBlue2", 142, 229, 238 },
+{ "CadetBlue3", 122, 197, 205 },
+{ "CadetBlue4", 83, 134, 139 },
+{ "turquoise1", 0, 245, 255 },
+{ "turquoise2", 0, 229, 238 },
+{ "turquoise3", 0, 197, 205 },
+{ "turquoise4", 0, 134, 139 },
+{ "cyan1", 0, 255, 255 },
+{ "cyan2", 0, 238, 238 },
+{ "cyan3", 0, 205, 205 },
+{ "cyan4", 0, 139, 139 },
+{ "DarkSlateGray1", 151, 255, 255 },
+{ "DarkSlateGray2", 141, 238, 238 },
+{ "DarkSlateGray3", 121, 205, 205 },
+{ "DarkSlateGray4", 82, 139, 139 },
+{ "aquamarine1", 127, 255, 212 },
+{ "aquamarine2", 118, 238, 198 },
+{ "aquamarine3", 102, 205, 170 },
+{ "aquamarine4", 69, 139, 116 },
+{ "DarkSeaGreen1", 193, 255, 193 },
+{ "DarkSeaGreen2", 180, 238, 180 },
+{ "DarkSeaGreen3", 155, 205, 155 },
+{ "DarkSeaGreen4", 105, 139, 105 },
+{ "SeaGreen1", 84, 255, 159 },
+{ "SeaGreen2", 78, 238, 148 },
+{ "SeaGreen3", 67, 205, 128 },
+{ "SeaGreen4", 46, 139, 87 },
+{ "PaleGreen1", 154, 255, 154 },
+{ "PaleGreen2", 144, 238, 144 },
+{ "PaleGreen3", 124, 205, 124 },
+{ "PaleGreen4", 84, 139, 84 },
+{ "SpringGreen1", 0, 255, 127 },
+{ "SpringGreen2", 0, 238, 118 },
+{ "SpringGreen3", 0, 205, 102 },
+{ "SpringGreen4", 0, 139, 69 },
+{ "green1", 0, 255, 0 },
+{ "green2", 0, 238, 0 },
+{ "green3", 0, 205, 0 },
+{ "green4", 0, 139, 0 },
+{ "chartreuse1", 127, 255, 0 },
+{ "chartreuse2", 118, 238, 0 },
+{ "chartreuse3", 102, 205, 0 },
+{ "chartreuse4", 69, 139, 0 },
+{ "OliveDrab1", 192, 255, 62 },
+{ "OliveDrab2", 179, 238, 58 },
+{ "OliveDrab3", 154, 205, 50 },
+{ "OliveDrab4", 105, 139, 34 },
+{ "DarkOliveGreen1", 202, 255, 112 },
+{ "DarkOliveGreen2", 188, 238, 104 },
+{ "DarkOliveGreen3", 162, 205, 90 },
+{ "DarkOliveGreen4", 110, 139, 61 },
+{ "khaki1", 255, 246, 143 },
+{ "khaki2", 238, 230, 133 },
+{ "khaki3", 205, 198, 115 },
+{ "khaki4", 139, 134, 78 },
+{ "LightGoldenrod1", 255, 236, 139 },
+{ "LightGoldenrod2", 238, 220, 130 },
+{ "LightGoldenrod3", 205, 190, 112 },
+{ "LightGoldenrod4", 139, 129, 76 },
+{ "LightYellow1", 255, 255, 224 },
+{ "LightYellow2", 238, 238, 209 },
+{ "LightYellow3", 205, 205, 180 },
+{ "LightYellow4", 139, 139, 122 },
+{ "yellow1", 255, 255, 0 },
+{ "yellow2", 238, 238, 0 },
+{ "yellow3", 205, 205, 0 },
+{ "yellow4", 139, 139, 0 },
+{ "gold1", 255, 215, 0 },
+{ "gold2", 238, 201, 0 },
+{ "gold3", 205, 173, 0 },
+{ "gold4", 139, 117, 0 },
+{ "goldenrod1", 255, 193, 37 },
+{ "goldenrod2", 238, 180, 34 },
+{ "goldenrod3", 205, 155, 29 },
+{ "goldenrod4", 139, 105, 20 },
+{ "DarkGoldenrod1", 255, 185, 15 },
+{ "DarkGoldenrod2", 238, 173, 14 },
+{ "DarkGoldenrod3", 205, 149, 12 },
+{ "DarkGoldenrod4", 139, 101, 8 },
+{ "RosyBrown1", 255, 193, 193 },
+{ "RosyBrown2", 238, 180, 180 },
+{ "RosyBrown3", 205, 155, 155 },
+{ "RosyBrown4", 139, 105, 105 },
+{ "IndianRed1", 255, 106, 106 },
+{ "IndianRed2", 238, 99, 99 },
+{ "IndianRed3", 205, 85, 85 },
+{ "IndianRed4", 139, 58, 58 },
+{ "sienna1", 255, 130, 71 },
+{ "sienna2", 238, 121, 66 },
+{ "sienna3", 205, 104, 57 },
+{ "sienna4", 139, 71, 38 },
+{ "burlywood1", 255, 211, 155 },
+{ "burlywood2", 238, 197, 145 },
+{ "burlywood3", 205, 170, 125 },
+{ "burlywood4", 139, 115, 85 },
+{ "wheat1", 255, 231, 186 },
+{ "wheat2", 238, 216, 174 },
+{ "wheat3", 205, 186, 150 },
+{ "wheat4", 139, 126, 102 },
+{ "tan1", 255, 165, 79 },
+{ "tan2", 238, 154, 73 },
+{ "tan3", 205, 133, 63 },
+{ "tan4", 139 , 90, 43 },
+{ "chocolate1", 255, 127, 36 },
+{ "chocolate2", 238, 118, 33 },
+{ "chocolate3", 205, 102, 29 },
+{ "chocolate4", 139, 69, 19 },
+{ "firebrick1", 255, 48, 48 },
+{ "firebrick2", 238, 44, 44 },
+{ "firebrick3", 205, 38, 38 },
+{ "firebrick4", 139, 26, 26 },
+{ "brown1", 255, 64, 64 },
+{ "brown2", 238, 59, 59 },
+{ "brown3", 205, 51, 51 },
+{ "brown4", 139, 35, 35 },
+{ "salmon1", 255, 140, 105 },
+{ "salmon2", 238, 130, 98 },
+{ "salmon3", 205, 112, 84 },
+{ "salmon4", 139, 76, 57 },
+{ "LightSalmon1", 255, 160, 122 },
+{ "LightSalmon2", 238, 149, 114 },
+{ "LightSalmon3", 205, 129, 98 },
+{ "LightSalmon4", 139, 87, 66 },
+{ "orange1", 255, 165, 0 },
+{ "orange2", 238, 154, 0 },
+{ "orange3", 205, 133, 0 },
+{ "orange4", 139 , 90, 0 },
+{ "DarkOrange1", 255, 127, 0 },
+{ "DarkOrange2", 238, 118, 0 },
+{ "DarkOrange3", 205, 102, 0 },
+{ "DarkOrange4", 139 , 69, 0 },
+{ "coral1", 255, 114, 86 },
+{ "coral2", 238, 106, 80 },
+{ "coral3", 205, 91, 69 },
+{ "coral4", 139, 62, 47 },
+{ "tomato1", 255, 99, 71 },
+{ "tomato2", 238, 92, 66 },
+{ "tomato3", 205, 79, 57 },
+{ "tomato4", 139, 54, 38 },
+{ "OrangeRed1", 255, 69, 0 },
+{ "OrangeRed2", 238, 64, 0 },
+{ "OrangeRed3", 205, 55, 0 },
+{ "OrangeRed4", 139, 37, 0 },
+{ "red1", 255, 0, 0 },
+{ "red2", 238, 0, 0 },
+{ "red3", 205, 0, 0 },
+{ "red4", 139, 0, 0 },
+{ "DeepPink1", 255, 20, 147 },
+{ "DeepPink2", 238, 18, 137 },
+{ "DeepPink3", 205, 16, 118 },
+{ "DeepPink4", 139, 10, 80 },
+{ "HotPink1", 255, 110, 180 },
+{ "HotPink2", 238, 106, 167 },
+{ "HotPink3", 205, 96, 144 },
+{ "HotPink4", 139, 58, 98 },
+{ "pink1", 255, 181, 197 },
+{ "pink2", 238, 169, 184 },
+{ "pink3", 205, 145, 158 },
+{ "pink4", 139, 99, 108 },
+{ "LightPink1", 255, 174, 185 },
+{ "LightPink2", 238, 162, 173 },
+{ "LightPink3", 205, 140, 149 },
+{ "LightPink4", 139, 95, 101 },
+{ "PaleVioletRed1", 255, 130, 171 },
+{ "PaleVioletRed2", 238, 121, 159 },
+{ "PaleVioletRed3", 205, 104, 137 },
+{ "PaleVioletRed4", 139, 71, 93 },
+{ "maroon1", 255, 52, 179 },
+{ "maroon2", 238, 48, 167 },
+{ "maroon3", 205, 41, 144 },
+{ "maroon4", 139, 28, 98 },
+{ "VioletRed1", 255, 62, 150 },
+{ "VioletRed2", 238, 58, 140 },
+{ "VioletRed3", 205, 50, 120 },
+{ "VioletRed4", 139, 34, 82 },
+{ "magenta1", 255, 0, 255 },
+{ "magenta2", 238, 0, 238 },
+{ "magenta3", 205, 0, 205 },
+{ "magenta4", 139, 0, 139 },
+{ "orchid1", 255, 131, 250 },
+{ "orchid2", 238, 122, 233 },
+{ "orchid3", 205, 105, 201 },
+{ "orchid4", 139, 71, 137 },
+{ "plum1", 255, 187, 255 },
+{ "plum2", 238, 174, 238 },
+{ "plum3", 205, 150, 205 },
+{ "plum4", 139, 102, 139 },
+{ "MediumOrchid1", 224, 102, 255 },
+{ "MediumOrchid2", 209, 95, 238 },
+{ "MediumOrchid3", 180, 82, 205 },
+{ "MediumOrchid4", 122, 55, 139 },
+{ "DarkOrchid1", 191, 62, 255 },
+{ "DarkOrchid2", 178, 58, 238 },
+{ "DarkOrchid3", 154, 50, 205 },
+{ "DarkOrchid4", 104, 34, 139 },
+{ "purple1", 155, 48, 255 },
+{ "purple2", 145, 44, 238 },
+{ "purple3", 125, 38, 205 },
+{ "purple4", 85, 26, 139 },
+{ "MediumPurple1", 171, 130, 255 },
+{ "MediumPurple2", 159, 121, 238 },
+{ "MediumPurple3", 137, 104, 205 },
+{ "MediumPurple4", 93, 71, 139 },
+{ "thistle1", 255, 225, 255 },
+{ "thistle2", 238, 210, 238 },
+{ "thistle3", 205, 181, 205 },
+{ "thistle4", 139, 123, 139 },
+{ "gray0", 0, 0, 0 },
+{ "grey0", 0, 0, 0 },
+{ "gray1", 3, 3, 3 },
+{ "grey1", 3, 3, 3 },
+{ "gray2", 5, 5, 5 },
+{ "grey2", 5, 5, 5 },
+{ "gray3", 8, 8, 8 },
+{ "grey3", 8, 8, 8 },
+{ "gray4", 10, 10, 10 },
+{ "grey4", 10, 10, 10 },
+{ "gray5", 13, 13, 13 },
+{ "grey5", 13, 13, 13 },
+{ "gray6", 15, 15, 15 },
+{ "grey6", 15, 15, 15 },
+{ "gray7", 18, 18, 18 },
+{ "grey7", 18, 18, 18 },
+{ "gray8", 20, 20, 20 },
+{ "grey8", 20, 20, 20 },
+{ "gray9", 23, 23, 23 },
+{ "grey9", 23, 23, 23 },
+{ "gray10", 26, 26, 26 },
+{ "grey10", 26, 26, 26 },
+{ "gray11", 28, 28, 28 },
+{ "grey11", 28, 28, 28 },
+{ "gray12", 31, 31, 31 },
+{ "grey12", 31, 31, 31 },
+{ "gray13", 33, 33, 33 },
+{ "grey13", 33, 33, 33 },
+{ "gray14", 36, 36, 36 },
+{ "grey14", 36, 36, 36 },
+{ "gray15", 38, 38, 38 },
+{ "grey15", 38, 38, 38 },
+{ "gray16", 41, 41, 41 },
+{ "grey16", 41, 41, 41 },
+{ "gray17", 43, 43, 43 },
+{ "grey17", 43, 43, 43 },
+{ "gray18", 46, 46, 46 },
+{ "grey18", 46, 46, 46 },
+{ "gray19", 48, 48, 48 },
+{ "grey19", 48, 48, 48 },
+{ "gray20", 51, 51, 51 },
+{ "grey20", 51, 51, 51 },
+{ "gray21", 54, 54, 54 },
+{ "grey21", 54, 54, 54 },
+{ "gray22", 56, 56, 56 },
+{ "grey22", 56, 56, 56 },
+{ "gray23", 59, 59, 59 },
+{ "grey23", 59, 59, 59 },
+{ "gray24", 61, 61, 61 },
+{ "grey24", 61, 61, 61 },
+{ "gray25", 64, 64, 64 },
+{ "grey25", 64, 64, 64 },
+{ "gray26", 66, 66, 66 },
+{ "grey26", 66, 66, 66 },
+{ "gray27", 69, 69, 69 },
+{ "grey27", 69, 69, 69 },
+{ "gray28", 71, 71, 71 },
+{ "grey28", 71, 71, 71 },
+{ "gray29", 74, 74, 74 },
+{ "grey29", 74, 74, 74 },
+{ "gray30", 77, 77, 77 },
+{ "grey30", 77, 77, 77 },
+{ "gray31", 79, 79, 79 },
+{ "grey31", 79, 79, 79 },
+{ "gray32", 82, 82, 82 },
+{ "grey32", 82, 82, 82 },
+{ "gray33", 84, 84, 84 },
+{ "grey33", 84, 84, 84 },
+{ "gray34", 87, 87, 87 },
+{ "grey34", 87, 87, 87 },
+{ "gray35", 89, 89, 89 },
+{ "grey35", 89, 89, 89 },
+{ "gray36", 92, 92, 92 },
+{ "grey36", 92, 92, 92 },
+{ "gray37", 94, 94, 94 },
+{ "grey37", 94, 94, 94 },
+{ "gray38", 97, 97, 97 },
+{ "grey38", 97, 97, 97 },
+{ "gray39", 99, 99, 99 },
+{ "grey39", 99, 99, 99 },
+{ "gray40", 102, 102, 102 },
+{ "grey40", 102, 102, 102 },
+{ "gray41", 105, 105, 105 },
+{ "grey41", 105, 105, 105 },
+{ "gray42", 107, 107, 107 },
+{ "grey42", 107, 107, 107 },
+{ "gray43", 110, 110, 110 },
+{ "grey43", 110, 110, 110 },
+{ "gray44", 112, 112, 112 },
+{ "grey44", 112, 112, 112 },
+{ "gray45", 115, 115, 115 },
+{ "grey45", 115, 115, 115 },
+{ "gray46", 117, 117, 117 },
+{ "grey46", 117, 117, 117 },
+{ "gray47", 120, 120, 120 },
+{ "grey47", 120, 120, 120 },
+{ "gray48", 122, 122, 122 },
+{ "grey48", 122, 122, 122 },
+{ "gray49", 125, 125, 125 },
+{ "grey49", 125, 125, 125 },
+{ "gray50", 127, 127, 127 },
+{ "grey50", 127, 127, 127 },
+{ "gray51", 130, 130, 130 },
+{ "grey51", 130, 130, 130 },
+{ "gray52", 133, 133, 133 },
+{ "grey52", 133, 133, 133 },
+{ "gray53", 135, 135, 135 },
+{ "grey53", 135, 135, 135 },
+{ "gray54", 138, 138, 138 },
+{ "grey54", 138, 138, 138 },
+{ "gray55", 140, 140, 140 },
+{ "grey55", 140, 140, 140 },
+{ "gray56", 143, 143, 143 },
+{ "grey56", 143, 143, 143 },
+{ "gray57", 145, 145, 145 },
+{ "grey57", 145, 145, 145 },
+{ "gray58", 148, 148, 148 },
+{ "grey58", 148, 148, 148 },
+{ "gray59", 150, 150, 150 },
+{ "grey59", 150, 150, 150 },
+{ "gray60", 153, 153, 153 },
+{ "grey60", 153, 153, 153 },
+{ "gray61", 156, 156, 156 },
+{ "grey61", 156, 156, 156 },
+{ "gray62", 158, 158, 158 },
+{ "grey62", 158, 158, 158 },
+{ "gray63", 161, 161, 161 },
+{ "grey63", 161, 161, 161 },
+{ "gray64", 163, 163, 163 },
+{ "grey64", 163, 163, 163 },
+{ "gray65", 166, 166, 166 },
+{ "grey65", 166, 166, 166 },
+{ "gray66", 168, 168, 168 },
+{ "grey66", 168, 168, 168 },
+{ "gray67", 171, 171, 171 },
+{ "grey67", 171, 171, 171 },
+{ "gray68", 173, 173, 173 },
+{ "grey68", 173, 173, 173 },
+{ "gray69", 176, 176, 176 },
+{ "grey69", 176, 176, 176 },
+{ "gray70", 179, 179, 179 },
+{ "grey70", 179, 179, 179 },
+{ "gray71", 181, 181, 181 },
+{ "grey71", 181, 181, 181 },
+{ "gray72", 184, 184, 184 },
+{ "grey72", 184, 184, 184 },
+{ "gray73", 186, 186, 186 },
+{ "grey73", 186, 186, 186 },
+{ "gray74", 189, 189, 189 },
+{ "grey74", 189, 189, 189 },
+{ "gray75", 191, 191, 191 },
+{ "grey75", 191, 191, 191 },
+{ "gray76", 194, 194, 194 },
+{ "grey76", 194, 194, 194 },
+{ "gray77", 196, 196, 196 },
+{ "grey77", 196, 196, 196 },
+{ "gray78", 199, 199, 199 },
+{ "grey78", 199, 199, 199 },
+{ "gray79", 201, 201, 201 },
+{ "grey79", 201, 201, 201 },
+{ "gray80", 204, 204, 204 },
+{ "grey80", 204, 204, 204 },
+{ "gray81", 207, 207, 207 },
+{ "grey81", 207, 207, 207 },
+{ "gray82", 209, 209, 209 },
+{ "grey82", 209, 209, 209 },
+{ "gray83", 212, 212, 212 },
+{ "grey83", 212, 212, 212 },
+{ "gray84", 214, 214, 214 },
+{ "grey84", 214, 214, 214 },
+{ "gray85", 217, 217, 217 },
+{ "grey85", 217, 217, 217 },
+{ "gray86", 219, 219, 219 },
+{ "grey86", 219, 219, 219 },
+{ "gray87", 222, 222, 222 },
+{ "grey87", 222, 222, 222 },
+{ "gray88", 224, 224, 224 },
+{ "grey88", 224, 224, 224 },
+{ "gray89", 227, 227, 227 },
+{ "grey89", 227, 227, 227 },
+{ "gray90", 229, 229, 229 },
+{ "grey90", 229, 229, 229 },
+{ "gray91", 232, 232, 232 },
+{ "grey91", 232, 232, 232 },
+{ "gray92", 235, 235, 235 },
+{ "grey92", 235, 235, 235 },
+{ "gray93", 237, 237, 237 },
+{ "grey93", 237, 237, 237 },
+{ "gray94", 240, 240, 240 },
+{ "grey94", 240, 240, 240 },
+{ "gray95", 242, 242, 242 },
+{ "grey95", 242, 242, 242 },
+{ "gray96", 245, 245, 245 },
+{ "grey96", 245, 245, 245 },
+{ "gray97", 247, 247, 247 },
+{ "grey97", 247, 247, 247 },
+{ "gray98", 250, 250, 250 },
+{ "grey98", 250, 250, 250 },
+{ "gray99", 252, 252, 252 },
+{ "grey99", 252, 252, 252 },
+{ "gray100", 255, 255, 255 },
+{ "grey100", 255, 255, 255 },
+{ "DarkGrey", 169, 169, 169 },
+{ "DarkGray", 169, 169, 169 },
+{ "DarkBlue", 0, 0, 139 },
+{ "DarkCyan", 0, 139, 139 },
+{ "DarkMagenta", 139, 0, 139 },
+{ "DarkRed", 139, 0, 0 },
+{ "LightGreen", 144, 238, 144 },
+{ NULL, 0 , 0, 0}
+};
diff --git a/svtools/source/filter.vcl/ixpm/xpmread.cxx b/svtools/source/filter.vcl/ixpm/xpmread.cxx
new file mode 100644
index 000000000000..7575c94e3ed9
--- /dev/null
+++ b/svtools/source/filter.vcl/ixpm/xpmread.cxx
@@ -0,0 +1,702 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifndef _BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+#ifndef _GRAPH_HXX
+#include <vcl/graph.hxx>
+#endif
+#include "rgbtable.hxx"
+#define _XPMPRIVATE
+#include "xpmread.hxx"
+
+// -------------
+// - XPMReader -
+// -------------
+
+XPMReader::XPMReader( SvStream& rStm ) :
+ mrIStm ( rStm ),
+ mpAcc ( NULL ),
+ mpMaskAcc ( NULL ),
+ mnLastPos ( rStm.Tell() ),
+ mnWidth ( 0 ),
+ mnHeight ( 0 ),
+ mnColors ( 0 ),
+ mnCpp ( 0 ),
+ mbTransparent ( FALSE ),
+ mbStatus ( TRUE ),
+ mnStatus ( 0 ),
+ mnIdentifier ( XPMIDENTIFIER ),
+ mcThisByte ( 0 ),
+ mnTempAvail ( 0 ),
+ mpFastColorTable( NULL ),
+ mpColMap ( NULL )
+{
+
+}
+
+// ------------------------------------------------------------------------
+
+XPMReader::~XPMReader()
+{
+ if( mpAcc )
+ maBmp.ReleaseAccess( mpAcc );
+}
+
+// ------------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("",off)
+#endif
+
+ReadState XPMReader::ReadXPM( Graphic& rGraphic )
+{
+ ReadState eReadState;
+ BYTE cDummy;
+
+ // sehen, ob wir _alles_ lesen koennen
+ mrIStm.Seek( STREAM_SEEK_TO_END );
+ mrIStm >> cDummy;
+
+ // falls wir nicht alles lesen koennen
+ // kehren wir zurueck und warten auf neue Daten
+ if ( mrIStm.GetError() != ERRCODE_IO_PENDING )
+ {
+ mrIStm.Seek( mnLastPos );
+ mbStatus = TRUE;
+
+ if ( mbStatus )
+ {
+ mpStringBuf = new BYTE [ XPMSTRINGBUF ];
+ mpTempBuf = new BYTE [ XPMTEMPBUFSIZE ];
+
+ if ( ( mbStatus = ImplGetString() ) == TRUE )
+ {
+ mnIdentifier = XPMVALUES; // Bitmap informationen einholen
+ mnWidth = ImplGetULONG( 0 );
+ mnHeight = ImplGetULONG( 1 );
+ mnColors = ImplGetULONG( 2 );
+ mnCpp = ImplGetULONG( 3 );
+ }
+ if ( mnColors > ( SAL_MAX_UINT32 / ( 4 + mnCpp ) ) )
+ mbStatus = sal_False;
+ if ( ( mnWidth * mnCpp ) >= XPMSTRINGBUF )
+ mbStatus = sal_False;
+ if ( mbStatus && mnWidth && mnHeight && mnColors && mnCpp )
+ {
+ mnIdentifier = XPMCOLORS;
+
+ // mpColMap beinhaltet fuer jede vorhandene
+ // Farbe: ( mnCpp )Byte(s)-> ASCII Eintrag der der Farbe zugeordnet ist
+ // 1 Byte -> 0xff wenn Farbe transparent ist
+ // 3 Bytes -> RGB Wert der Farbe
+ mpColMap = new BYTE[ mnColors * ( 4 + mnCpp ) ];
+ if ( mpColMap )
+ {
+ for ( ULONG i = 0; i < mnColors; i++ )
+ {
+ if ( ImplGetColor( i ) == FALSE )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ }
+ }
+ else
+ mbStatus = sal_False;
+
+ if ( mbStatus )
+ {
+ // bei mehr als 256 Farben wird eine 24 Bit Grafik erstellt
+ sal_uInt16 nBits = 1;
+ if ( mnColors > 256 )
+ nBits = 24;
+ else if ( mnColors > 16 )
+ nBits = 8;
+ else if ( mnColors > 2 )
+ nBits = 4;
+ else
+ nBits = 1;
+
+ maBmp = Bitmap( Size( mnWidth, mnHeight ), nBits );
+ mpAcc = maBmp.AcquireWriteAccess();
+
+ // mbTransparent ist TRUE wenn mindestens eine Farbe Transparent ist
+ if ( mbTransparent )
+ {
+ maMaskBmp = Bitmap( Size( mnWidth, mnHeight ), 1 );
+ if ( ( mpMaskAcc = maMaskBmp.AcquireWriteAccess() ) == NULL )
+ mbStatus = FALSE;
+ }
+ if( mpAcc && mbStatus )
+ {
+ ULONG i;
+ if ( mnColors <=256 ) // palette is only needed by using less than 257
+ { // colors
+
+ BYTE* pPtr = &mpColMap[mnCpp];
+
+ for ( i = 0; i < mnColors; i++ )
+ {
+ mpAcc->SetPaletteColor( (BYTE)i, Color( pPtr[1], pPtr[2], pPtr[3] ) );
+ pPtr += ( mnCpp + 4 );
+ }
+ // using 2 charakters per pixel and less than 257 Colors we speed up
+ if ( mnCpp == 2 ) // by using a 64kb indexing table
+ {
+ mpFastColorTable = new BYTE[ 256 * 256 ];
+ for ( pPtr = mpColMap, i = 0; i < mnColors; i++, pPtr += mnCpp + 4 )
+ {
+ ULONG j = pPtr[ 0 ] << 8;
+ j += pPtr[ 1 ];
+ mpFastColorTable[ j ] = (BYTE)i;
+ }
+ }
+ }
+ // now we get the bitmap data
+ mnIdentifier = XPMPIXELS;
+ for ( i = 0; i < mnHeight; i++ )
+ {
+ if ( ImplGetScanLine( i ) == FALSE )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ }
+ mnIdentifier = XPMEXTENSIONS;
+ }
+ }
+ }
+
+ delete[] mpFastColorTable;
+ delete[] mpColMap;
+ delete[] mpStringBuf;
+ delete[] mpTempBuf;
+
+ }
+ if( mbStatus )
+ {
+ if ( mpMaskAcc )
+ {
+ maMaskBmp.ReleaseAccess ( mpMaskAcc), mpMaskAcc = NULL;
+ maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
+ rGraphic = Graphic( BitmapEx( maBmp, maMaskBmp ) );
+ }
+ else
+ {
+ maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
+ rGraphic = maBmp;
+ }
+ eReadState = XPMREAD_OK;
+ }
+ else
+ {
+ if ( mpMaskAcc ) maMaskBmp.ReleaseAccess ( mpMaskAcc), mpMaskAcc = NULL;
+ if ( mpAcc ) maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
+ eReadState = XPMREAD_ERROR;
+ }
+ }
+ else
+ {
+ mrIStm.ResetError();
+ eReadState = XPMREAD_NEED_MORE;
+ }
+ return eReadState;
+}
+
+#ifdef _MSC_VER
+#pragma optimize ("",on)
+#endif
+
+// ------------------------------------------------------------------------
+// ImplGetColor ermittelt saemtliche Farbwerte,
+// die Rueckgabe ist TRUE wenn saemtliche Farben zugeordnet werden konnten
+
+BOOL XPMReader::ImplGetColor( ULONG nNumb )
+{
+ BYTE* pString = mpStringBuf;
+ BYTE* pPtr = ( mpColMap + nNumb * ( 4 + mnCpp ) );
+ BOOL bStatus = ImplGetString();
+
+ if ( bStatus )
+ {
+ for ( ULONG i = 0; i < mnCpp; i++ )
+ *pPtr++ = *pString++;
+ bStatus = ImplGetColSub ( pPtr );
+ }
+ return bStatus;
+}
+
+// ------------------------------------------------------------------------
+// ImpGetScanLine liest den String mpBufSize aus und schreibt die Pixel in die
+// Bitmap. Der Parameter nY gibt die horizontale Position an.
+
+BOOL XPMReader::ImplGetScanLine( ULONG nY )
+{
+ BOOL bStatus = ImplGetString();
+ BYTE* pString = mpStringBuf;
+ BYTE* pColor;
+ BitmapColor aWhite;
+ BitmapColor aBlack;
+
+ if ( bStatus )
+ {
+ if ( mpMaskAcc )
+ {
+ aWhite = mpMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) );
+ aBlack = mpMaskAcc->GetBestMatchingColor( Color( COL_BLACK ) );
+ }
+ if ( mnStringSize != ( mnWidth * mnCpp ))
+ bStatus = FALSE;
+ else
+ {
+ ULONG i, j;
+ if ( mpFastColorTable )
+ {
+ for ( i = 0; i < mnWidth; i++ )
+ {
+ j = (*pString++) << 8;
+ j += *pString++;
+ BYTE k = (BYTE)mpFastColorTable[ j ];
+ mpAcc->SetPixel( nY, i, BitmapColor( (BYTE)k ) );
+
+ if ( mpMaskAcc )
+ mpMaskAcc->SetPixel( nY, i,
+ ( mpColMap[ k * (mnCpp + 4) + mnCpp] ) ? aWhite : aBlack );
+ }
+ }
+ else for ( i = 0; i < mnWidth; i++ )
+ {
+ pColor = mpColMap;
+ for ( j = 0; j < mnColors; j++ )
+ {
+ if ( ImplCompare( pString, pColor, mnCpp, XPMCASESENSITIVE ) == TRUE )
+ {
+ if ( mnColors > 256 )
+ mpAcc->SetPixel( nY, i, Color ( pColor[3], pColor[4], pColor[5] ) );
+ else
+ mpAcc->SetPixel( nY, i, BitmapColor( (BYTE) j ) );
+
+ if ( mpMaskAcc )
+ mpMaskAcc->SetPixel( nY, i, (
+ pColor[ mnCpp ] ) ? aWhite : aBlack );
+
+ break;
+ }
+ pColor += ( mnCpp + 4 );
+ }
+ pString += mnCpp;
+ }
+
+ }
+ }
+ return bStatus;
+}
+
+// ------------------------------------------------------------------------
+// versucht aus mpStringBuf einen Farbwert zu uebermitteln
+// wurde eine Farbe gefunden wird an pDest[1]..pDest[2] der RGB wert geschrieben
+// pDest[0] enthaelt 0xff wenn die Farbe transparent ist sonst 0
+
+BOOL XPMReader::ImplGetColSub( BYTE* pDest )
+{
+ unsigned char cTransparent[] = "None";
+
+ BOOL bColStatus = FALSE;
+
+ if ( ImplGetColKey( 'c' ) || ImplGetColKey( 'm' ) || ImplGetColKey( 'g' ) )
+ {
+ // hexentry for RGB or HSV color ?
+ if ( *mpPara == '#' )
+ {
+ *pDest++ = 0;
+ bColStatus = TRUE;
+ switch ( mnParaSize )
+ {
+ case 25 :
+ ImplGetRGBHex ( pDest, 6 );
+ break;
+ case 13 :
+ ImplGetRGBHex ( pDest, 2 );
+ break;
+ case 7 :
+ ImplGetRGBHex ( pDest, 0 );
+ break;
+ default:
+ bColStatus = FALSE;
+ break;
+ }
+ }
+ // maybe pixel is transparent
+ else if ( ImplCompare( &cTransparent[0], mpPara, 4 ))
+ {
+ *pDest++ = 0xff;
+ bColStatus = TRUE;
+ mbTransparent = TRUE;
+ }
+ // last we will try to get the colorname
+ else if ( mnParaSize > 2 ) // name must enlarge the minimum size
+ {
+ ULONG i = 0;
+ while ( TRUE )
+ {
+ if ( pRGBTable[ i ].name == NULL )
+ break;
+ if ( pRGBTable[ i ].name[ mnParaSize ] == 0 )
+ {
+ if ( ImplCompare ( (unsigned char*)pRGBTable[ i ].name,
+ mpPara, mnParaSize, XPMCASENONSENSITIVE ) )
+ {
+ bColStatus = TRUE;
+ *pDest++ = 0;
+ *pDest++ = pRGBTable[ i ].red;
+ *pDest++ = pRGBTable[ i ].green;
+ *pDest++ = pRGBTable[ i ].blue;
+ }
+ }
+ i++;
+ }
+ }
+ }
+ return bColStatus;
+}
+
+// ------------------------------------------------------------------------
+// ImplGetColKey durchsuch den String mpStringBuf nach einem Parameter 'nKey'
+// und gibt einen BOOL zurueck. ( wenn TRUE werden mpPara und mnParaSize gesetzt )
+
+BOOL XPMReader::ImplGetColKey( BYTE nKey )
+{
+ BYTE nTemp, nPrev = ' ';
+
+ mpPara = mpStringBuf + mnCpp + 1;
+ mnParaSize = 0;
+
+ while ( *mpPara != 0 )
+ {
+ if ( *mpPara == nKey )
+ {
+ nTemp = *( mpPara + 1 );
+ if ( nTemp == ' ' || nTemp == 0x09 )
+ {
+ if ( nPrev == ' ' || nPrev == 0x09 )
+ break;
+ }
+ }
+ nPrev = *mpPara;
+ mpPara++;
+ }
+ if ( *mpPara )
+ {
+ mpPara++;
+ while ( (*mpPara == ' ') || (*mpPara == 0x09) )
+ {
+ mpPara++;
+ }
+ if ( *mpPara != 0 )
+ {
+ while ( *(mpPara+mnParaSize) != ' ' && *(mpPara+mnParaSize) != 0x09 &&
+ *(mpPara+mnParaSize) != 0 )
+ {
+ mnParaSize++;
+ }
+ }
+ }
+ return ( mnParaSize ) ? TRUE : FALSE;
+}
+
+// ------------------------------------------------------------------------
+// ImplGetRGBHex uebersetzt den ASCII-Hexadezimalwert der sich bei mpPara befindet
+// in einen RGB wert und schreibt diesen nach pDest
+// folgende Formate muessen sich bei mpPara befinden:
+// wenn nAdd = 0 : '#12ab12' -> RGB = 0x12, 0xab, 0x12
+// 2 : '#1234abcd1234' " " " "
+// 6 : '#12345678abcdefab12345678' " " " "
+
+
+void XPMReader::ImplGetRGBHex( BYTE* pDest,ULONG nAdd )
+{
+ BYTE* pPtr = mpPara+1;
+ BYTE nHex, nTemp;
+
+ for ( ULONG i = 0; i < 3; i++ )
+ {
+ nHex = (*pPtr++) - '0';
+ if ( nHex > 9 )
+ nHex = ((nHex - 'A' + '0') & 7) + 10;
+
+ nTemp = (*pPtr++) - '0';
+ if ( nTemp > 9 )
+ nTemp = ((nTemp - 'A' + '0') & 7) + 10;
+ nHex = ( nHex << 4 ) + nTemp;
+
+ pPtr += nAdd;
+ *pDest++ = (BYTE)nHex;
+ }
+}
+
+// ------------------------------------------------------------------------
+// ImplGetUlong gibt den wert einer bis zu 6stelligen ASCII-Dezimalzahl zurueck.
+
+ULONG XPMReader::ImplGetULONG( ULONG nPara )
+{
+ if ( ImplGetPara ( nPara ) )
+ {
+ ULONG nRetValue = 0;
+ BYTE* pPtr = mpPara;
+
+ if ( ( mnParaSize > 6 ) || ( mnParaSize == 0 ) ) return 0;
+ for ( ULONG i = 0; i < mnParaSize; i++ )
+ {
+ BYTE j = (*pPtr++) - 48;
+ if ( j > 9 ) return 0; // ascii is invalid
+ nRetValue*=10;
+ nRetValue+=j;
+ }
+ return nRetValue;
+ }
+ else return 0;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL XPMReader::ImplCompare( BYTE* pSource, BYTE* pDest, ULONG nSize, ULONG nMode )
+{
+ BOOL bRet = TRUE;
+
+ if ( nMode == XPMCASENONSENSITIVE )
+ {
+ for ( ULONG i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for ( ULONG i = 0; i < nSize; i++ )
+ {
+ if ( pSource[i] != pDest[i] )
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+ }
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+// ImplGetPara versucht den nNumb ( 0...x ) Parameter aus mpStringBuf zu ermitteln.
+// Ein Parameter ist durch Spaces oder Tabs von den anderen getrennt.
+// Konnte der Parameter gefunden werden ist der Rueckgabewert TRUE und mpPara + mnParaSize
+// werden gesetzt.
+
+BOOL XPMReader::ImplGetPara ( ULONG nNumb )
+{
+ BYTE nByte;
+ ULONG pSize = 0;
+ BYTE* pPtr = mpStringBuf;
+ ULONG nCount = 0;
+
+ if ( ( *pPtr != ' ' ) && ( *pPtr != 0x09 ) )
+ {
+ mpPara = pPtr;
+ mnParaSize = 0;
+ nCount = 0;
+ }
+ else
+ {
+ mpPara = NULL;
+ nCount = 0xffffffff;
+ }
+
+ while ( pSize < mnStringSize )
+ {
+ nByte = *pPtr;
+
+ if ( mpPara )
+ {
+ if ( ( nByte == ' ' ) || ( nByte == 0x09 ) )
+ {
+ if ( nCount == nNumb )
+ break;
+ else
+ mpPara = NULL;
+ }
+ else
+ mnParaSize++;
+ }
+ else
+ {
+ if ( ( nByte != ' ' ) && ( nByte != 0x09 ) )
+ {
+ mpPara = pPtr;
+ mnParaSize = 1;
+ nCount++;
+ }
+ }
+ pSize++;
+ pPtr++;
+ }
+ return ( ( nCount == nNumb ) && ( mpPara ) ) ? TRUE : FALSE;
+}
+
+// ------------------------------------------------------------------------
+// Der naechste String wird ausgelesen und in mpStringBuf (mit 0 abgeschlossen) abgelegt;
+// mnStringSize enthaelt die Groesse des gelesenen Strings.
+// Bemerkungen wie '//' und '/*.....*/' werden uebersprungen.
+
+BOOL XPMReader::ImplGetString( void )
+{
+ BYTE sID[] = "/* XPM */";
+ BYTE* pString = mpStringBuf;
+
+ mnStringSize = 0;
+ mpStringBuf[0] = 0;
+
+ while( mbStatus && ( mnStatus != XPMFINISHED ) )
+ {
+ if ( mnTempAvail == 0 )
+ {
+ mnTempAvail = mrIStm.Read( mpTempBuf, XPMTEMPBUFSIZE );
+ if ( mnTempAvail == 0 )
+ break;
+
+ mpTempPtr = mpTempBuf;
+
+ if ( mnIdentifier == XPMIDENTIFIER )
+ {
+ if ( mnTempAvail <= 50 )
+ {
+ mbStatus = FALSE; // file is too short to be a correct XPM format
+ break;
+ }
+ for ( int i = 0; i < 9; i++ ) // searching for "/* XPM */"
+ if ( *mpTempPtr++ != sID[i] )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ mnTempAvail-=9;
+ mnIdentifier++;
+ }
+ }
+ mcLastByte = mcThisByte;
+ mcThisByte = *mpTempPtr++;
+ mnTempAvail--;
+
+ if ( mnStatus & XPMDOUBLE )
+ {
+ if ( mcThisByte == 0x0a )
+ mnStatus &=~XPMDOUBLE;
+ continue;
+ }
+ if ( mnStatus & XPMREMARK )
+ {
+ if ( ( mcThisByte == '/' ) && ( mcLastByte == '*' ) )
+ mnStatus &=~XPMREMARK;
+ continue;
+ }
+ if ( mnStatus & XPMSTRING ) // characters in string
+ {
+ if ( mcThisByte == '"' )
+ {
+ mnStatus &=~XPMSTRING; // end of parameter by eol
+ break;
+ }
+ if ( mnStringSize >= ( XPMSTRINGBUF - 1 ) )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ *pString++ = mcThisByte;
+ pString[0] = 0;
+ mnStringSize++;
+ continue;
+ }
+ else
+ { // characters beside string
+ switch ( mcThisByte )
+ {
+ case '*' :
+ if ( mcLastByte == '/' ) mnStatus |= XPMREMARK;
+ break;
+ case '/' :
+ if ( mcLastByte == '/' ) mnStatus |= XPMDOUBLE;
+ break;
+ case '"' : mnStatus |= XPMSTRING;
+ break;
+ case '{' :
+ if ( mnIdentifier == XPMDEFINITION )
+ mnIdentifier++;
+ break;
+ case '}' :
+ if ( mnIdentifier == XPMENDEXT )
+ mnStatus = XPMFINISHED;
+ break;
+ }
+ }
+ }
+ return mbStatus;
+}
+
+// -------------
+// - ImportXPM -
+// -------------
+
+BOOL ImportXPM( SvStream& rStm, Graphic& rGraphic )
+{
+ XPMReader* pXPMReader = (XPMReader*) rGraphic.GetContext();
+ ReadState eReadState;
+ BOOL bRet = TRUE;
+
+ if( !pXPMReader )
+ pXPMReader = new XPMReader( rStm );
+
+ rGraphic.SetContext( NULL );
+ eReadState = pXPMReader->ReadXPM( rGraphic );
+
+ if( eReadState == XPMREAD_ERROR )
+ {
+ bRet = FALSE;
+ delete pXPMReader;
+ }
+ else if( eReadState == XPMREAD_OK )
+ delete pXPMReader;
+ else
+ rGraphic.SetContext( pXPMReader );
+
+ return bRet;
+}
diff --git a/svtools/source/filter.vcl/jpeg/jpeg.cxx b/svtools/source/filter.vcl/jpeg/jpeg.cxx
new file mode 100644
index 000000000000..a2de92171af3
--- /dev/null
+++ b/svtools/source/filter.vcl/jpeg/jpeg.cxx
@@ -0,0 +1,779 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <tools/solar.h>
+
+extern "C"
+{
+ #define INT32 JPEG_INT32
+ #include "stdio.h"
+ #include "jpeg.h"
+ #include "jpeglib.h"
+ #include "jerror.h"
+ #undef INT32
+}
+
+#define _JPEGPRIVATE
+#include <vcl/bmpacc.hxx>
+#include "jpeg.hxx"
+#include <svtools/FilterConfigItem.hxx>
+#include <svtools/filter.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+using namespace ::com::sun::star;
+
+#define JPEGMINREAD 512
+
+// -------------
+// - (C-Calls) -
+// -------------
+
+// ------------------------------------------------------------------------
+
+extern "C" void* CreateBitmap( void* pJPEGReader, void* pJPEGCreateBitmapParam )
+{
+ return ( (JPEGReader*) pJPEGReader )->CreateBitmap( pJPEGCreateBitmapParam );
+}
+
+// ------------------------------------------------------------------------
+
+extern "C" void* GetScanline( void* pJPEGWriter, long nY )
+{
+ return ( (JPEGWriter*) pJPEGWriter )->GetScanline( nY );
+}
+
+// ------------------------------------------------------------------------
+
+struct JPEGCallbackStruct
+{
+ uno::Reference< task::XStatusIndicator > xStatusIndicator;
+};
+
+extern "C" long JPEGCallback( void* pCallbackData, long nPercent )
+{
+ JPEGCallbackStruct* pS = (JPEGCallbackStruct*)pCallbackData;
+ if ( pS && pS->xStatusIndicator.is() )
+ {
+ pS->xStatusIndicator->setValue( nPercent );
+ }
+ return 0L;
+}
+
+#define BUF_SIZE 4096
+
+typedef struct
+{
+ struct jpeg_destination_mgr pub; /* public fields */
+
+ SvStream* outfile; /* target stream */
+ JOCTET * buffer; /* start of buffer */
+} my_destination_mgr;
+
+typedef my_destination_mgr * my_dest_ptr;
+
+extern "C" void init_destination (j_compress_ptr cinfo)
+{
+ my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+ /* Allocate the output buffer --- it will be released when done with image */
+ dest->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ BUF_SIZE * sizeof(JOCTET));
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = BUF_SIZE;
+}
+
+extern "C" int empty_output_buffer (j_compress_ptr cinfo)
+{
+ my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+ if (dest->outfile->Write(dest->buffer, BUF_SIZE) !=
+ (size_t) BUF_SIZE)
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = BUF_SIZE;
+
+ return TRUE;
+}
+
+extern "C" void term_destination (j_compress_ptr cinfo)
+{
+ my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+ size_t datacount = BUF_SIZE - dest->pub.free_in_buffer;
+
+ /* Write any data remaining in the buffer */
+ if (datacount > 0) {
+ if (dest->outfile->Write(dest->buffer, datacount) != datacount)
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+ }
+}
+
+extern "C" void jpeg_svstream_dest (j_compress_ptr cinfo, void* out)
+{
+ SvStream * outfile = (SvStream*)out;
+ my_dest_ptr dest;
+
+ /* The destination object is made permanent so that multiple JPEG images
+ * can be written to the same file without re-executing jpeg_svstream_dest.
+ * This makes it dangerous to use this manager and a different destination
+ * manager serially with the same JPEG object, because their private object
+ * sizes may be different. Caveat programmer.
+ */
+ if (cinfo->dest == NULL) { /* first time for this JPEG object? */
+ cinfo->dest = (struct jpeg_destination_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof(my_destination_mgr));
+ }
+
+ dest = (my_dest_ptr) cinfo->dest;
+ dest->pub.init_destination = init_destination;
+ dest->pub.empty_output_buffer = empty_output_buffer;
+ dest->pub.term_destination = term_destination;
+ dest->outfile = outfile;
+}
+
+/* Expanded data source object for stdio input */
+
+typedef struct {
+ struct jpeg_source_mgr pub; /* public fields */
+
+ SvStream * infile; /* source stream */
+ JOCTET * buffer; /* start of buffer */
+ boolean start_of_file; /* have we gotten any data yet? */
+} my_source_mgr;
+
+typedef my_source_mgr * my_src_ptr;
+
+/*
+ * Initialize source --- called by jpeg_read_header
+ * before any data is actually read.
+ */
+
+extern "C" void init_source (j_decompress_ptr cinfo)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
+
+ /* We reset the empty-input-file flag for each image,
+ * but we don't clear the input buffer.
+ * This is correct behavior for reading a series of images from one source.
+ */
+ src->start_of_file = TRUE;
+}
+
+long StreamRead( SvStream* pSvStm, void* pBuffer, long nBufferSize )
+{
+ long nRead;
+
+ if( pSvStm->GetError() != ERRCODE_IO_PENDING )
+ {
+ long nActPos = pSvStm->Tell();
+
+ nRead = (long) pSvStm->Read( pBuffer, nBufferSize );
+
+ if( pSvStm->GetError() == ERRCODE_IO_PENDING )
+ {
+ nRead = 0;
+
+ // Damit wir wieder an die alte Position
+ // seeken koennen, setzen wir den Error temp.zurueck
+ pSvStm->ResetError();
+ pSvStm->Seek( nActPos );
+ pSvStm->SetError( ERRCODE_IO_PENDING );
+ }
+ }
+ else
+ nRead = 0;
+
+ return nRead;
+}
+
+extern "C" int fill_input_buffer (j_decompress_ptr cinfo)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
+ size_t nbytes;
+
+ nbytes = StreamRead(src->infile, src->buffer, BUF_SIZE);
+
+ if (nbytes <= 0) {
+ if (src->start_of_file) /* Treat empty input file as fatal error */
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ /* Insert a fake EOI marker */
+ src->buffer[0] = (JOCTET) 0xFF;
+ src->buffer[1] = (JOCTET) JPEG_EOI;
+ nbytes = 2;
+ }
+
+ src->pub.next_input_byte = src->buffer;
+ src->pub.bytes_in_buffer = nbytes;
+ src->start_of_file = FALSE;
+
+ return TRUE;
+}
+
+extern "C" void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
+
+ /* Just a dumb implementation for now. Could use fseek() except
+ * it doesn't work on pipes. Not clear that being smart is worth
+ * any trouble anyway --- large skips are infrequent.
+ */
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->pub.bytes_in_buffer) {
+ num_bytes -= (long) src->pub.bytes_in_buffer;
+ (void) fill_input_buffer(cinfo);
+ /* note we assume that fill_input_buffer will never return FALSE,
+ * so suspension need not be handled.
+ */
+ }
+ src->pub.next_input_byte += (size_t) num_bytes;
+ src->pub.bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+extern "C" void term_source (j_decompress_ptr)
+{
+ /* no work necessary here */
+}
+
+extern "C" void jpeg_svstream_src (j_decompress_ptr cinfo, void * in)
+{
+ my_src_ptr src;
+ SvStream * infile = (SvStream*)in;
+
+ /* The source object and input buffer are made permanent so that a series
+ * of JPEG images can be read from the same file by calling jpeg_stdio_src
+ * only before the first one. (If we discarded the buffer at the end of
+ * one image, we'd likely lose the start of the next one.)
+ * This makes it unsafe to use this manager and a different source
+ * manager serially with the same JPEG object. Caveat programmer.
+ */
+ if (cinfo->src == NULL) { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof(my_source_mgr));
+ src = (my_src_ptr) cinfo->src;
+ src->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ BUF_SIZE * sizeof(JOCTET));
+ }
+
+ src = (my_src_ptr) cinfo->src;
+ src->pub.init_source = init_source;
+ src->pub.fill_input_buffer = fill_input_buffer;
+ src->pub.skip_input_data = skip_input_data;
+ src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->pub.term_source = term_source;
+ src->infile = infile;
+ src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+ src->pub.next_input_byte = NULL; /* until buffer loaded */
+}
+
+// --------------
+// - JPEGReader -
+// --------------
+
+JPEGReader::JPEGReader( SvStream& rStm, void* /*pCallData*/, sal_Bool bSetLS ) :
+ rIStm ( rStm ),
+ pAcc ( NULL ),
+ pAcc1 ( NULL ),
+ pBuffer ( NULL ),
+ nLastPos ( rStm.Tell() ),
+ nLastLines ( 0 ),
+ bSetLogSize ( bSetLS )
+{
+ maUpperName = String::CreateFromAscii( "SVIJPEG", 7 );
+ nFormerPos = nLastPos;
+}
+
+// ------------------------------------------------------------------------
+
+JPEGReader::~JPEGReader()
+{
+ if( pBuffer )
+ rtl_freeMemory( pBuffer );
+
+ if( pAcc )
+ aBmp.ReleaseAccess( pAcc );
+
+ if( pAcc1 )
+ aBmp1.ReleaseAccess( pAcc1 );
+}
+
+// ------------------------------------------------------------------------
+
+void* JPEGReader::CreateBitmap( void* pParam )
+{
+ Size aSize( ((JPEGCreateBitmapParam*)pParam)->nWidth,
+ ((JPEGCreateBitmapParam*)pParam)->nHeight );
+ sal_Bool bGray = ((JPEGCreateBitmapParam*)pParam)->bGray != 0;
+
+ void* pBmpBuf = NULL;
+
+ if( pAcc )
+ aBmp.ReleaseAccess( pAcc );
+
+ if( bGray )
+ {
+ BitmapPalette aGrayPal( 256 );
+
+ for( USHORT n = 0; n < 256; n++ )
+ {
+ const BYTE cGray = (BYTE) n;
+ aGrayPal[ n ] = BitmapColor( cGray, cGray, cGray );
+ }
+
+ aBmp = Bitmap( aSize, 8, &aGrayPal );
+ }
+ else
+ aBmp = Bitmap( aSize, 24 );
+
+ if ( bSetLogSize )
+ {
+ unsigned long nUnit = ((JPEGCreateBitmapParam*)pParam)->density_unit;
+
+ if( ( ( 1 == nUnit ) || ( 2 == nUnit ) ) &&
+ ( (JPEGCreateBitmapParam*) pParam )->X_density &&
+ ( (JPEGCreateBitmapParam*) pParam )->Y_density )
+ {
+ Point aEmptyPoint;
+ Fraction aFractX( 1, ((JPEGCreateBitmapParam*)pParam)->X_density );
+ Fraction aFractY( 1, ((JPEGCreateBitmapParam*)pParam)->Y_density );
+ MapMode aMapMode( nUnit == 1 ? MAP_INCH : MAP_CM, aEmptyPoint, aFractX, aFractY );
+ Size aPrefSize = OutputDevice::LogicToLogic( aSize, aMapMode, MAP_100TH_MM );
+
+ aBmp.SetPrefSize( aPrefSize );
+ aBmp.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
+ }
+ }
+
+ pAcc = aBmp.AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ long nAlignedWidth;
+
+ const ULONG nFormat = pAcc->GetScanlineFormat();
+
+ if(
+ ( bGray && ( BMP_FORMAT_8BIT_PAL == nFormat ) ) ||
+ ( !bGray && ( BMP_FORMAT_24BIT_TC_RGB == nFormat ) )
+ )
+ {
+ pBmpBuf = pAcc->GetBuffer();
+ nAlignedWidth = pAcc->GetScanlineSize();
+ ((JPEGCreateBitmapParam*)pParam)->bTopDown = pAcc->IsTopDown();
+ }
+ else
+ {
+ nAlignedWidth = AlignedWidth4Bytes( aSize.Width() * ( bGray ? 8 : 24 ) );
+ ((JPEGCreateBitmapParam*)pParam)->bTopDown = TRUE;
+ pBmpBuf = pBuffer = rtl_allocateMemory( nAlignedWidth * aSize.Height() );
+ }
+ ((JPEGCreateBitmapParam*)pParam)->nAlignedWidth = nAlignedWidth;
+ }
+
+ return pBmpBuf;
+}
+
+// ------------------------------------------------------------------------
+
+void JPEGReader::FillBitmap()
+{
+ if( pBuffer && pAcc )
+ {
+ HPBYTE pTmp;
+ BitmapColor aColor;
+ long nAlignedWidth;
+ long nWidth = pAcc->Width();
+ long nHeight = pAcc->Height();
+
+ if( pAcc->GetBitCount() == 8 )
+ {
+ BitmapColor* pCols = new BitmapColor[ 256 ];
+
+ for( USHORT n = 0; n < 256; n++ )
+ {
+ const BYTE cGray = (BYTE) n;
+ pCols[ n ] = pAcc->GetBestMatchingColor( BitmapColor( cGray, cGray, cGray ) );
+ }
+
+ nAlignedWidth = AlignedWidth4Bytes( pAcc->Width() * 8L );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ pTmp = (BYTE*) pBuffer + nY * nAlignedWidth;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pAcc->SetPixel( nY, nX, pCols[ *pTmp++ ] );
+ }
+
+ delete[] pCols;
+ }
+ else
+ {
+ nAlignedWidth = AlignedWidth4Bytes( pAcc->Width() * 24L );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ pTmp = (BYTE*) pBuffer + nY * nAlignedWidth;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor.SetRed( *pTmp++ );
+ aColor.SetGreen( *pTmp++ );
+ aColor.SetBlue( *pTmp++ );
+ pAcc->SetPixel( nY, nX, aColor );
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+Graphic JPEGReader::CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines )
+{
+ Graphic aGraphic;
+ const Size aSizePix( rBitmap.GetSizePixel() );
+
+ if( !nLastLines )
+ {
+ if( pAcc1 )
+ aBmp1.ReleaseAccess( pAcc1 );
+
+ aBmp1 = Bitmap( rBitmap.GetSizePixel(), 1 );
+ aBmp1.Erase( Color( COL_WHITE ) );
+ pAcc1 = aBmp1.AcquireWriteAccess();
+ }
+
+ if( nLines && ( nLines < aSizePix.Height() ) )
+ {
+ if( pAcc1 )
+ {
+ const long nNewLines = nLines - nLastLines;
+
+ if( nNewLines )
+ {
+ pAcc1->SetFillColor( Color( COL_BLACK ) );
+ pAcc1->FillRect( Rectangle( Point( 0, nLastLines ),
+ Size( pAcc1->Width(), nNewLines ) ) );
+ }
+
+ aBmp1.ReleaseAccess( pAcc1 );
+ aGraphic = BitmapEx( rBitmap, aBmp1 );
+ pAcc1 = aBmp1.AcquireWriteAccess();
+ }
+ else
+ aGraphic = rBitmap;
+ }
+ else
+ aGraphic = rBitmap;
+
+ nLastLines = nLines;
+
+ return aGraphic;
+}
+
+// ------------------------------------------------------------------------
+
+ReadState JPEGReader::Read( Graphic& rGraphic )
+{
+ long nEndPos;
+ long nLines;
+ ReadState eReadState;
+ BOOL bRet = FALSE;
+ BYTE cDummy;
+
+#if 1 // TODO: is it possible to get rid of this seek to the end?
+ // check if the stream's end is already available
+ rIStm.Seek( STREAM_SEEK_TO_END );
+ rIStm >> cDummy;
+ nEndPos = rIStm.Tell();
+
+ // else check if at least JPEGMINREAD bytes can be read
+ if( rIStm.GetError() == ERRCODE_IO_PENDING )
+ {
+ rIStm.ResetError();
+ if( ( nEndPos - nFormerPos ) < JPEGMINREAD )
+ {
+ rIStm.Seek( nLastPos );
+ return JPEGREAD_NEED_MORE;
+ }
+ }
+
+ // seek back to the original position
+ rIStm.Seek( nLastPos );
+#endif
+
+ Size aPreviewSize = GetPreviewSize();
+ SetJpegPreviewSizeHint( aPreviewSize.Width(), aPreviewSize.Height() );
+
+ // read the (partial) image
+ ReadJPEG( this, &rIStm, &nLines );
+
+ if( pAcc )
+ {
+ if( pBuffer )
+ {
+ FillBitmap();
+ rtl_freeMemory( pBuffer );
+ pBuffer = NULL;
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ pAcc = NULL;
+
+ if( rIStm.GetError() == ERRCODE_IO_PENDING )
+ rGraphic = CreateIntermediateGraphic( aBmp, nLines );
+ else
+ rGraphic = aBmp;
+
+ bRet = TRUE;
+ }
+ else if( rIStm.GetError() == ERRCODE_IO_PENDING )
+ bRet = TRUE;
+
+ // Status setzen ( Pending hat immer Vorrang )
+ if( rIStm.GetError() == ERRCODE_IO_PENDING )
+ {
+ eReadState = JPEGREAD_NEED_MORE;
+ rIStm.ResetError();
+ nFormerPos = rIStm.Tell();
+ }
+ else
+ {
+ if( bRet )
+ eReadState = JPEGREAD_OK;
+ else
+ eReadState = JPEGREAD_ERROR;
+ }
+
+ return eReadState;
+}
+
+
+// --------------
+// - JPEGWriter -
+// --------------
+
+JPEGWriter::JPEGWriter( SvStream& rStm, const uno::Sequence< beans::PropertyValue >* pFilterData, bool* pExportWasGrey ) :
+ rOStm ( rStm ),
+ pAcc ( NULL ),
+ pBuffer ( NULL ),
+ pExpWasGrey ( pExportWasGrey )
+{
+ FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
+ bGreys = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "ColorMode" ) ), 0 ) != 0;
+ nQuality = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ), 75 );
+
+ if ( pFilterData )
+ {
+ int nArgs = pFilterData->getLength();
+ const beans::PropertyValue* pValues = pFilterData->getConstArray();
+ while( nArgs-- )
+ {
+ if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ) ) )
+ {
+ pValues->Value >>= xStatusIndicator;
+ }
+ pValues++;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void* JPEGWriter::GetScanline( long nY )
+{
+ void* pScanline = NULL;
+
+ if( pAcc )
+ {
+ if( bNative )
+ pScanline = pAcc->GetScanline( nY );
+ else if( pBuffer )
+ {
+ BitmapColor aColor;
+ long nWidth = pAcc->Width();
+ BYTE* pTmp = pBuffer;
+
+ if( pAcc->HasPalette() )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor = pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) );
+ *pTmp++ = aColor.GetRed();
+ if ( bGreys )
+ continue;
+ *pTmp++ = aColor.GetGreen();
+ *pTmp++ = aColor.GetBlue();
+ }
+ }
+ else
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aColor = pAcc->GetPixel( nY, nX );
+ *pTmp++ = aColor.GetRed();
+ if ( bGreys )
+ continue;
+ *pTmp++ = aColor.GetGreen();
+ *pTmp++ = aColor.GetBlue();
+ }
+ }
+
+ pScanline = pBuffer;
+ }
+ }
+
+ return pScanline;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL JPEGWriter::Write( const Graphic& rGraphic )
+{
+ BOOL bRet = FALSE;
+
+ if ( xStatusIndicator.is() )
+ {
+ rtl::OUString aMsg;
+ xStatusIndicator->start( aMsg, 100 );
+ }
+
+ Bitmap aGraphicBmp( rGraphic.GetBitmap() );
+
+ if ( bGreys )
+ {
+ if ( !aGraphicBmp.Convert( BMP_CONVERSION_8BIT_GREYS ) )
+ aGraphicBmp = rGraphic.GetBitmap();
+ }
+
+ pAcc = aGraphicBmp.AcquireReadAccess();
+
+ if ( !bGreys ) // bitmap was not explicitely converted into greyscale,
+ { // check if source is greyscale only
+
+ sal_Bool bIsGrey = sal_True;
+
+ long nWidth = pAcc->Width();
+ for ( long nY = 0; bIsGrey && ( nY < pAcc->Height() ); nY++ )
+ {
+ BitmapColor aColor;
+ for( long nX = 0L; bIsGrey && ( nX < nWidth ); nX++ )
+ {
+ aColor = pAcc->HasPalette() ? pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) )
+ : pAcc->GetPixel( nY, nX );
+ bIsGrey = ( aColor.GetRed() == aColor.GetGreen() ) && ( aColor.GetRed() == aColor.GetBlue() );
+ }
+ }
+ if ( bIsGrey )
+ bGreys = sal_True;
+ }
+
+ if( pExpWasGrey )
+ *pExpWasGrey = bGreys;
+
+ if( pAcc )
+ {
+ bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB );
+
+ if( !bNative )
+ pBuffer = new BYTE[ AlignedWidth4Bytes( bGreys ? pAcc->Width() * 8L : pAcc->Width() * 24L ) ];
+
+ JPEGCallbackStruct aCallbackData;
+ aCallbackData.xStatusIndicator = xStatusIndicator;
+ bRet = (BOOL) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), bGreys, nQuality, &aCallbackData );
+
+ delete[] pBuffer;
+ pBuffer = NULL;
+
+ aGraphicBmp.ReleaseAccess( pAcc );
+ pAcc = NULL;
+ }
+ if ( xStatusIndicator.is() )
+ xStatusIndicator->end();
+
+ return bRet;
+}
+
+// --------------
+// - ImportJPEG -
+// --------------
+
+BOOL ImportJPEG( SvStream& rStm, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags )
+{
+ JPEGReader* pJPEGReader = (JPEGReader*) rGraphic.GetContext();
+ ReadState eReadState;
+ BOOL bRet = TRUE;
+
+ if( !pJPEGReader )
+ pJPEGReader = new JPEGReader( rStm, pCallerData, ( nImportFlags & GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG ) != 0 );
+
+ if( nImportFlags & GRFILTER_I_FLAGS_FOR_PREVIEW )
+ pJPEGReader->SetPreviewSize( Size(128,128) );
+ else
+ pJPEGReader->DisablePreviewMode();
+
+ rGraphic.SetContext( NULL );
+ eReadState = pJPEGReader->Read( rGraphic );
+
+ if( eReadState == JPEGREAD_ERROR )
+ {
+ bRet = FALSE;
+ delete pJPEGReader;
+ }
+ else if( eReadState == JPEGREAD_OK )
+ delete pJPEGReader;
+ else
+ rGraphic.SetContext( pJPEGReader );
+
+ return bRet;
+}
+
+// --------------
+// - ExportJPEG -
+// --------------
+
+BOOL ExportJPEG( SvStream& rOStm, const Graphic& rGraphic,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
+ bool* pExportWasGrey
+ )
+{
+ JPEGWriter aJPEGWriter( rOStm, pFilterData, pExportWasGrey );
+ return aJPEGWriter.Write( rGraphic );
+}
diff --git a/svtools/source/filter.vcl/jpeg/jpeg.h b/svtools/source/filter.vcl/jpeg/jpeg.h
new file mode 100644
index 000000000000..deb06600474c
--- /dev/null
+++ b/svtools/source/filter.vcl/jpeg/jpeg.h
@@ -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 _JPEG_H
+#define _JPEG_H
+
+#if defined( ICC )
+#include <stdio.h>
+#endif
+
+#if defined (UNX) || defined(__MINGW32__)
+#include <sys/types.h>
+#endif
+
+struct JPEGCreateBitmapParam
+{
+ unsigned long nWidth;
+ unsigned long nHeight;
+ unsigned long density_unit;
+ unsigned long X_density;
+ unsigned long Y_density;
+ long bGray;
+
+ long nAlignedWidth; // these members will be filled by the
+ long bTopDown; // CreateBitmap method in svtools
+};
+
+typedef struct my_error_mgr* my_error_ptr;
+typedef unsigned char BYTE;
+#ifdef WIN
+typedef unsigned char _huge* HPBYTE;
+#else
+typedef unsigned char* HPBYTE;
+#endif
+
+void* JPEGMalloc( size_t size );
+void JPEGFree( void *ptr );
+long JPEGCallback( void* pCallbackData, long nPercent );
+
+long WriteJPEG( void* pJPEGWriter, void* pOStm, long nWidth, long nHeight, long bGreyScale,
+ long nQualityPercent, void* pCallbackData );
+void* GetScanline( void* pJPEGWriter, long nY );
+
+void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines );
+void* CreateBitmap( void* pJPEGReader, void* pJPEGCreateBitmapParam );
+
+/* TODO: when incompatible changes are possible again
+ the preview size hint should be redone */
+void SetJpegPreviewSizeHint( int nWidth, int nHeight );
+
+#endif
diff --git a/svtools/source/filter.vcl/jpeg/jpegc.c b/svtools/source/filter.vcl/jpeg/jpegc.c
new file mode 100644
index 000000000000..29b4749a7b51
--- /dev/null
+++ b/svtools/source/filter.vcl/jpeg/jpegc.c
@@ -0,0 +1,284 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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 <stdlib.h>
+#include "setjmp.h"
+#include "jpeglib.h"
+#include "jerror.h"
+#include "jpeg.h"
+#include "rtl/alloc.h"
+#include "osl/diagnose.h"
+
+struct my_error_mgr
+{
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+};
+
+void jpeg_svstream_src (j_decompress_ptr cinfo, void* infile);
+void jpeg_svstream_dest (j_compress_ptr cinfo, void* outfile);
+
+METHODDEF( void )
+my_error_exit (j_common_ptr cinfo)
+{
+ my_error_ptr myerr = (my_error_ptr) cinfo->err;
+ (*cinfo->err->output_message) (cinfo);
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+
+METHODDEF( void )
+my_output_message (j_common_ptr cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message) (cinfo, buffer);
+}
+
+/* TODO: when incompatible changes are possible again
+ the preview size hint should be redone */
+static int nPreviewWidth = 0;
+static int nPreviewHeight = 0;
+void SetJpegPreviewSizeHint( int nWidth, int nHeight )
+{
+ nPreviewWidth = nWidth;
+ nPreviewHeight = nHeight;
+}
+
+void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
+{
+ struct jpeg_decompress_struct cinfo;
+ struct my_error_mgr jerr;
+ struct JPEGCreateBitmapParam aCreateBitmapParam;
+ HPBYTE pDIB;
+ HPBYTE pTmp;
+ long nWidth;
+ long nHeight;
+ long nAlignedWidth;
+ JSAMPLE * range_limit;
+ HPBYTE pScanLineBuffer = NULL;
+ long nScanLineBufferComponents = 0;
+ // declare bDecompCreated volatile because of gcc
+ // warning: variable 'bDecompCreated' might be clobbered by `longjmp' or `vfork'
+ volatile long bDecompCreated = 0;
+
+ /* Falls der Stream nicht ausreicht (IO_PENDING)
+ wird ueber ein longjmp in der Schleife nach Exit
+ gesprungen, wir geben dann die Anzahl
+ der bisher bearbeiteten Scanlines zurueck*/
+ if ( setjmp( jerr.setjmp_buffer ) )
+ goto Exit;
+
+ cinfo.err = jpeg_std_error( &jerr.pub );
+ jerr.pub.error_exit = my_error_exit;
+ jerr.pub.output_message = my_output_message;
+
+ jpeg_create_decompress( &cinfo );
+ bDecompCreated = 1;
+ jpeg_svstream_src( &cinfo, pIStm );
+ jpeg_read_header( &cinfo, TRUE );
+
+ cinfo.scale_num = 1;
+ cinfo.scale_denom = 1;
+ cinfo.output_gamma = 1.0;
+ cinfo.raw_data_out = FALSE;
+ cinfo.quantize_colors = FALSE;
+ if ( cinfo.jpeg_color_space == JCS_YCbCr )
+ cinfo.out_color_space = JCS_RGB;
+ else if ( cinfo.jpeg_color_space == JCS_YCCK )
+ cinfo.out_color_space = JCS_CMYK;
+
+ OSL_ASSERT(cinfo.out_color_space == JCS_CMYK || cinfo.out_color_space == JCS_GRAYSCALE || cinfo.out_color_space == JCS_RGB);
+
+ /* change scale for preview import */
+ if( nPreviewWidth || nPreviewHeight )
+ {
+ if( nPreviewWidth == 0 ) {
+ nPreviewWidth = ( cinfo.image_width*nPreviewHeight )/cinfo.image_height;
+ if( nPreviewWidth <= 0 )
+ nPreviewWidth = 1;
+ } else if( nPreviewHeight == 0 ) {
+ nPreviewHeight = ( cinfo.image_height*nPreviewWidth )/cinfo.image_width;
+ if( nPreviewHeight <= 0 )
+ nPreviewHeight = 1;
+ }
+
+ for( cinfo.scale_denom = 1; cinfo.scale_denom < 8; cinfo.scale_denom *= 2 )
+ {
+ if( cinfo.image_width < nPreviewWidth * cinfo.scale_denom )
+ break;
+ if( cinfo.image_height < nPreviewHeight * cinfo.scale_denom )
+ break;
+ }
+
+ if( cinfo.scale_denom > 1 )
+ {
+ cinfo.dct_method = JDCT_FASTEST;
+ cinfo.do_fancy_upsampling = FALSE;
+ cinfo.do_block_smoothing = FALSE;
+ }
+ }
+
+ jpeg_start_decompress( &cinfo );
+
+ nWidth = cinfo.output_width;
+ nHeight = cinfo.output_height;
+ aCreateBitmapParam.nWidth = nWidth;
+ aCreateBitmapParam.nHeight = nHeight;
+
+ aCreateBitmapParam.density_unit = cinfo.density_unit;
+ aCreateBitmapParam.X_density = cinfo.X_density;
+ aCreateBitmapParam.Y_density = cinfo.Y_density;
+ aCreateBitmapParam.bGray = cinfo.output_components == 1;
+ pDIB = CreateBitmap( pJPEGReader, &aCreateBitmapParam );
+ nAlignedWidth = aCreateBitmapParam.nAlignedWidth;
+ range_limit=cinfo.sample_range_limit;
+
+ if ( cinfo.out_color_space == JCS_CMYK )
+ {
+ nScanLineBufferComponents = cinfo.output_width * 4;
+ pScanLineBuffer = rtl_allocateMemory( nScanLineBufferComponents );
+ }
+
+ if( pDIB )
+ {
+ if( aCreateBitmapParam.bTopDown )
+ pTmp = pDIB;
+ else
+ {
+ pTmp = pDIB + ( nHeight - 1 ) * nAlignedWidth;
+ nAlignedWidth = -nAlignedWidth;
+ }
+
+ for ( *pLines = 0; *pLines < nHeight; (*pLines)++ )
+ {
+ if (pScanLineBuffer!=NULL) { // in other words cinfo.out_color_space == JCS_CMYK
+ int i;
+ int j;
+ jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pScanLineBuffer, 1 );
+ // convert CMYK to RGB
+ for( i=0, j=0; i < nScanLineBufferComponents; i+=4, j+=3 )
+ {
+ int c_=255-pScanLineBuffer[i+0];
+ int m_=255-pScanLineBuffer[i+1];
+ int y_=255-pScanLineBuffer[i+2];
+ int k_=255-pScanLineBuffer[i+3];
+ pTmp[j+0]=range_limit[ 255L - ( c_ + k_ ) ];
+ pTmp[j+1]=range_limit[ 255L - ( m_ + k_ ) ];
+ pTmp[j+2]=range_limit[ 255L - ( y_ + k_ ) ];
+ }
+ } else {
+ jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
+ }
+ /* PENDING ??? */
+ if ( cinfo.err->msg_code == 113 )
+ break;
+
+ pTmp += nAlignedWidth;
+ }
+ }
+
+ jpeg_finish_decompress( &cinfo );
+ if (pScanLineBuffer!=NULL) {
+ rtl_freeMemory( pScanLineBuffer );
+ pScanLineBuffer=NULL;
+ }
+
+Exit:
+
+ if( bDecompCreated )
+ jpeg_destroy_decompress( &cinfo );
+}
+
+long WriteJPEG( void* pJPEGWriter, void* pOStm,
+ long nWidth, long nHeight, long bGreys,
+ long nQualityPercent, void* pCallbackData )
+{
+ struct jpeg_compress_struct cinfo;
+ struct my_error_mgr jerr;
+ void* pScanline;
+ long nY;
+ // declare bCompCreated, bRet volatile because of gcc
+ // warning: variable 'bCompCreated' might be clobbered by `longjmp' or `vfork'
+ volatile long bCompCreated = 0;
+ volatile long bRet = 0;
+
+ if ( setjmp( jerr.setjmp_buffer ) )
+ goto Exit;
+
+ cinfo.err = jpeg_std_error( &jerr.pub );
+ jerr.pub.error_exit = my_error_exit;
+ jerr.pub.output_message = my_output_message;
+
+ jpeg_create_compress( &cinfo );
+ bCompCreated = 1;
+
+ jpeg_svstream_dest( &cinfo, pOStm );
+
+ cinfo.image_width = (JDIMENSION) nWidth;
+ cinfo.image_height = (JDIMENSION) nHeight;
+ if ( bGreys )
+ {
+ cinfo.input_components = 1;
+ cinfo.in_color_space = JCS_GRAYSCALE;
+ }
+ else
+ {
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ }
+
+ jpeg_set_defaults( &cinfo );
+ jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE );
+
+ if ( ( nWidth > 128 ) || ( nHeight > 128 ) )
+ jpeg_simple_progression( &cinfo );
+
+ jpeg_start_compress( &cinfo, TRUE );
+
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ pScanline = GetScanline( pJPEGWriter, nY );
+
+ if( pScanline )
+ jpeg_write_scanlines( &cinfo, (JSAMPARRAY) &pScanline, 1 );
+
+ if( JPEGCallback( pCallbackData, nY * 100L / nHeight ) )
+ goto Exit;
+ }
+
+ bRet = 1;
+
+ jpeg_finish_compress(&cinfo);
+
+Exit:
+
+ if ( bCompCreated )
+ jpeg_destroy_compress( &cinfo );
+
+ return bRet;
+}
diff --git a/svtools/source/filter.vcl/jpeg/makefile.mk b/svtools/source/filter.vcl/jpeg/makefile.mk
new file mode 100644
index 000000000000..c782c520324c
--- /dev/null
+++ b/svtools/source/filter.vcl/jpeg/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=svtools
+TARGET=jpeg
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+SOLARINC+=-I../../inc
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/jpegc.obj \
+ $(SLO)$/jpeg.obj
+
+.INCLUDE : target.mk
diff --git a/svtools/source/filter.vcl/wmf/emfwr.cxx b/svtools/source/filter.vcl/wmf/emfwr.cxx
new file mode 100644
index 000000000000..f31fd4439e9f
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/emfwr.cxx
@@ -0,0 +1,1415 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "emfwr.hxx"
+#include <vcl/salbtype.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/lineinfo.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+#define WIN_EMR_HEADER 1
+#define WIN_EMR_POLYBEZIER 2
+#define WIN_EMR_POLYGON 3
+#define WIN_EMR_POLYLINE 4
+#define WIN_EMR_POLYBEZIERTO 5
+#define WIN_EMR_POLYLINETO 6
+#define WIN_EMR_POLYPOLYLINE 7
+#define WIN_EMR_POLYPOLYGON 8
+#define WIN_EMR_SETWINDOWEXTEX 9
+#define WIN_EMR_SETWINDOWORGEX 10
+#define WIN_EMR_SETVIEWPORTEXTEX 11
+#define WIN_EMR_SETVIEWPORTORGEX 12
+#define WIN_EMR_SETBRUSHORGEX 13
+#define WIN_EMR_EOF 14
+#define WIN_EMR_SETPIXELV 15
+#define WIN_EMR_SETMAPPERFLAGS 16
+#define WIN_EMR_SETMAPMODE 17
+#define WIN_EMR_SETBKMODE 18
+#define WIN_EMR_SETPOLYFILLMODE 19
+#define WIN_EMR_SETROP2 20
+#define WIN_EMR_SETSTRETCHBLTMODE 21
+#define WIN_EMR_SETTEXTALIGN 22
+#define WIN_EMR_SETCOLORADJUSTMENT 23
+#define WIN_EMR_SETTEXTCOLOR 24
+#define WIN_EMR_SETBKCOLOR 25
+#define WIN_EMR_OFFSETCLIPRGN 26
+#define WIN_EMR_MOVETOEX 27
+#define WIN_EMR_SETMETARGN 28
+#define WIN_EMR_EXCLUDECLIPRECT 29
+#define WIN_EMR_INTERSECTCLIPRECT 30
+#define WIN_EMR_SCALEVIEWPORTEXTEX 31
+#define WIN_EMR_SCALEWINDOWEXTEX 32
+#define WIN_EMR_SAVEDC 33
+#define WIN_EMR_RESTOREDC 34
+#define WIN_EMR_SETWORLDTRANSFORM 35
+#define WIN_EMR_MODIFYWORLDTRANSFORM 36
+#define WIN_EMR_SELECTOBJECT 37
+#define WIN_EMR_CREATEPEN 38
+#define WIN_EMR_CREATEBRUSHINDIRECT 39
+#define WIN_EMR_DELETEOBJECT 40
+#define WIN_EMR_ANGLEARC 41
+#define WIN_EMR_ELLIPSE 42
+#define WIN_EMR_RECTANGLE 43
+#define WIN_EMR_ROUNDRECT 44
+#define WIN_EMR_ARC 45
+#define WIN_EMR_CHORD 46
+#define WIN_EMR_PIE 47
+#define WIN_EMR_SELECTPALETTE 48
+#define WIN_EMR_CREATEPALETTE 49
+#define WIN_EMR_SETPALETTEENTRIES 50
+#define WIN_EMR_RESIZEPALETTE 51
+#define WIN_EMR_REALIZEPALETTE 52
+#define WIN_EMR_EXTFLOODFILL 53
+#define WIN_EMR_LINETO 54
+#define WIN_EMR_ARCTO 55
+#define WIN_EMR_POLYDRAW 56
+#define WIN_EMR_SETARCDIRECTION 57
+#define WIN_EMR_SETMITERLIMIT 58
+#define WIN_EMR_BEGINPATH 59
+#define WIN_EMR_ENDPATH 60
+#define WIN_EMR_CLOSEFIGURE 61
+#define WIN_EMR_FILLPATH 62
+#define WIN_EMR_STROKEANDFILLPATH 63
+#define WIN_EMR_STROKEPATH 64
+#define WIN_EMR_FLATTENPATH 65
+#define WIN_EMR_WIDENPATH 66
+#define WIN_EMR_SELECTCLIPPATH 67
+#define WIN_EMR_ABORTPATH 68
+
+#define WIN_EMR_GDICOMMENT 70
+#define WIN_EMR_FILLRGN 71
+#define WIN_EMR_FRAMERGN 72
+#define WIN_EMR_INVERTRGN 73
+#define WIN_EMR_PAINTRGN 74
+#define WIN_EMR_EXTSELECTCLIPRGN 75
+#define WIN_EMR_BITBLT 76
+#define WIN_EMR_STRETCHBLT 77
+#define WIN_EMR_MASKBLT 78
+#define WIN_EMR_PLGBLT 79
+#define WIN_EMR_SETDIBITSTODEVICE 80
+#define WIN_EMR_STRETCHDIBITS 81
+#define WIN_EMR_EXTCREATEFONTINDIRECTW 82
+#define WIN_EMR_EXTTEXTOUTA 83
+#define WIN_EMR_EXTTEXTOUTW 84
+#define WIN_EMR_POLYBEZIER16 85
+#define WIN_EMR_POLYGON16 86
+#define WIN_EMR_POLYLINE16 87
+#define WIN_EMR_POLYBEZIERTO16 88
+#define WIN_EMR_POLYLINETO16 89
+#define WIN_EMR_POLYPOLYLINE16 90
+#define WIN_EMR_POLYPOLYGON16 91
+#define WIN_EMR_POLYDRAW16 92
+#define WIN_EMR_CREATEMONOBRUSH 93
+#define WIN_EMR_CREATEDIBPATTERNBRUSHPT 94
+#define WIN_EMR_EXTCREATEPEN 95
+#define WIN_EMR_POLYTEXTOUTA 96
+#define WIN_EMR_POLYTEXTOUTW 97
+
+#define WIN_SRCCOPY 0x00CC0020L
+#define WIN_SRCPAINT 0x00EE0086L
+#define WIN_SRCAND 0x008800C6L
+#define WIN_SRCINVERT 0x00660046L
+
+#define HANDLE_INVALID 0xffffffff
+#define MAXHANDLES 65000
+
+#define LINE_SELECT 0x00000001
+#define FILL_SELECT 0x00000002
+#define TEXT_SELECT 0x00000004
+
+/* Text Alignment Options */
+#define TA_NOUPDATECP 0
+#define TA_UPDATECP 1
+
+#define TA_LEFT 0
+#define TA_RIGHT 2
+#define TA_CENTER 6
+
+#define TA_TOP 0
+#define TA_BOTTOM 8
+#define TA_BASELINE 24
+#define TA_RTLREADING 256
+#define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
+
+#define MM_ANISOTROPIC 8
+
+// -------------
+// - EMFWriter -
+// -------------
+
+BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfigItem* pFilterConfigItem )
+{
+ const ULONG nHeaderPos = rOStm.Tell();
+
+ mpHandlesUsed = new BOOL[ MAXHANDLES ];
+ memset( mpHandlesUsed, 0, MAXHANDLES * sizeof( BOOL ) );
+ mnHorTextAlign = mnHandleCount = mnLastPercent = mnRecordPos = mnRecordCount = 0;
+ mnLineHandle = mnFillHandle = mnTextHandle = HANDLE_INVALID;
+ mbRecordOpen = FALSE;
+
+ mpStm = &rOStm;
+ maVDev.EnableOutput( FALSE );
+ maVDev.SetMapMode( rMtf.GetPrefMapMode() );
+ mpFilterConfigItem = pFilterConfigItem;
+
+ // don't work with pixel as destination map mode -> higher resolution preferrable
+ maDestMapMode.SetMapUnit( MAP_100TH_MM );
+
+ const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
+ const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
+
+ // seek over header
+ // use [MS-EMF 2.2.11] HeaderExtension2 Object, otherwise resulting EMF cannot be converted with GetWinMetaFileBits()
+ rOStm.SeekRel( 108 );
+
+ // write initial values
+
+ // set 100th mm map mode in EMF
+ ImplBeginRecord( WIN_EMR_SETMAPMODE );
+ (*mpStm) << (INT32) MM_ANISOTROPIC;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETVIEWPORTEXTEX );
+ (*mpStm) << (INT32) maVDev.ImplGetDPIX() << (INT32) maVDev.ImplGetDPIY();
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX );
+ (*mpStm) << (INT32) 2540 << (INT32) 2540;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETVIEWPORTORGEX );
+ (*mpStm) << (INT32) 0 << (INT32) 0;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
+ (*mpStm) << (INT32) 0 << (INT32) 0;
+ ImplEndRecord();
+
+ ImplWriteRasterOp( ROP_OVERPAINT );
+
+ ImplBeginRecord( WIN_EMR_SETBKMODE );
+ (*mpStm) << (UINT32) 1; // TRANSPARENT
+ ImplEndRecord();
+
+ // write emf data
+ ImplWrite( rMtf );
+
+ ImplBeginRecord( WIN_EMR_EOF );
+ (*mpStm)<< (sal_uInt32)0 // nPalEntries
+ << (sal_uInt32)0x10 // offPalEntries
+ << (sal_uInt32)0x14; // nSizeLast
+ ImplEndRecord();
+
+
+ // write header
+ const ULONG nEndPos = mpStm->Tell(); mpStm->Seek( nHeaderPos );
+
+ (*mpStm) << (UINT32) 0x00000001 << (UINT32) 108 //use [MS-EMF 2.2.11] HeaderExtension2 Object
+ << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 )
+ << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 )
+ << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos )
+ << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0
+ << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height()
+ << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 )
+ << (UINT32) 0 << (UINT32) 0 << (UINT32) 0
+ << (INT32) ( aMtfSizeLog.Width() * 10 ) << (INT32) ( aMtfSizeLog.Height() * 10 ); //use [MS-EMF 2.2.11] HeaderExtension2 Object
+
+ mpStm->Seek( nEndPos );
+ delete[] mpHandlesUsed;
+
+ return( mpStm->GetError() == ERRCODE_NONE );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG EMFWriter::ImplAcquireHandle()
+{
+ ULONG nHandle = HANDLE_INVALID;
+
+ for( ULONG i = 0; i < MAXHANDLES && ( HANDLE_INVALID == nHandle ); i++ )
+ {
+ if( !mpHandlesUsed[ i ] )
+ {
+ mpHandlesUsed[ i ] = TRUE;
+
+ if( ( nHandle = i ) == mnHandleCount )
+ mnHandleCount++;
+ }
+ }
+
+ DBG_ASSERT( nHandle != HANDLE_INVALID, "No more handles available" );
+ return( nHandle != HANDLE_INVALID ? nHandle + 1 : HANDLE_INVALID );
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplReleaseHandle( ULONG nHandle )
+{
+ DBG_ASSERT( nHandle && ( nHandle < MAXHANDLES ), "Handle out of range" );
+ mpHandlesUsed[ nHandle - 1 ] = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplBeginRecord( sal_uInt32 nType )
+{
+ DBG_ASSERT( !mbRecordOpen, "Another record is already opened!" );
+
+ if( !mbRecordOpen )
+ {
+ mbRecordOpen = TRUE;
+ mnRecordPos = mpStm->Tell();
+
+ (*mpStm) << nType;
+ mpStm->SeekRel( 4 );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplEndRecord()
+{
+ DBG_ASSERT( mbRecordOpen, "Record was not opened!" );
+
+ if( mbRecordOpen )
+ {
+ sal_Int32 nFillBytes, nActPos = mpStm->Tell();
+ mpStm->Seek( mnRecordPos + 4 );
+ nFillBytes = nActPos - mnRecordPos;
+ nFillBytes += 3; // each record has to be dword aligned
+ nFillBytes ^= 3;
+ nFillBytes &= 3;
+ *mpStm << (sal_uInt32)( ( nActPos - mnRecordPos ) + nFillBytes );
+ mpStm->Seek( nActPos );
+ while( nFillBytes-- )
+ *mpStm << (sal_uInt8)0;
+ mnRecordCount++;
+ mbRecordOpen = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL EMFWriter::ImplPrepareHandleSelect( sal_uInt32& rHandle, ULONG nSelectType )
+{
+ if( rHandle != HANDLE_INVALID )
+ {
+ UINT32 nStockObject = 0x80000000;
+
+ if( LINE_SELECT == nSelectType )
+ nStockObject |= 0x00000007;
+ else if( FILL_SELECT == nSelectType )
+ nStockObject |= 0x00000001;
+ else if( TEXT_SELECT == nSelectType )
+ nStockObject |= 0x0000000a;
+
+ // select stock object first
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ ( *mpStm ) << nStockObject;
+ ImplEndRecord();
+
+ // destroy handle of created object
+ ImplBeginRecord( WIN_EMR_DELETEOBJECT );
+ ( *mpStm ) << rHandle;
+ ImplEndRecord();
+
+ // mark handle as free
+ ImplReleaseHandle( rHandle );
+ }
+
+ rHandle = ImplAcquireHandle();
+
+ return( HANDLE_INVALID != rHandle );
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplCheckLineAttr()
+{
+ if( mbLineChanged && ImplPrepareHandleSelect( mnLineHandle, LINE_SELECT ) )
+ {
+ sal_uInt32 nStyle = maVDev.IsLineColor() ? 0 : 5;
+ sal_uInt32 nWidth = 0, nHeight = 0;
+
+ ImplBeginRecord( WIN_EMR_CREATEPEN );
+ (*mpStm) << mnLineHandle << nStyle << nWidth << nHeight;
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ (*mpStm) << mnLineHandle;
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplCheckFillAttr()
+{
+ if( mbFillChanged && ImplPrepareHandleSelect( mnFillHandle, FILL_SELECT ) )
+ {
+ sal_uInt32 nStyle = maVDev.IsFillColor() ? 0 : 1;
+ sal_uInt32 nPatternStyle = 0;
+
+ ImplBeginRecord( WIN_EMR_CREATEBRUSHINDIRECT );
+ (*mpStm) << mnFillHandle << nStyle;
+ ImplWriteColor( maVDev.GetFillColor() );
+ (*mpStm) << nPatternStyle;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ (*mpStm) << mnFillHandle;
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplCheckTextAttr()
+{
+ if( mbTextChanged && ImplPrepareHandleSelect( mnTextHandle, TEXT_SELECT ) )
+ {
+ const Font& rFont = maVDev.GetFont();
+ String aFontName( rFont.GetName() );
+ sal_Int32 nWeight;
+ sal_uInt16 i;
+ sal_uInt8 nPitchAndFamily;
+
+ ImplBeginRecord( WIN_EMR_EXTCREATEFONTINDIRECTW );
+ (*mpStm) << mnTextHandle;
+ ImplWriteExtent( -rFont.GetSize().Height() );
+ ImplWriteExtent( rFont.GetSize().Width() );
+ (*mpStm) << (INT32) rFont.GetOrientation() << (INT32) rFont.GetOrientation();
+
+ switch( rFont.GetWeight() )
+ {
+ case WEIGHT_THIN: nWeight = 100; break;
+ case WEIGHT_ULTRALIGHT: nWeight = 200; break;
+ case WEIGHT_LIGHT: nWeight = 300; break;
+ case WEIGHT_SEMILIGHT: nWeight = 300; break;
+ case WEIGHT_NORMAL: nWeight = 400; break;
+ case WEIGHT_MEDIUM: nWeight = 500; break;
+ case WEIGHT_SEMIBOLD: nWeight = 600; break;
+ case WEIGHT_BOLD: nWeight = 700; break;
+ case WEIGHT_ULTRABOLD: nWeight = 800; break;
+ case WEIGHT_BLACK: nWeight = 900; break;
+ default: nWeight = 0; break;
+ }
+
+ (*mpStm) << nWeight;
+ (*mpStm) << (BYTE) ( ( ITALIC_NONE == rFont.GetItalic() ) ? 0 : 1 );
+ (*mpStm) << (BYTE) ( ( UNDERLINE_NONE == rFont.GetUnderline() ) ? 0 : 1 );
+ (*mpStm) << (BYTE) ( ( STRIKEOUT_NONE == rFont.GetStrikeout() ) ? 0 : 1 );
+ (*mpStm) << (BYTE) ( ( RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet() ) ? 2 : 0 );
+ (*mpStm) << (BYTE) 0 << (BYTE) 0 << (BYTE) 0;
+
+ switch( rFont.GetPitch() )
+ {
+ case PITCH_FIXED: nPitchAndFamily = 0x01; break;
+ case PITCH_VARIABLE: nPitchAndFamily = 0x02; break;
+ default: nPitchAndFamily = 0x00; break;
+ }
+
+ switch( rFont.GetFamily() )
+ {
+ case FAMILY_DECORATIVE: nPitchAndFamily |= 0x50; break;
+ case FAMILY_MODERN: nPitchAndFamily |= 0x30; break;
+ case FAMILY_ROMAN: nPitchAndFamily |= 0x10; break;
+ case FAMILY_SCRIPT: nPitchAndFamily |= 0x40; break;
+ case FAMILY_SWISS: nPitchAndFamily |= 0x20; break;
+ default: break;
+ }
+
+ (*mpStm) << nPitchAndFamily;
+
+ for( i = 0; i < 32; i++ )
+ (*mpStm) << (sal_Unicode) ( ( i < aFontName.Len() ) ? aFontName.GetChar( i ) : 0 );
+
+ // dummy elfFullName
+ for( i = 0; i < 64; i++ )
+ (*mpStm) << (sal_Unicode) 0;
+
+ // dummy elfStyle
+ for( i = 0; i < 32; i++ )
+ (*mpStm) << (sal_Unicode) 0;
+
+ // dummy elfVersion, elfStyleSize, elfMatch, elfReserved
+ (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 ;
+
+ // dummy elfVendorId
+ (*mpStm) << (UINT32) 0;
+
+ // dummy elfCulture
+ (*mpStm) << (UINT32) 0;
+
+ // dummy elfPanose
+ (*mpStm) << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0;
+
+ // fill record to get a record size divideable by 4
+ (*mpStm) << (UINT16) 0;
+
+ ImplEndRecord();
+
+ // TextAlign
+ UINT32 nTextAlign;
+
+ switch( rFont.GetAlign() )
+ {
+ case ALIGN_TOP: nTextAlign = TA_TOP; break;
+ case ALIGN_BOTTOM: nTextAlign = TA_BOTTOM; break;
+ default: nTextAlign = TA_BASELINE; break;
+ }
+ nTextAlign |= mnHorTextAlign;
+
+ ImplBeginRecord( WIN_EMR_SETTEXTALIGN );
+ (*mpStm) << nTextAlign;
+ ImplEndRecord();
+
+ // Text color
+ ImplBeginRecord( WIN_EMR_SETTEXTCOLOR );
+ ImplWriteColor( maVDev.GetTextColor() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ (*mpStm) << mnTextHandle;
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteColor( const Color& rColor )
+{
+ UINT32 nCol = rColor.GetRed();
+
+ nCol |= ( (UINT32) rColor.GetGreen() ) << 8;
+ nCol |= ( (UINT32) rColor.GetBlue() ) << 16;
+
+ (*mpStm) << nCol;
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteRasterOp( RasterOp eRop )
+{
+ UINT32 nROP2;
+
+ switch( eRop )
+ {
+ case ROP_INVERT: nROP2 = 6; break;
+ case ROP_XOR: nROP2 = 7; break;
+ default: nROP2 = 13;break;
+ }
+
+ ImplBeginRecord( WIN_EMR_SETROP2 );
+ (*mpStm) << nROP2;
+ ImplEndRecord();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteExtent( long nExtent )
+{
+ nExtent = maVDev.LogicToLogic( Size( nExtent, 0 ), maVDev.GetMapMode(), maDestMapMode ).Width();
+ (*mpStm) << (INT32) nExtent;
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePoint( const Point& rPoint )
+{
+ const Point aPoint( maVDev.LogicToLogic( rPoint, maVDev.GetMapMode(), maDestMapMode ));
+ (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteSize( const Size& rSize)
+{
+ const Size aSize( maVDev.LogicToLogic( rSize, maVDev.GetMapMode(), maDestMapMode ));
+ (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteRect( const Rectangle& rRect )
+{
+ const Rectangle aRect( maVDev.LogicToLogic ( rRect, maVDev.GetMapMode(), maDestMapMode ));
+ (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose )
+{
+ if( rPoly.GetSize() )
+ {
+ if( rPoly.HasFlags() )
+ ImplWritePath( rPoly, bClose );
+ else
+ {
+ if( bClose )
+ ImplCheckFillAttr();
+
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( bClose ? WIN_EMR_POLYGON : WIN_EMR_POLYLINE );
+ ImplWriteRect( rPoly.GetBoundRect() );
+ (*mpStm) << (UINT32) rPoly.GetSize();
+
+ for( USHORT i = 0; i < rPoly.GetSize(); i++ )
+ ImplWritePoint( rPoly[ i ] );
+
+ ImplEndRecord();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly )
+{
+ sal_uInt16 n, i, nPolyCount = rPolyPoly.Count();
+
+ if( nPolyCount )
+ {
+ if( 1 == nPolyCount )
+ ImplWritePolygonRecord( rPolyPoly[ 0 ], TRUE );
+ else
+ {
+ sal_Bool bHasFlags = sal_False;
+ sal_uInt32 nTotalPoints = 0;
+
+ for( i = 0; i < nPolyCount; i++ )
+ {
+ nTotalPoints += rPolyPoly[ i ].GetSize();
+ if ( rPolyPoly[ i ].HasFlags() )
+ bHasFlags = sal_True;
+ }
+ if( nTotalPoints )
+ {
+ if ( bHasFlags )
+ ImplWritePath( rPolyPoly, sal_True );
+ else
+ {
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_POLYPOLYGON );
+ ImplWriteRect( rPolyPoly.GetBoundRect() );
+ (*mpStm) << (sal_uInt32)nPolyCount << nTotalPoints;
+
+ for( i = 0; i < nPolyCount; i++ )
+ (*mpStm) << (sal_uInt32)rPolyPoly[ i ].GetSize();
+
+ for( i = 0; i < nPolyCount; i++ )
+ {
+ const Polygon& rPoly = rPolyPoly[ i ];
+
+ for( n = 0; n < rPoly.GetSize(); n++ )
+ ImplWritePoint( rPoly[ n ] );
+ }
+ ImplEndRecord();
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
+{
+ if ( bClosed )
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_BEGINPATH );
+ ImplEndRecord();
+
+ sal_uInt16 i, n, o, nPolyCount = rPolyPoly.Count();
+ for ( i = 0; i < nPolyCount; i++ )
+ {
+ n = 0;
+ const Polygon& rPoly = rPolyPoly[ i ];
+ while ( n < rPoly.GetSize() )
+ {
+ if( n == 0 )
+ {
+ ImplBeginRecord( WIN_EMR_MOVETOEX );
+ ImplWritePoint( rPoly[ 0 ] );
+ ImplEndRecord();
+ n++;
+ continue;
+ }
+
+ sal_uInt16 nBezPoints = 0;
+
+ while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) )
+ nBezPoints += 3;
+
+ if ( nBezPoints )
+ {
+ ImplBeginRecord( WIN_EMR_POLYBEZIERTO );
+ Polygon aNewPoly( nBezPoints + 1 );
+ aNewPoly[ 0 ] = rPoly[ n - 1 ];
+ for ( o = 0; o < nBezPoints; o++ )
+ aNewPoly[ o + 1 ] = rPoly[ n + o ];
+ ImplWriteRect( aNewPoly.GetBoundRect() );
+ (*mpStm) << (sal_uInt32)nBezPoints;
+ for( o = 1; o < aNewPoly.GetSize(); o++ )
+ ImplWritePoint( aNewPoly[ o ] );
+ ImplEndRecord();
+ n = n + nBezPoints;
+ }
+ else
+ {
+ sal_uInt16 nPoints = 1;
+ while( ( nPoints + n ) < rPoly.GetSize() && ( rPoly.GetFlags( nPoints + n ) != POLY_CONTROL ) )
+ nPoints++;
+
+ if ( nPoints > 1 )
+ {
+ ImplBeginRecord( WIN_EMR_POLYLINETO );
+ Polygon aNewPoly( nPoints + 1 );
+ aNewPoly[ 0 ] = rPoly[ n - 1];
+ for ( o = 1; o <= nPoints; o++ )
+ aNewPoly[ o ] = rPoly[ n - 1 + o ];
+ ImplWriteRect( aNewPoly.GetBoundRect() );
+ (*mpStm) << (sal_uInt32)( nPoints );
+ for( o = 1; o < aNewPoly.GetSize(); o++ )
+ ImplWritePoint( aNewPoly[ o ] );
+ ImplEndRecord();
+ }
+ else
+ {
+ ImplBeginRecord( WIN_EMR_LINETO );
+ ImplWritePoint( rPoly[ n ] );
+ ImplEndRecord();
+ }
+ n = n + nPoints;
+ }
+ if ( bClosed && ( n == rPoly.GetSize() ) )
+ {
+ ImplBeginRecord( WIN_EMR_CLOSEFIGURE );
+ ImplEndRecord();
+ }
+ }
+ }
+ ImplBeginRecord( WIN_EMR_ENDPATH );
+ ImplEndRecord();
+ ImplBeginRecord( bClosed ? WIN_EMR_FILLPATH : WIN_EMR_STROKEPATH );
+ ImplWriteRect( rPolyPoly.GetBoundRect() );
+ ImplEndRecord();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt,
+ const Size& rSz, UINT32 nROP )
+{
+ if( !!rBmp )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+ const Size aBmpSizePixel( rBmp.GetSizePixel() );
+
+ ImplBeginRecord( WIN_EMR_STRETCHDIBITS );
+ ImplWriteRect( Rectangle( rPt, rSz ) );
+ ImplWritePoint( rPt );
+ (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) aBmpSizePixel.Width() << (INT32) aBmpSizePixel.Height();
+
+ // write offset positions and sizes later
+ const ULONG nOffPos = mpStm->Tell();
+ mpStm->SeekRel( 16 );
+
+ (*mpStm) << (UINT32) 0 << ( ( ROP_XOR == maVDev.GetRasterOp() && WIN_SRCCOPY == nROP ) ? WIN_SRCINVERT : nROP );
+ ImplWriteSize( rSz );
+
+ rBmp.Write( aMemStm, TRUE, FALSE );
+
+ UINT32 nDIBSize = aMemStm.Tell(), nHeaderSize, nCompression, nColsUsed, nPalCount, nImageSize;
+ UINT16 nBitCount;
+
+ // get DIB parameters
+ aMemStm.Seek( 0 );
+ aMemStm >> nHeaderSize;
+ aMemStm.SeekRel( 10 );
+ aMemStm >> nBitCount >> nCompression >> nImageSize;
+ aMemStm.SeekRel( 8 );
+ aMemStm >> nColsUsed;
+
+ nPalCount = ( nBitCount <= 8 ) ? ( nColsUsed ? nColsUsed : ( 1 << (UINT32) nBitCount ) ) :
+ ( ( 3 == nCompression ) ? 12 : 0 );
+
+ mpStm->Write( aMemStm.GetData(), nDIBSize );
+
+ const ULONG nEndPos = mpStm->Tell();
+ mpStm->Seek( nOffPos );
+ (*mpStm) << (UINT32) 80 << (UINT32)( nHeaderSize + ( nPalCount << 2 ) );
+ (*mpStm) << (UINT32)( 80 + ( nHeaderSize + ( nPalCount << 2 ) ) ) << nImageSize;
+ mpStm->Seek( nEndPos );
+
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth )
+{
+ xub_StrLen nLen = rText.Len(), i;
+
+ if( nLen )
+ {
+ sal_uInt32 nNormWidth;
+ sal_Int32* pOwnArray;
+ sal_Int32* pDX;
+
+ // get text sizes
+ if( pDXArray )
+ {
+ pOwnArray = NULL;
+ nNormWidth = maVDev.GetTextWidth( rText );
+ pDX = (sal_Int32*) pDXArray;
+ }
+ else
+ {
+ pOwnArray = new sal_Int32[ nLen ];
+ nNormWidth = maVDev.GetTextArray( rText, pOwnArray );
+ pDX = pOwnArray;
+ }
+
+ if( nLen > 1 )
+ {
+ nNormWidth = pDX[ nLen - 2 ] + maVDev.GetTextWidth( rText.GetChar( nLen - 1 ) );
+
+ if( nWidth && nNormWidth && ( nWidth != nNormWidth ) )
+ {
+ const double fFactor = (double) nWidth / nNormWidth;
+
+ for( i = 0; i < ( nLen - 1 ); i++ )
+ pDX[ i ] = FRound( pDX[ i ] * fFactor );
+ }
+ }
+
+ // write text record
+ ImplBeginRecord( WIN_EMR_EXTTEXTOUTW );
+
+ ImplWriteRect( Rectangle( rPos, Size( nNormWidth, maVDev.GetTextHeight() ) ) );
+ (*mpStm) << (UINT32)1;
+ (*mpStm) << (INT32) 0 << (INT32) 0;
+ ImplWritePoint( rPos );
+ (*mpStm) << (UINT32) nLen << (UINT32) 76 << (UINT32) 2;
+ (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) 0 << (INT32) 0;
+ (*mpStm) << (UINT32) ( 76 + ( nLen << 1 ) + ( (nLen & 1 ) ? 2 : 0 ) );
+
+ // write text
+ for( i = 0; i < nLen; i++ )
+ (*mpStm) << (sal_Unicode)rText.GetChar( i );
+
+ // padding word
+ if( nLen & 1 )
+ (*mpStm) << (UINT16) 0;
+
+ // write DX array
+ ImplWriteExtent( pDX[ 0 ] );
+
+ if( nLen > 1 )
+ {
+ for( i = 1; i < ( nLen - 1 ); i++ )
+ ImplWriteExtent( pDX[ i ] - pDX[ i - 1 ] );
+
+ ImplWriteExtent( pDX[ nLen - 2 ] / ( nLen - 1 ) );
+ }
+
+ ImplEndRecord();
+ delete[] pOwnArray;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
+{
+ if(rLinePolygon.count())
+ {
+ basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
+ basegfx::B2DPolyPolygon aFillPolyPolygon;
+
+ rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
+
+ if(aLinePolyPolygon.count())
+ {
+ for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
+ {
+ const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
+ ImplWritePolygonRecord( Polygon(aCandidate), FALSE );
+ }
+ }
+
+ if(aFillPolyPolygon.count())
+ {
+ const Color aOldLineColor(maVDev.GetLineColor());
+ const Color aOldFillColor(maVDev.GetFillColor());
+
+ maVDev.SetLineColor();
+ maVDev.SetFillColor(aOldLineColor);
+
+ for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
+ {
+ const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
+ ImplWritePolyPolygonRecord(PolyPolygon(Polygon(aPolygon)));
+ }
+
+ maVDev.SetLineColor(aOldLineColor);
+ maVDev.SetFillColor(aOldFillColor);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
+{
+ for( ULONG j = 0, nActionCount = rMtf.GetActionCount(); j < nActionCount; j++ )
+ {
+ const MetaAction* pAction = rMtf.GetAction( j );
+ const USHORT nType = pAction->GetType();
+
+ switch( nType )
+ {
+ case( META_PIXEL_ACTION ):
+ {
+ const MetaPixelAction* pA = (const MetaPixelAction*) pAction;
+
+ ImplCheckLineAttr();
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetPoint() );
+ ImplWriteColor( pA->GetColor() );
+ ImplEndRecord();
+ }
+ break;
+
+ case( META_POINT_ACTION ):
+ {
+ if( maVDev.IsLineColor() )
+ {
+ const MetaPointAction* pA = (const MetaPointAction*) pAction;
+
+ ImplCheckLineAttr();
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetPoint() );
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_LINE_ACTION ):
+ {
+ if( maVDev.IsLineColor() )
+ {
+ const MetaLineAction* pA = (const MetaLineAction*) pAction;
+
+ if(pA->GetLineInfo().IsDefault())
+ {
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_MOVETOEX );
+ ImplWritePoint( pA->GetStartPoint() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_LINETO );
+ ImplWritePoint( pA->GetEndPoint() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetEndPoint() );
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
+ aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
+ Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
+ }
+ }
+ }
+ break;
+
+ case( META_RECT_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ const MetaRectAction* pA = (const MetaRectAction*) pAction;
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_RECTANGLE );
+ ImplWriteRect( pA->GetRect() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_ROUNDRECT_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction;
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_ROUNDRECT );
+ ImplWriteRect( pA->GetRect() );
+ ImplWriteSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_ELLIPSE_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction;
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_ELLIPSE );
+ ImplWriteRect( pA->GetRect() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_ARC_ACTION ):
+ case( META_PIE_ACTION ):
+ case( META_CHORD_ACTION ):
+ case( META_POLYGON_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ Polygon aPoly;
+
+ switch( nType )
+ {
+ case( META_ARC_ACTION ):
+ {
+ const MetaArcAction* pA = (const MetaArcAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC );
+ }
+ break;
+
+ case( META_PIE_ACTION ):
+ {
+ const MetaPieAction* pA = (const MetaPieAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE );
+ }
+ break;
+
+ case( META_CHORD_ACTION ):
+ {
+ const MetaChordAction* pA = (const MetaChordAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD );
+ }
+ break;
+
+ case( META_POLYGON_ACTION ):
+ aPoly = ( (const MetaPolygonAction*) pAction )->GetPolygon();
+ break;
+ }
+
+ ImplWritePolygonRecord( aPoly, nType != META_ARC_ACTION );
+ }
+ }
+ break;
+
+ case( META_POLYLINE_ACTION ):
+ {
+ if( maVDev.IsLineColor() )
+ {
+ const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction;
+ const Polygon& rPoly = pA->GetPolygon();
+
+ if( rPoly.GetSize() )
+ {
+ if(pA->GetLineInfo().IsDefault())
+ {
+ ImplWritePolygonRecord( rPoly, FALSE );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
+ }
+ }
+ }
+ }
+ break;
+
+ case( META_POLYPOLYGON_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ ImplWritePolyPolygonRecord( ( (const MetaPolyPolygonAction*) pAction )->GetPolyPolygon() );
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ {
+ const MetaGradientAction* pA = (const MetaGradientAction*) pAction;
+ GDIMetaFile aTmpMtf;
+
+ maVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
+ ImplWrite( aTmpMtf );
+ }
+ break;
+
+ case META_HATCH_ACTION:
+ {
+ const MetaHatchAction* pA = (const MetaHatchAction*) pAction;
+ GDIMetaFile aTmpMtf;
+
+ maVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
+ ImplWrite( aTmpMtf );
+ }
+ break;
+
+ case META_TRANSPARENT_ACTION:
+ {
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+ ImplWritePolyPolygonRecord( ( (MetaTransparentAction*) pAction )->GetPolyPolygon() );
+ }
+ break;
+
+ case META_FLOATTRANSPARENT_ACTION:
+ {
+ const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction;
+
+ GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
+ Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
+ const Size aSrcSize( aTmpMtf.GetPrefSize() );
+ const Point aDestPt( pA->GetPoint() );
+ const Size aDestSize( pA->GetSize() );
+ const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
+ const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
+ long nMoveX, nMoveY;
+
+ if( fScaleX != 1.0 || fScaleY != 1.0 )
+ {
+ aTmpMtf.Scale( fScaleX, fScaleY );
+ aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+ }
+
+ nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
+
+ if( nMoveX || nMoveY )
+ aTmpMtf.Move( nMoveX, nMoveY );
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+ ImplCheckTextAttr();
+ ImplWrite( aTmpMtf );
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ {
+ const MetaEPSAction* pA = (const MetaEPSAction*) pAction;
+ const GDIMetaFile aSubstitute( pA->GetSubstitute() );
+
+ for( ULONG i = 0, nCount = aSubstitute.GetActionCount(); i < nCount; i++ )
+ {
+ const MetaAction* pSubstAct = aSubstitute.GetAction( i );
+ if( pSubstAct->GetType() == META_BMPSCALE_ACTION )
+ {
+ maVDev.Push( PUSH_ALL );
+ ImplBeginRecord( WIN_EMR_SAVEDC );
+ ImplEndRecord();
+
+ MapMode aMapMode( aSubstitute.GetPrefMapMode() );
+ Size aOutSize( maVDev.LogicToLogic( pA->GetSize(), maVDev.GetMapMode(), aMapMode ) );
+ aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) );
+ aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) );
+ aMapMode.SetOrigin( maVDev.LogicToLogic( pA->GetPoint(), maVDev.GetMapMode(), aMapMode ) );
+ maVDev.SetMapMode( aMapMode );
+ ImplWrite( aSubstitute );
+
+ maVDev.Pop();
+ ImplBeginRecord( WIN_EMR_RESTOREDC );
+ (*mpStm) << (INT32) -1;
+ ImplEndRecord();
+ break;
+ }
+ }
+ }
+ break;
+
+ case META_BMP_ACTION:
+ {
+ const MetaBmpAction* pA = (const MetaBmpAction *) pAction;
+ ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetBitmap().GetSizePixel(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPSCALE_ACTION:
+ {
+ const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
+ ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPSCALEPART_ACTION:
+ {
+ const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction;
+ Bitmap aTmp( pA->GetBitmap() );
+
+ if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
+ ImplWriteBmpRecord( aTmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPEX_ACTION:
+ {
+ const MetaBmpExAction* pA = (const MetaBmpExAction *) pAction;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ ImplWriteBmpRecord( aMsk, pA->GetPoint(), aMsk.GetSizePixel(), WIN_SRCPAINT );
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCAND );
+ }
+ else
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPEXSCALE_ACTION:
+ {
+ const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT );
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND );
+ }
+ else
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPEXSCALEPART_ACTION:
+ {
+ const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction;
+ BitmapEx aBmpEx( pA->GetBitmapEx() );
+ aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
+ Bitmap aBmp( aBmpEx.GetBitmap() );
+ Bitmap aMsk( aBmpEx.GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ ImplWriteBmpRecord( aMsk, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCPAINT );
+ ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCAND );
+ }
+ else
+ ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_TEXT_ACTION:
+ {
+ const MetaTextAction* pA = (const MetaTextAction*) pAction;
+ const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetPoint(), aText, NULL, 0 );
+ }
+ break;
+
+ case META_TEXTRECT_ACTION:
+ {
+ const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
+ const String aText( pA->GetText() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetRect().TopLeft(), aText, NULL, 0 );
+ }
+ break;
+
+ case META_TEXTARRAY_ACTION:
+ {
+ const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction;
+ const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetPoint(), aText, pA->GetDXArray(), 0 );
+ }
+ break;
+
+ case META_STRETCHTEXT_ACTION:
+ {
+ const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
+ const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetPoint(), aText, NULL, pA->GetWidth() );
+ }
+ break;
+
+ case( META_LINECOLOR_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ mbLineChanged = TRUE;
+ }
+ break;
+
+ case( META_FILLCOLOR_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ mbFillChanged = TRUE;
+ }
+ break;
+
+ case( META_TEXTCOLOR_ACTION ):
+ case( META_TEXTLINECOLOR_ACTION ):
+ case( META_TEXTFILLCOLOR_ACTION ):
+ case( META_TEXTALIGN_ACTION ):
+ case( META_FONT_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ mbTextChanged = TRUE;
+ }
+ break;
+
+ case( META_ISECTRECTCLIPREGION_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+
+ ImplBeginRecord( WIN_EMR_INTERSECTCLIPRECT );
+ ImplWriteRect( ( (MetaISectRectClipRegionAction*) pAction )->GetRect() );
+ ImplEndRecord();
+ }
+ break;
+
+ case( META_CLIPREGION_ACTION ):
+ case( META_ISECTREGIONCLIPREGION_ACTION ):
+ case( META_MOVECLIPREGION_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ }
+ break;
+
+ case( META_REFPOINT_ACTION ):
+ case( META_MAPMODE_ACTION ):
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ break;
+
+ case( META_PUSH_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+
+ ImplBeginRecord( WIN_EMR_SAVEDC );
+ ImplEndRecord();
+ }
+ break;
+
+ case( META_POP_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+
+ ImplBeginRecord( WIN_EMR_RESTOREDC );
+ (*mpStm) << (INT32) -1;
+ ImplEndRecord();
+
+ ImplWriteRasterOp( maVDev.GetRasterOp() );
+ mbLineChanged = mbFillChanged = mbTextChanged = TRUE;
+ }
+ break;
+
+ case( META_RASTEROP_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ ImplWriteRasterOp( ( (MetaRasterOpAction*) pAction )->GetRasterOp() );
+ }
+ break;
+
+ case( META_LAYOUTMODE_ACTION ):
+ {
+ sal_uInt32 nLayoutMode = ( (MetaLayoutModeAction*) pAction )->GetLayoutMode();
+ mnHorTextAlign = 0;
+ if (nLayoutMode & TEXT_LAYOUT_BIDI_RTL)
+ {
+ mnHorTextAlign = TA_RIGHT | TA_RTLREADING;
+ }
+ if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT)
+ mnHorTextAlign |= TA_RIGHT;
+ else if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT)
+ mnHorTextAlign &= ~TA_RIGHT;
+ break;
+ }
+
+ case( META_MASK_ACTION ):
+ case( META_MASKSCALE_ACTION ):
+ case( META_MASKSCALEPART_ACTION ):
+ case( META_WALLPAPER_ACTION ):
+ case( META_TEXTLINE_ACTION ):
+ case( META_COMMENT_ACTION ):
+ case( META_GRADIENTEX_ACTION ):
+ {
+ // !!! >>> we don't want to support these actions
+ }
+ break;
+
+ default:
+ DBG_ERROR( ( ByteString( "EMFWriter::ImplWriteActions: unsupported MetaAction #" ) += ByteString::CreateFromInt32( nType ) ).GetBuffer() );
+ break;
+ }
+ }
+}
diff --git a/svtools/source/filter.vcl/wmf/emfwr.hxx b/svtools/source/filter.vcl/wmf/emfwr.hxx
new file mode 100644
index 000000000000..6334b5dfe16f
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/emfwr.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 _EMFWR_HXX
+#define _EMFWR_HXX
+
+#include <tools/debug.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/virdev.hxx>
+#include <svtools/fltcall.hxx>
+
+// -------------
+// - EMFWriter -
+// -------------
+
+class LineInfo;
+namespace basegfx { class B2DPolygon; }
+
+class EMFWriter
+{
+private:
+
+ VirtualDevice maVDev;
+ MapMode maDestMapMode;
+ FilterConfigItem* mpFilterConfigItem;
+ SvStream* mpStm;
+ BOOL* mpHandlesUsed;
+ ULONG mnHandleCount;
+ ULONG mnLastPercent;
+ ULONG mnRecordCount;
+ ULONG mnRecordPos;
+ BOOL mbRecordOpen;
+ BOOL mbLineChanged;
+ sal_uInt32 mnLineHandle;
+ BOOL mbFillChanged;
+ sal_uInt32 mnFillHandle;
+ BOOL mbTextChanged;
+ sal_uInt32 mnTextHandle;
+ sal_uInt32 mnHorTextAlign;
+
+ void ImplBeginRecord( sal_uInt32 nType );
+ void ImplEndRecord();
+
+ ULONG ImplAcquireHandle();
+ void ImplReleaseHandle( ULONG nHandle );
+
+ BOOL ImplPrepareHandleSelect( sal_uInt32& rHandle, ULONG nSelectType );
+ void ImplCheckLineAttr();
+ void ImplCheckFillAttr();
+ void ImplCheckTextAttr();
+
+ void ImplWriteColor( const Color& rColor );
+ void ImplWriteRasterOp( RasterOp eRop );
+ void ImplWriteExtent( long nExtent );
+ void ImplWritePoint( const Point& rPoint );
+ void ImplWriteSize( const Size& rSize);
+ void ImplWriteRect( const Rectangle& rRect );
+ void ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClose );
+ void ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose );
+ void ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly );
+ void ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt, const Size& rSz, UINT32 nROP );
+ void ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth );
+
+ void Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
+ void ImplWrite( const GDIMetaFile& rMtf );
+
+public:
+
+ EMFWriter() {}
+
+ BOOL WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfigItem* pConfigItem = NULL );
+};
+
+#endif // _EMFWR_HXX
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx
new file mode 100644
index 000000000000..1e49e0d61446
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx
@@ -0,0 +1,1343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "winmtf.hxx"
+#include <osl/endian.h>
+
+//=========================== GDI-Array ===================================
+
+#define EMR_HEADER 1
+#define EMR_POLYBEZIER 2
+#define EMR_POLYGON 3
+#define EMR_POLYLINE 4
+#define EMR_POLYBEZIERTO 5
+#define EMR_POLYLINETO 6
+#define EMR_POLYPOLYLINE 7
+#define EMR_POLYPOLYGON 8
+#define EMR_SETWINDOWEXTEX 9
+#define EMR_SETWINDOWORGEX 10
+#define EMR_SETVIEWPORTEXTEX 11
+#define EMR_SETVIEWPORTORGEX 12
+#define EMR_SETBRUSHORGEX 13
+#define EMR_EOF 14
+#define EMR_SETPIXELV 15
+#define EMR_SETMAPPERFLAGS 16
+#define EMR_SETMAPMODE 17
+#define EMR_SETBKMODE 18
+#define EMR_SETPOLYFILLMODE 19
+#define EMR_SETROP2 20
+#define EMR_SETSTRETCHBLTMODE 21
+#define EMR_SETTEXTALIGN 22
+#define EMR_SETCOLORADJUSTMENT 23
+#define EMR_SETTEXTCOLOR 24
+#define EMR_SETBKCOLOR 25
+#define EMR_OFFSETCLIPRGN 26
+#define EMR_MOVETOEX 27
+#define EMR_SETMETARGN 28
+#define EMR_EXCLUDECLIPRECT 29
+#define EMR_INTERSECTCLIPRECT 30
+#define EMR_SCALEVIEWPORTEXTEX 31
+#define EMR_SCALEWINDOWEXTEX 32
+#define EMR_SAVEDC 33
+#define EMR_RESTOREDC 34
+#define EMR_SETWORLDTRANSFORM 35
+#define EMR_MODIFYWORLDTRANSFORM 36
+#define EMR_SELECTOBJECT 37
+#define EMR_CREATEPEN 38
+#define EMR_CREATEBRUSHINDIRECT 39
+#define EMR_DELETEOBJECT 40
+#define EMR_ANGLEARC 41
+#define EMR_ELLIPSE 42
+#define EMR_RECTANGLE 43
+#define EMR_ROUNDRECT 44
+#define EMR_ARC 45
+#define EMR_CHORD 46
+#define EMR_PIE 47
+#define EMR_SELECTPALETTE 48
+#define EMR_CREATEPALETTE 49
+#define EMR_SETPALETTEENTRIES 50
+#define EMR_RESIZEPALETTE 51
+#define EMR_REALIZEPALETTE 52
+#define EMR_EXTFLOODFILL 53
+#define EMR_LINETO 54
+#define EMR_ARCTO 55
+#define EMR_POLYDRAW 56
+#define EMR_SETARCDIRECTION 57
+#define EMR_SETMITERLIMIT 58
+#define EMR_BEGINPATH 59
+#define EMR_ENDPATH 60
+#define EMR_CLOSEFIGURE 61
+#define EMR_FILLPATH 62
+#define EMR_STROKEANDFILLPATH 63
+#define EMR_STROKEPATH 64
+#define EMR_FLATTENPATH 65
+#define EMR_WIDENPATH 66
+#define EMR_SELECTCLIPPATH 67
+#define EMR_ABORTPATH 68
+
+#define EMR_GDICOMMENT 70
+#define EMR_FILLRGN 71
+#define EMR_FRAMERGN 72
+#define EMR_INVERTRGN 73
+#define EMR_PAINTRGN 74
+#define EMR_EXTSELECTCLIPRGN 75
+#define EMR_BITBLT 76
+#define EMR_STRETCHBLT 77
+#define EMR_MASKBLT 78
+#define EMR_PLGBLT 79
+#define EMR_SETDIBITSTODEVICE 80
+#define EMR_STRETCHDIBITS 81
+#define EMR_EXTCREATEFONTINDIRECTW 82
+#define EMR_EXTTEXTOUTA 83
+#define EMR_EXTTEXTOUTW 84
+#define EMR_POLYBEZIER16 85
+#define EMR_POLYGON16 86
+#define EMR_POLYLINE16 87
+#define EMR_POLYBEZIERTO16 88
+#define EMR_POLYLINETO16 89
+#define EMR_POLYPOLYLINE16 90
+#define EMR_POLYPOLYGON16 91
+#define EMR_POLYDRAW16 92
+#define EMR_CREATEMONOBRUSH 93
+#define EMR_CREATEDIBPATTERNBRUSHPT 94
+#define EMR_EXTCREATEPEN 95
+#define EMR_POLYTEXTOUTA 96
+#define EMR_POLYTEXTOUTW 97
+
+// WINDOWS VERSION >= 0x400
+#define EMR_SETICMMODE 98
+#define EMR_CREATECOLORSPACE 99
+#define EMR_SETCOLORSPACE 100
+#define EMR_DELETECOLORSPACE 101
+#define EMR_GLSRECORD 102
+#define EMR_GLSBOUNDEDRECORD 103
+#define EMR_PIXELFORMAT 104
+
+// WINDOWS VERSION >= 0x500
+#define EMR_DRAWESCAPE 105
+#define EMR_EXTESCAPE 106
+#define EMR_STARTDOC 107
+#define EMR_SMALLTEXTOUT 108
+#define EMR_FORCEUFIMAPPING 109
+#define EMR_NAMEDESCAPE 110
+#define EMR_COLORCORRECTPALETTE 111
+#define EMR_SETICMPROFILEA 112
+#define EMR_SETICMPROFILEW 113
+#define EMR_ALPHABLEND 114
+#define EMR_ALPHADIBBLEND 115
+#define EMR_TRANSPARENTBLT 116
+#define EMR_TRANSPARENTDIB 117
+#define EMR_GRADIENTFILL 118
+#define EMR_SETLINKEDUFIS 119
+#define EMR_SETTEXTJUSTIFICATION 120
+
+
+//-----------------------------------------------------------------------------------
+
+#ifdef OSL_BIGENDIAN
+// currently unused
+static float GetSwapFloat( SvStream& rSt )
+{
+ float fTmp;
+ sal_Int8* pPtr = (sal_Int8*)&fTmp;
+ rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch
+ return fTmp;
+}
+#endif
+
+SvStream& operator>>( SvStream& rIn, XForm& rXForm )
+{
+ if ( sizeof( float ) != 4 )
+ {
+ DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" );
+ rXForm = XForm();
+ }
+ else
+ {
+#ifdef OSL_BIGENDIAN
+ rXForm.eM11 = GetSwapFloat( rIn );
+ rXForm.eM12 = GetSwapFloat( rIn );
+ rXForm.eM21 = GetSwapFloat( rIn );
+ rXForm.eM22 = GetSwapFloat( rIn );
+ rXForm.eDx = GetSwapFloat( rIn );
+ rXForm.eDy = GetSwapFloat( rIn );
+#else
+ rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22
+ >> rXForm.eDx >> rXForm.eDy;
+#endif
+ }
+ return rIn;
+}
+
+static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen )
+{
+ sal_Bool bOk = sal_False;
+ if ( nLen )
+ {
+ sal_uInt32 nHdSize, nType, nCount, nRgnSize, i;
+ rSt >> nHdSize
+ >> nType
+ >> nCount
+ >> nRgnSize;
+
+ if ( nCount && ( nType == RDH_RECTANGLES ) &&
+ ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) )
+ {
+ sal_Int32 nx1, ny1, nx2, ny2;
+
+ for ( i = 0; i < nCount; i++ )
+ {
+ rSt >> nx1 >> ny1 >> nx2 >> ny2;
+
+ Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) );
+ Polygon aPolygon( aRect );
+ PolyPolygon aPolyPolyOr1( aPolygon );
+ PolyPolygon aPolyPolyOr2( rPolyPoly );
+ rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 );
+ rPolyPoly = aPolyPolyOr2;
+ }
+ bOk = sal_True;
+ }
+ }
+ return bOk;
+}
+
+BOOL EnhWMFReader::ReadEnhWMF()
+{
+ sal_uInt32 nStretchBltMode = 0;
+ sal_uInt32 nRecType, nRecSize, nNextPos,
+ nW, nH, nPoints, nColor, nIndex,
+ nDat32, nNom1, nDen1, nNom2, nDen2;
+ sal_Int32 nX32, nY32, nx32, ny32;
+ sal_Int16 nX16, nY16;
+
+ sal_Bool bFlag, bStatus = ReadHeader();
+
+ while( bStatus && nRecordCount-- )
+ {
+ *pWMF >> nRecType >> nRecSize;
+
+ if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar
+ {
+ bStatus = FALSE;
+ break;
+ }
+
+ nNextPos = pWMF->Tell() + ( nRecSize - 8 );
+
+ if ( nNextPos > nEndPos )
+ {
+ bStatus = FALSE;
+ break;
+ }
+
+ if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+
+ bFlag = sal_False;
+
+ switch( nRecType )
+ {
+ case EMR_POLYBEZIERTO :
+ bFlag = sal_True;
+ case EMR_POLYBEZIER :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ sal_uInt16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+ Polygon aPoly( (sal_uInt16)nPoints );
+ for( ; i < (sal_uInt16)nPoints; i++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPoly[ i ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath );
+ }
+ break;
+
+ case EMR_POLYGON :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ Polygon aPoly( (UINT16)nPoints );
+ for( UINT16 k = 0; k < (UINT16)nPoints; k++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPoly[ k ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolygon( aPoly, bRecordPath );
+ }
+ break;
+
+ case EMR_POLYLINETO :
+ bFlag = sal_True;
+ case EMR_POLYLINE :
+ {
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> nPoints;
+ UINT16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+ Polygon aPolygon( (UINT16)nPoints );
+ for ( ; i < (UINT16)nPoints; i++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPolygon[ i ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath );
+ }
+ break;
+
+ case EMR_POLYPOLYLINE :
+ {
+ UINT16* pnPoints;
+
+ INT32 i, nPoly;
+ pWMF->SeekRel( 0x10 );
+
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> i;
+
+ // taking the amount of points of each polygon, retrieving the total number of points
+ if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(UINT16) )
+ {
+ if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(UINT16) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ pnPoints = new UINT16[ nPoly ];
+
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+
+ // Polygonpunkte holen:
+
+ for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ )
+ {
+ Polygon aPoly( pnPoints[ i ] );
+ for( UINT16 k = 0; k < pnPoints[ i ]; k++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPoly[ k ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolyLine( aPoly, sal_False, bRecordPath );
+ }
+ delete[] pnPoints;
+ }
+ }
+ }
+ break;
+
+ case EMR_POLYPOLYGON :
+ {
+ UINT16* pnPoints;
+ Point* pPtAry;
+
+ UINT32 i, nPoly, nGesPoints;
+ pWMF->SeekRel( 0x10 );
+
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> nGesPoints;
+
+ if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(UINT16) ) )
+ {
+ if ( ( nPoly * sizeof(UINT16) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ pnPoints = new UINT16[ nPoly ];
+
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+
+ if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ // Polygonpunkte holen:
+ pPtAry = new Point[ nGesPoints ];
+
+ for ( i = 0; i < nGesPoints; i++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ pPtAry[ i ] = Point( nX32, nY32 );
+ }
+ // PolyPolygon Actions erzeugen
+ PolyPolygon aPolyPoly( (UINT16)nPoly, pnPoints, pPtAry );
+ pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
+ delete[] pPtAry;
+ }
+ delete[] pnPoints;
+ }
+ }
+ }
+ break;
+
+ case EMR_SETWINDOWEXTEX :
+ { // #75383#
+ *pWMF >> nW >> nH;
+ pOut->SetWinExt( Size( nW, nH ) );
+ }
+ break;
+
+ case EMR_SETWINDOWORGEX :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->SetWinOrg( Point( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_SCALEWINDOWEXTEX :
+ {
+ *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2;
+ pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
+ }
+ break;
+
+ case EMR_SETVIEWPORTORGEX :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->SetDevOrg( Point( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_SCALEVIEWPORTEXTEX :
+ {
+ *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2;
+ pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
+ }
+ break;
+
+ case EMR_SETVIEWPORTEXTEX :
+ {
+ *pWMF >> nW >> nH;
+ pOut->SetDevExt( Size( nW, nH ) );
+ }
+ break;
+
+ case EMR_EOF :
+ nRecordCount = 0; // #76846#
+ break;
+
+ case EMR_SETPIXELV :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() );
+ }
+ break;
+
+ case EMR_SETMAPMODE :
+ {
+ sal_uInt32 nMapMode;
+ *pWMF >> nMapMode;
+ pOut->SetMapMode( nMapMode );
+ }
+ break;
+
+ case EMR_SETBKMODE :
+ {
+ *pWMF >> nDat32;
+ pOut->SetBkMode( nDat32 );
+ }
+ break;
+
+ case EMR_SETPOLYFILLMODE :
+ break;
+
+ case EMR_SETROP2 :
+ {
+ *pWMF >> nDat32;
+ pOut->SetRasterOp( nDat32 );
+ }
+ break;
+
+ case EMR_SETSTRETCHBLTMODE :
+ {
+ *pWMF >> nStretchBltMode;
+ }
+ break;
+
+ case EMR_SETTEXTALIGN :
+ {
+ *pWMF >> nDat32;
+ pOut->SetTextAlign( nDat32 );
+ }
+ break;
+
+ case EMR_SETTEXTCOLOR :
+ {
+ pOut->SetTextColor( ReadColor() );
+ }
+ break;
+
+ case EMR_SETBKCOLOR :
+ {
+ pOut->SetBkColor( ReadColor() );
+ }
+ break;
+
+ case EMR_OFFSETCLIPRGN :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->MoveClipRegion( Size( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_MOVETOEX :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->MoveTo( Point( nX32, nY32 ), bRecordPath );
+ }
+ break;
+
+ case EMR_INTERSECTCLIPRECT :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
+ pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
+ }
+ break;
+
+ case EMR_SAVEDC :
+ {
+ pOut->Push();
+ }
+ break;
+
+ case EMR_RESTOREDC :
+ {
+ pOut->Pop();
+ }
+ break;
+
+ case EMR_SETWORLDTRANSFORM :
+ {
+ XForm aTempXForm;
+ *pWMF >> aTempXForm;
+ pOut->SetWorldTransform( aTempXForm );
+ }
+ break;
+
+ case EMR_MODIFYWORLDTRANSFORM :
+ {
+ UINT32 nMode;
+ XForm aTempXForm;
+ *pWMF >> aTempXForm >> nMode;
+ pOut->ModifyWorldTransform( aTempXForm, nMode );
+ }
+ break;
+
+ case EMR_SELECTOBJECT :
+ {
+ *pWMF >> nIndex;
+ pOut->SelectObject( nIndex );
+ }
+ break;
+
+ case EMR_CREATEPEN :
+ {
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+
+ LineInfo aLineInfo;
+ UINT32 nStyle;
+ Size aSize;
+
+ *pWMF >> nStyle >> aSize.Width() >> aSize.Height();
+
+ if ( aSize.Width() )
+ aLineInfo.SetWidth( aSize.Width() );
+
+ BOOL bTransparent = FALSE;
+ UINT16 nDashCount = 0;
+ UINT16 nDotCount = 0;
+ switch( nStyle )
+ {
+ case PS_DASHDOTDOT :
+ nDotCount++;
+ case PS_DASHDOT :
+ nDashCount++;
+ case PS_DOT :
+ nDotCount++;
+ break;
+ case PS_DASH :
+ nDashCount++;
+ break;
+ case PS_NULL :
+ bTransparent = TRUE;
+ aLineInfo.SetStyle( LINE_NONE );
+ break;
+ default :
+ case PS_INSIDEFRAME :
+ case PS_SOLID :
+ aLineInfo.SetStyle( LINE_SOLID );
+ }
+ if ( nDashCount | nDotCount )
+ {
+ aLineInfo.SetStyle( LINE_DASH );
+ aLineInfo.SetDashCount( nDashCount );
+ aLineInfo.SetDotCount( nDotCount );
+ }
+ pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
+ }
+ }
+ break;
+
+ case EMR_EXTCREATEPEN :
+ {
+ sal_Int32 elpHatch;
+ sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries;
+ Color aColorRef;
+
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ *pWMF >> offBmi >> cbBmi >> offBits >> cbBits >> nStyle >> nWidth >> nBrushStyle;
+ aColorRef = ReadColor();
+ *pWMF >> elpHatch >> elpNumEntries;
+
+ LineInfo aLineInfo;
+ if ( nWidth )
+ aLineInfo.SetWidth( nWidth );
+
+ sal_Bool bTransparent = sal_False;
+ sal_uInt16 nDashCount = 0;
+ sal_uInt16 nDotCount = 0;
+
+ switch( nStyle & PS_STYLE_MASK )
+ {
+ case PS_DASHDOTDOT :
+ nDotCount++;
+ case PS_DASHDOT :
+ nDashCount++;
+ case PS_DOT :
+ nDotCount++;
+ break;
+ case PS_DASH :
+ nDashCount++;
+ break;
+ case PS_NULL :
+ bTransparent = sal_True;
+ aLineInfo.SetStyle( LINE_NONE );
+ break;
+
+ default :
+ case PS_INSIDEFRAME :
+ case PS_SOLID :
+ aLineInfo.SetStyle( LINE_SOLID );
+ }
+ if ( nDashCount | nDotCount )
+ {
+ aLineInfo.SetStyle( LINE_DASH );
+ aLineInfo.SetDashCount( nDashCount );
+ aLineInfo.SetDotCount( nDotCount );
+ }
+ pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) );
+ }
+ }
+ break;
+
+ case EMR_CREATEBRUSHINDIRECT :
+ {
+ UINT32 nStyle;
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ *pWMF >> nStyle;
+ pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? TRUE : FALSE ) );
+ }
+ }
+ break;
+
+ case EMR_DELETEOBJECT :
+ {
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ pOut->DeleteObject( nIndex );
+ }
+ break;
+
+ case EMR_ELLIPSE :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
+ pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) );
+ }
+ break;
+
+ case EMR_RECTANGLE :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
+ pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
+ }
+ break;
+
+ case EMR_ROUNDRECT :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nW >> nH;
+ Size aSize( Size( nW, nH ) );
+ pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize );
+ }
+ break;
+
+ case EMR_ARC :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+ }
+ break;
+
+ case EMR_CHORD :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+ }
+ break;
+
+ case EMR_PIE :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 ));
+
+ // #i73608# OutputDevice deviates from WMF
+ // semantics. start==end means full ellipse here.
+ if( nStartX == nEndX && nStartY == nEndY )
+ pOut->DrawEllipse( aRect );
+ else
+ pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+ }
+ break;
+
+ case EMR_LINETO :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->LineTo( Point( nX32, nY32 ), bRecordPath );
+ }
+ break;
+
+ case EMR_ARCTO :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), TRUE );
+ }
+ break;
+
+ case EMR_BEGINPATH :
+ {
+ pOut->ClearPath();
+ bRecordPath = sal_True;
+ }
+ break;
+
+ case EMR_ABORTPATH :
+ pOut->ClearPath();
+ case EMR_ENDPATH :
+ bRecordPath = sal_False;
+ break;
+
+ case EMR_CLOSEFIGURE :
+ pOut->ClosePath();
+ break;
+
+ case EMR_FILLPATH :
+ pOut->StrokeAndFillPath( sal_False, sal_True );
+ break;
+
+ case EMR_STROKEANDFILLPATH :
+ pOut->StrokeAndFillPath( sal_True, sal_True );
+ break;
+
+ case EMR_STROKEPATH :
+ pOut->StrokeAndFillPath( sal_True, sal_False );
+ break;
+
+ case EMR_SELECTCLIPPATH :
+ {
+ sal_Int32 nClippingMode;
+ *pWMF >> nClippingMode;
+ pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, sal_True );
+ }
+ break;
+
+ case EMR_EXTSELECTCLIPRGN :
+ {
+ sal_Int32 iMode, cbRgnData;
+ *pWMF >> cbRgnData
+ >> iMode;
+
+ PolyPolygon aPolyPoly;
+ if ( cbRgnData )
+ ImplReadRegion( aPolyPoly, *pWMF, nRecSize );
+ pOut->SetClipPath( aPolyPoly, iMode, sal_False );
+ }
+ break;
+
+ case EMR_BITBLT : // PASSTHROUGH INTENDED
+ case EMR_STRETCHBLT :
+ {
+ INT32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
+ UINT32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
+ XForm xformSrc;
+
+ UINT32 nStart = pWMF->Tell() - 8;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc
+ >> xformSrc >> nColor >> iUsageSrc >> offBmiSrc >> cbBmiSrc
+ >> offBitsSrc >> cbBitsSrc;
+
+ if ( nRecType == EMR_STRETCHBLT )
+ *pWMF >> cxSrc >> cySrc;
+ else
+ cxSrc = cySrc = 0;
+
+ Bitmap aBitmap;
+ Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
+
+ cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative
+ cyDest = abs( (int)cyDest ); // and also 122889
+
+ if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
+ bStatus = FALSE;
+ else
+ {
+ UINT32 nSize = cbBmiSrc + cbBitsSrc + 14;
+ if ( nSize <= ( nEndPos - nStartPos ) )
+ {
+ char* pBuf = new char[ nSize ];
+ SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
+ aTmp.ObjectOwnsMemory( TRUE );
+ aTmp << (BYTE)'B'
+ << (BYTE)'M'
+ << (UINT32)cbBitsSrc
+ << (UINT16)0
+ << (UINT16)0
+ << (UINT32)cbBmiSrc + 14;
+ pWMF->Seek( nStart + offBmiSrc );
+ pWMF->Read( pBuf + 14, cbBmiSrc );
+ pWMF->Seek( nStart + offBitsSrc );
+ pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
+ aTmp.Seek( 0 );
+ aBitmap.Read( aTmp, TRUE );
+
+ // test if it is sensible to crop
+ if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
+ ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
+ ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
+ ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
+ {
+ Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
+ aBitmap.Crop( aCropRect );
+ }
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ }
+ }
+ }
+ break;
+
+ case EMR_STRETCHDIBITS :
+ {
+ INT32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
+ UINT32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
+ UINT32 nStart = pWMF->Tell() - 8;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc
+ >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest;
+
+ Bitmap aBitmap;
+ Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
+
+ cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative
+ cyDest = abs( (int)cyDest ); // and also 122889
+
+ if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
+ bStatus = FALSE;
+ else
+ {
+ UINT32 nSize = cbBmiSrc + cbBitsSrc + 14;
+ if ( nSize <= ( nEndPos - nStartPos ) )
+ {
+ char* pBuf = new char[ nSize ];
+ SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
+ aTmp.ObjectOwnsMemory( TRUE );
+ aTmp << (BYTE)'B'
+ << (BYTE)'M'
+ << (UINT32)cbBitsSrc
+ << (UINT16)0
+ << (UINT16)0
+ << (UINT32)cbBmiSrc + 14;
+ pWMF->Seek( nStart + offBmiSrc );
+ pWMF->Read( pBuf + 14, cbBmiSrc );
+ pWMF->Seek( nStart + offBitsSrc );
+ pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
+ aTmp.Seek( 0 );
+ aBitmap.Read( aTmp, TRUE );
+
+ // test if it is sensible to crop
+ if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
+ ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
+ ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
+ ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
+ {
+ Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
+ aBitmap.Crop( aCropRect );
+ }
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ }
+ }
+ }
+ break;
+
+ case EMR_EXTCREATEFONTINDIRECTW :
+ {
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ LOGFONTW aLogFont;
+ *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic
+ >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision
+ >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily;
+
+ sal_Unicode lfFaceName[ LF_FACESIZE ];
+
+ for ( int i = 0; i < LF_FACESIZE; i++ )
+ {
+ UINT16 nChar;
+ *pWMF >> nChar;
+ lfFaceName[ i ] = nChar;
+ }
+ aLogFont.alfFaceName = UniString( lfFaceName );
+ pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) );
+ }
+ }
+ break;
+
+ case EMR_EXTTEXTOUTA :
+ bFlag = sal_True;
+ case EMR_EXTTEXTOUTW :
+ {
+ sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
+ sal_uInt32 nCurPos, nLen, nOffString, nOptions, offDx;
+ sal_Int32* pDX = NULL;
+
+ nCurPos = pWMF->Tell() - 8;
+
+ *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale
+ >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> offDx;
+
+ sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT;
+ if ( nOptions & ETO_RTLREADING )
+ nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
+ pOut->SetTextLayoutMode( nTextLayoutMode );
+ DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" );
+
+ Point aPos( ptlReferenceX, ptlReferenceY );
+ if ( nLen && ( nLen < SAL_MAX_UINT32 / sizeof(sal_Int32) ) )
+ {
+ if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) )
+ {
+ pWMF->Seek( nCurPos + offDx );
+ if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ pDX = new sal_Int32[ nLen ];
+ sal_uInt32 i;
+ for ( i = 0; i < nLen; i++ )
+ *pWMF >> pDX[ i ];
+ }
+ }
+ pWMF->Seek( nCurPos + nOffString );
+ String aText;
+ if ( bFlag )
+ {
+ if ( nLen <= ( nEndPos - pWMF->Tell() ) )
+ {
+ sal_Char* pBuf = new sal_Char[ nLen ];
+ pWMF->Read( pBuf, nLen );
+ aText = String( pBuf, (sal_uInt16)nLen, pOut->GetCharSet() );
+ delete[] pBuf;
+
+ if ( aText.Len() != nLen )
+ {
+ sal_uInt16 i, j, k;
+ sal_Int32* pOldDx = pDX;
+ pDX = new sal_Int32[ aText.Len() ];
+ for ( i = 0, j = 0; i < aText.Len(); i++ )
+ {
+ ByteString aCharacter( aText.GetChar( i ), pOut->GetCharSet() );
+ pDX[ i ] = 0;
+ for ( k = 0; ( k < aCharacter.Len() ) && ( j < nLen ) && ( i < aText.Len() ); k++ )
+ pDX[ i ] += pOldDx[ j++ ];
+ }
+ delete[] pOldDx;
+ }
+ }
+ }
+ else
+ {
+ if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ sal_Unicode* pBuf = new sal_Unicode[ nLen ];
+ pWMF->Read( pBuf, nLen << 1 );
+#ifdef OSL_BIGENDIAN
+ sal_Char nTmp, *pTmp = (sal_Char*)( pBuf + nLen );
+ while ( pTmp-- != (sal_Char*)pBuf )
+ {
+ nTmp = *pTmp--;
+ pTmp[ 1 ] = *pTmp;
+ *pTmp = nTmp;
+ }
+#endif
+ aText = String( pBuf, (xub_StrLen)nLen );
+ delete[] pBuf;
+ }
+ }
+ pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode );
+ }
+ delete[] pDX;
+ }
+ break;
+
+ case EMR_POLYBEZIERTO16 :
+ bFlag = sal_True;
+ case EMR_POLYBEZIER16 :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ UINT16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+ Polygon aPoly( (UINT16)nPoints );
+ for( ; i < (UINT16)nPoints; i++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPoly[ i ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); // Line( aPoly, bFlag );
+ }
+ break;
+
+ case EMR_POLYGON16 :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ Polygon aPoly( (UINT16)nPoints );
+ for( UINT16 k = 0; k < (UINT16)nPoints; k++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPoly[ k ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolygon( aPoly, bRecordPath );
+ }
+ break;
+
+ case EMR_POLYLINETO16 :
+ bFlag = sal_True;
+ case EMR_POLYLINE16 :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ UINT16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+
+ Polygon aPoly( (UINT16)nPoints );
+ for( ; i < (UINT16)nPoints; i++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPoly[ i ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolyLine( aPoly, bFlag, bRecordPath );
+ }
+ break;
+
+ case EMR_POLYPOLYLINE16 :
+ {
+ UINT16* pnPoints;
+
+ INT32 i, nPoly, nGesPoints;
+ pWMF->SeekRel( 0x10 );
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> nGesPoints;
+
+ // taking the amount of points of each polygon, retrieving the total number of points
+ if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(UINT16) )
+ {
+ if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(UINT16) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ pnPoints = new UINT16[ nPoly ];
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+ // Polygonpunkte holen:
+ for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ )
+ {
+ Polygon aPolygon( pnPoints[ i ] );
+ for ( UINT16 k = 0; k < pnPoints[ i ]; k++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPolygon[ k ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath );
+ }
+ delete[] pnPoints;
+ }
+ }
+ }
+ break;
+
+ case EMR_POLYPOLYGON16 :
+ {
+ UINT16* pnPoints;
+ Point* pPtAry;
+
+ UINT32 i, nPoly, nGesPoints;
+ pWMF->SeekRel( 0x10 );
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> nGesPoints;
+ if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(UINT16) ) )
+ {
+ if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( UINT16 ) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ pnPoints = new UINT16[ nPoly ];
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+ if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) )
+ {
+ // Polygonpunkte holen:
+ pPtAry = new Point[ nGesPoints ];
+ for ( i = 0; i < nGesPoints; i++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ pPtAry[ i ] = Point( nX16, nY16 );
+ }
+
+ // PolyPolygon Actions erzeugen
+ PolyPolygon aPolyPoly( (UINT16)nPoly, pnPoints, pPtAry );
+ pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
+ delete[] pPtAry;
+ }
+ delete[] pnPoints;
+ }
+ }
+ }
+ break;
+
+ case EMR_FILLRGN :
+ {
+ sal_uInt32 nLen;
+ PolyPolygon aPolyPoly;
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> nLen >> nIndex;
+
+ if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) )
+ {
+ pOut->Push();
+ pOut->SelectObject( nIndex );
+ pOut->DrawPolyPolygon( aPolyPoly, sal_False );
+ pOut->Pop();
+ }
+ }
+ break;
+
+
+#ifdef WIN_MTF_ASSERT
+ default : WinMtfAssertHandler( "Unknown Meta Action" ); break;
+ case EMR_MASKBLT : WinMtfAssertHandler( "MaskBlt" ); break;
+ case EMR_PLGBLT : WinMtfAssertHandler( "PlgBlt" ); break;
+ case EMR_SETDIBITSTODEVICE : WinMtfAssertHandler( "SetDIBitsToDevice" ); break;
+ case EMR_FRAMERGN : WinMtfAssertHandler( "FrameRgn" ); break;
+ case EMR_INVERTRGN : WinMtfAssertHandler( "InvertRgn" ); break;
+ case EMR_PAINTRGN : WinMtfAssertHandler( "PaintRgn" ); break;
+ case EMR_FLATTENPATH : WinMtfAssertHandler( "FlattenPath" ); break;
+ case EMR_WIDENPATH : WinMtfAssertHandler( "WidenPath" ); break;
+ case EMR_POLYDRAW : WinMtfAssertHandler( "Polydraw" ); break;
+ case EMR_SETARCDIRECTION : WinMtfAssertHandler( "SetArcDirection" ); break;
+ case EMR_SETPALETTEENTRIES : WinMtfAssertHandler( "SetPaletteEntries" ); break;
+ case EMR_RESIZEPALETTE : WinMtfAssertHandler( "ResizePalette" ); break;
+ case EMR_EXTFLOODFILL : WinMtfAssertHandler( "ExtFloodFill" ); break;
+ case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break;
+ case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break;
+ case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break;
+ case EMR_CREATEDIBPATTERNBRUSHPT : WinMtfAssertHandler( "CreateDibPatternBrushPt" ); break;
+ case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break;
+ case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break;
+ case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break;
+ case EMR_SETCOLORSPACE : WinMtfAssertHandler( "SetColorSpace" ); break;
+ case EMR_DELETECOLORSPACE : WinMtfAssertHandler( "DeleteColorSpace" ); break;
+ case EMR_GLSRECORD : WinMtfAssertHandler( "GlsRecord" ); break;
+ case EMR_GLSBOUNDEDRECORD : WinMtfAssertHandler( "GlsBoundRecord" ); break;
+ case EMR_PIXELFORMAT : WinMtfAssertHandler( "PixelFormat" ); break;
+ case EMR_DRAWESCAPE : WinMtfAssertHandler( "DrawEscape" ); break;
+ case EMR_EXTESCAPE : WinMtfAssertHandler( "ExtEscape" ); break;
+ case EMR_STARTDOC : WinMtfAssertHandler( "StartDoc" ); break;
+ case EMR_SMALLTEXTOUT : WinMtfAssertHandler( "SmallTextOut" ); break;
+ case EMR_FORCEUFIMAPPING : WinMtfAssertHandler( "ForceUFIMapping" ); break;
+ case EMR_NAMEDESCAPE : WinMtfAssertHandler( "NamedEscape" ); break;
+ case EMR_COLORCORRECTPALETTE : WinMtfAssertHandler( "ColorCorrectPalette" ); break;
+ case EMR_SETICMPROFILEA : WinMtfAssertHandler( "SetICMProfileA" ); break;
+ case EMR_SETICMPROFILEW : WinMtfAssertHandler( "SetICMProfileW" ); break;
+ case EMR_ALPHABLEND : WinMtfAssertHandler( "Alphablend" ); break;
+ case EMR_TRANSPARENTBLT : WinMtfAssertHandler( "TransparenBlt" ); break;
+ case EMR_TRANSPARENTDIB : WinMtfAssertHandler( "TransparenDib" ); break;
+ case EMR_GRADIENTFILL : WinMtfAssertHandler( "GradientFill" ); break;
+ case EMR_SETLINKEDUFIS : WinMtfAssertHandler( "SetLinkedUFIS" ); break;
+
+ case EMR_SETMAPPERFLAGS : WinMtfAssertHandler( "SetMapperFlags", 0 ); break;
+ case EMR_SETICMMODE : WinMtfAssertHandler( "SetICMMode", 0 ); break;
+ case EMR_CREATEMONOBRUSH : WinMtfAssertHandler( "CreateMonoBrush", 0 ); break;
+ case EMR_SETBRUSHORGEX : WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break;
+ case EMR_SETMETARGN : WinMtfAssertHandler( "SetMetArgn", 0 ); break;
+ case EMR_SETMITERLIMIT : WinMtfAssertHandler( "SetMiterLimit", 0 ); break;
+ case EMR_EXCLUDECLIPRECT : WinMtfAssertHandler( "ExcludeClipRect", 0 ); break;
+ case EMR_REALIZEPALETTE : WinMtfAssertHandler( "RealizePalette", 0 ); break;
+ case EMR_SELECTPALETTE : WinMtfAssertHandler( "SelectPalette", 0 ); break;
+ case EMR_CREATEPALETTE : WinMtfAssertHandler( "CreatePalette", 0 ); break;
+ case EMR_ALPHADIBBLEND : WinMtfAssertHandler( "AlphaDibBlend", 0 ); break;
+ case EMR_SETTEXTJUSTIFICATION : WinMtfAssertHandler( "SetTextJustification", 0 ); break;
+
+ case EMR_GDICOMMENT :
+ case EMR_HEADER : // has already been read at ReadHeader()
+ break;
+#endif
+ }
+ pWMF->Seek( nNextPos );
+ }
+ if( aBmpSaveList.Count() )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+
+ if ( bStatus )
+ pWMF->Seek(nEndPos);
+
+ return bStatus;
+};
+
+//-----------------------------------------------------------------------------------
+
+BOOL EnhWMFReader::ReadHeader()
+{
+ UINT32 nUINT32, nHeaderSize, nPalEntries;
+ INT32 nLeft, nTop, nRight, nBottom;
+
+ // METAFILEHEADER SPARE ICH MIR HIER
+ // Einlesen des METAHEADER
+ *pWMF >> nUINT32 >> nHeaderSize;
+ if ( nUINT32 != 1 ) // Typ
+ return FALSE;
+
+ // bound size
+ Rectangle rclBounds; // rectangle in logical units 1/100th mm
+ *pWMF >> nLeft >> nTop >> nRight >> nBottom;
+ rclBounds.Left() = nLeft;
+ rclBounds.Top() = nTop;
+ rclBounds.Right() = nRight;
+ rclBounds.Bottom() = nBottom;
+
+ // picture frame size
+ Rectangle rclFrame; // rectangle in device units
+ *pWMF >> nLeft >> nTop >> nRight >> nBottom;
+ rclFrame.Left() = nLeft;
+ rclFrame.Top() = nTop;
+ rclFrame.Right() = nRight;
+ rclFrame.Bottom() = nBottom;
+
+ *pWMF >> nUINT32; // signature
+
+ if ( nUINT32 != 0x464d4520 )
+ return FALSE;
+
+ *pWMF >> nUINT32; // nVersion
+ *pWMF >> nEndPos; // size of metafile
+ nEndPos += nStartPos;
+
+ sal_uInt32 nStrmPos = pWMF->Tell(); // checking if nEndPos is valid
+ pWMF->Seek( STREAM_SEEK_TO_END );
+ if ( pWMF->Tell() < nEndPos )
+ nEndPos = pWMF->Tell();
+ pWMF->Seek( nStrmPos );
+
+ *pWMF >> nRecordCount;
+
+ if ( !nRecordCount )
+ return FALSE;
+
+ pWMF->SeekRel( 0xc );
+
+ sal_Int32 nPixX, nPixY, nMillX, nMillY;
+ *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY;
+
+ pOut->SetrclFrame( rclFrame );
+ pOut->SetrclBounds( rclBounds );
+ pOut->SetRefPix( Size( nPixX, nPixY ) );
+ pOut->SetRefMill( Size( nMillX, nMillY ) );
+
+ pWMF->Seek( nStartPos + nHeaderSize );
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------------
+
+Rectangle EnhWMFReader::ReadRectangle( INT32 x1, INT32 y1, INT32 x2, INT32 y2 )
+{
+ Point aTL ( Point( x1, y1 ) );
+ Point aBR( Point( --x2, --y2 ) );
+ return Rectangle( aTL, aBR );
+}
+
+EnhWMFReader::~EnhWMFReader()
+{
+
+};
+
diff --git a/svtools/source/filter.vcl/wmf/makefile.mk b/svtools/source/filter.vcl/wmf/makefile.mk
new file mode 100644
index 000000000000..5c9412bc8387
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=svtools
+TARGET=wmf
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/wmf.obj \
+ $(SLO)$/winmtf.obj \
+ $(SLO)$/winwmf.obj \
+ $(SLO)$/enhwmf.obj \
+ $(SLO)$/emfwr.obj \
+ $(SLO)$/wmfwr.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
new file mode 100644
index 000000000000..787e6522b890
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -0,0 +1,2203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+
+#include "winmtf.hxx"
+#include <vcl/metaact.hxx>
+#include <vcl/metric.hxx>
+#include <rtl/tencinfo.h>
+
+// ------------------------------------------------------------------------
+
+#define WIN_MTF_MAX_CLIP_DEPTH 16
+
+void WinMtfClipPath::ImpUpdateType()
+{
+ if ( !aPolyPoly.Count() )
+ eType = EMPTY;
+ else if ( aPolyPoly.IsRect() )
+ eType = RECTANGLE;
+ else
+ eType = COMPLEX;
+
+ bNeedsUpdate = sal_True;
+}
+
+void WinMtfClipPath::IntersectClipRect( const Rectangle& rRect )
+{
+ if ( !aPolyPoly.Count() )
+ aPolyPoly = Polygon( rRect );
+ else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH )
+ {
+ Polygon aPolygon( rRect );
+ PolyPolygon aIntersection;
+ PolyPolygon aPolyPolyRect( aPolygon );
+ aPolyPoly.GetIntersection( aPolyPolyRect, aIntersection );
+ aPolyPoly = aIntersection;
+ nDepth++;
+ }
+ ImpUpdateType();
+}
+
+void WinMtfClipPath::ExcludeClipRect( const Rectangle& rRect )
+{
+ if ( aPolyPoly.Count() && ( nDepth < WIN_MTF_MAX_CLIP_DEPTH ) )
+ {
+ Polygon aPolygon( rRect );
+ PolyPolygon aPolyPolyRect( aPolygon );
+ PolyPolygon aDifference;
+ aPolyPoly.GetDifference( aPolyPolyRect, aDifference );
+ aPolyPoly = aDifference;
+ nDepth++;
+ }
+ ImpUpdateType();
+}
+
+void WinMtfClipPath::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
+{
+ if ( !rPolyPolygon.Count() )
+ aPolyPoly = rPolyPolygon;
+ else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH )
+ {
+ nDepth++;
+
+ PolyPolygon aNewClipPath;
+
+ // #115345# Watch out for empty aPolyPoly here - conceptually,
+ // an empty clip path is a rectangle of infinite size, but it
+ // is represented by an empty aPolyPoly. When intersecting
+ // rPolyPolygon with this _empty_ aPolyPoly, set algebra
+ // guarantees wrong results.
+ switch ( nClippingMode )
+ {
+ case RGN_OR :
+ // #115345# clip stays empty, when ORing an arbitrary
+ // rPolyPolygon. Thus, we can save us the unnecessary
+ // clipper call.
+ if( aPolyPoly.Count() )
+ aPolyPoly.GetUnion( rPolyPolygon, aNewClipPath );
+ break;
+ case RGN_XOR :
+ // TODO:
+ // #115345# Cannot handle this case, for the time being
+ aPolyPoly.GetXOR( rPolyPolygon, aNewClipPath );
+ break;
+ case RGN_DIFF :
+ // TODO:
+ // #115345# Cannot handle this case, for the time being
+ aPolyPoly.GetDifference( rPolyPolygon, aNewClipPath );
+ break;
+ case RGN_AND :
+ // #115345# Clip becomes rPolyPolygon, when ANDing
+ // with an arbitrary rPolyPolygon
+ if( aPolyPoly.Count() )
+ aPolyPoly.GetIntersection( rPolyPolygon, aNewClipPath );
+ else
+ aNewClipPath = rPolyPolygon;
+ break;
+ case RGN_COPY :
+ aNewClipPath = rPolyPolygon;
+ break;
+ }
+ aPolyPoly = aNewClipPath;
+ }
+ ImpUpdateType();
+}
+
+void WinMtfClipPath::MoveClipRegion( const Size& rSize )
+{
+ aPolyPoly.Move( rSize.Width(), rSize.Height() );
+ bNeedsUpdate = sal_True;
+}
+
+// ------------------------------------------------------------------------
+
+void WinMtfPathObj::AddPoint( const Point& rPoint )
+{
+ if ( bClosed )
+ Insert( Polygon(), POLYPOLY_APPEND );
+ Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
+ rPoly.Insert( rPoly.GetSize(), rPoint, POLY_NORMAL );
+ bClosed = sal_False;
+}
+
+void WinMtfPathObj::AddPolyLine( const Polygon& rPolyLine )
+{
+ if ( bClosed )
+ Insert( Polygon(), POLYPOLY_APPEND );
+ Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
+ rPoly.Insert( rPoly.GetSize(), rPolyLine );
+ bClosed = sal_False;
+}
+
+void WinMtfPathObj::AddPolygon( const Polygon& rPoly )
+{
+ Insert( rPoly, POLYPOLY_APPEND );
+ bClosed = sal_True;
+}
+
+void WinMtfPathObj::AddPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+ sal_uInt16 i, nCount = rPolyPoly.Count();
+ for ( i = 0; i < nCount; i++ )
+ Insert( rPolyPoly[ i ], POLYPOLY_APPEND );
+ bClosed = sal_True;
+}
+
+void WinMtfPathObj::ClosePath()
+{
+ if ( Count() )
+ {
+ Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
+ if ( rPoly.GetSize() > 2 )
+ {
+ Point aFirst( rPoly[ 0 ] );
+ if ( aFirst != rPoly[ rPoly.GetSize() - 1 ] )
+ rPoly.Insert( rPoly.GetSize(), aFirst, POLY_NORMAL );
+ }
+ }
+ bClosed = sal_True;
+}
+
+// ------------------------------------------------------------------------
+
+WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
+{
+ CharSet eCharSet;
+ if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) )
+ eCharSet = gsl_getSystemTextEncoding();
+ else
+ eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet );
+ if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
+ eCharSet = gsl_getSystemTextEncoding();
+ aFont.SetCharSet( eCharSet );
+ aFont.SetName( rFont.alfFaceName );
+ FontFamily eFamily;
+ switch ( rFont.lfPitchAndFamily & 0xf0 )
+ {
+ case FF_ROMAN:
+ eFamily = FAMILY_ROMAN;
+ break;
+
+ case FF_SWISS:
+ eFamily = FAMILY_SWISS;
+ break;
+
+ case FF_MODERN:
+ eFamily = FAMILY_MODERN;
+ break;
+
+ case FF_SCRIPT:
+ eFamily = FAMILY_SCRIPT;
+ break;
+
+ case FF_DECORATIVE:
+ eFamily = FAMILY_DECORATIVE;
+ break;
+
+ default:
+ eFamily = FAMILY_DONTKNOW;
+ break;
+ }
+ aFont.SetFamily( eFamily );
+
+ FontPitch ePitch;
+ switch ( rFont.lfPitchAndFamily & 0x0f )
+ {
+ case FIXED_PITCH:
+ ePitch = PITCH_FIXED;
+ break;
+
+ case DEFAULT_PITCH:
+ case VARIABLE_PITCH:
+ default:
+ ePitch = PITCH_VARIABLE;
+ break;
+ }
+ aFont.SetPitch( ePitch );
+
+ FontWeight eWeight;
+ if( rFont.lfWeight <= FW_THIN )
+ eWeight = WEIGHT_THIN;
+ else if( rFont.lfWeight <= FW_ULTRALIGHT )
+ eWeight = WEIGHT_ULTRALIGHT;
+ else if( rFont.lfWeight <= FW_LIGHT )
+ eWeight = WEIGHT_LIGHT;
+ else if( rFont.lfWeight < FW_MEDIUM )
+ eWeight = WEIGHT_NORMAL;
+ else if( rFont.lfWeight == FW_MEDIUM )
+ eWeight = WEIGHT_MEDIUM;
+ else if( rFont.lfWeight <= FW_SEMIBOLD )
+ eWeight = WEIGHT_SEMIBOLD;
+ else if( rFont.lfWeight <= FW_BOLD )
+ eWeight = WEIGHT_BOLD;
+ else if( rFont.lfWeight <= FW_ULTRABOLD )
+ eWeight = WEIGHT_ULTRABOLD;
+ else
+ eWeight = WEIGHT_BLACK;
+ aFont.SetWeight( eWeight );
+
+ if( rFont.lfItalic )
+ aFont.SetItalic( ITALIC_NORMAL );
+
+ if( rFont.lfUnderline )
+ aFont.SetUnderline( UNDERLINE_SINGLE );
+
+ if( rFont.lfStrikeOut )
+ aFont.SetStrikeout( STRIKEOUT_SINGLE );
+
+ if ( rFont.lfOrientation )
+ aFont.SetOrientation( (short)rFont.lfOrientation );
+ else
+ aFont.SetOrientation( (short)rFont.lfEscapement );
+
+ Size aFontSize( Size( rFont.lfWidth, rFont.lfHeight ) );
+ if ( rFont.lfHeight > 0 )
+ {
+ // converting the cell height into a font height
+ VirtualDevice aVDev;
+ aFont.SetSize( aFontSize );
+ aVDev.SetFont( aFont );
+ FontMetric aMetric( aVDev.GetFontMetric() );
+ long nHeight = aMetric.GetAscent() + aMetric.GetDescent();
+ if ( nHeight )
+ {
+ double fHeight = ((double)aFontSize.Height() * rFont.lfHeight ) / nHeight;
+ aFontSize.Height() = (sal_Int32)( fHeight + 0.5 );
+ }
+ }
+ else if ( aFontSize.Height() < 0 )
+ aFontSize.Height() *= -1;
+
+ if ( !rFont.lfWidth )
+ {
+ VirtualDevice aVDev;
+ aFont.SetSize( aFontSize );
+ aVDev.SetFont( aFont );
+ FontMetric aMetric( aVDev.GetFontMetric() );
+ aFontSize.Width() = aMetric.GetWidth();
+ }
+
+ aFont.SetSize( aFontSize );
+};
+
+// ------------------------------------------------------------------------
+
+#ifdef WIN_MTF_ASSERT
+void WinMtfAssertHandler( const sal_Char* pAction, sal_uInt32 nFlags )
+{
+ static sal_Bool bOnlyOnce;
+ static sal_Int32 nAssertCount;
+
+ if ( nFlags & WIN_MTF_ASSERT_INIT )
+ nAssertCount = 0;
+ if ( nFlags & WIN_MTF_ASSERT_ONCE )
+ bOnlyOnce = sal_True;
+ if ( nFlags & WIN_MTF_ASSERT_MIFE )
+ {
+ if ( ( nAssertCount == 0 ) || ( bOnlyOnce == sal_False ) )
+ {
+ ByteString aText( "WMF/EMF Import: " );
+ if ( pAction )
+ {
+ ByteString aAction( pAction );
+ aText.Append( aAction );
+ }
+ aText.Append( " needs to be implemented (SJ)" );
+ DBG_ASSERT( 0, aText.GetBuffer() );
+ }
+ nAssertCount++;
+ }
+}
+#endif
+
+// ------------------------------------------------------------------------
+
+WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, FilterConfigItem* pConfigItem ) :
+ pOut ( pWinMtfOutput ),
+ pWMF ( &rStreamWMF ),
+ pFilterConfigItem ( pConfigItem )
+{
+#ifdef WIN_MTF_ASSERT
+ // we want to assert not implemented features, but we do this
+ // only once, so that nobody is handicaped by getting too much assertions
+ // I hope this will bring more testdocuments, without support of these
+ // testdocuments the implementation of missing features won't be possible. (SJ)
+ WinMtfAssertHandler( NULL, WIN_MTF_ASSERT_INIT | WIN_MTF_ASSERT_ONCE );
+#endif
+
+ SvLockBytes *pLB = pWMF->GetLockBytes();
+ if ( pLB )
+ pLB->SetSynchronMode( TRUE );
+
+ nStartPos = pWMF->Tell();
+
+ pOut->SetDevOrg( Point() );
+ if ( pFilterConfigItem )
+ {
+ xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
+ if ( xStatusIndicator.is() )
+ {
+ rtl::OUString aMsg;
+ xStatusIndicator->start( aMsg, 100 );
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+WinMtf::~WinMtf()
+{
+ delete pOut;
+
+ if ( xStatusIndicator.is() )
+ xStatusIndicator->end();
+}
+
+// ------------------------------------------------------------------------
+
+void WinMtf::Callback( USHORT nPercent )
+{
+ if ( xStatusIndicator.is() )
+ xStatusIndicator->setValue( nPercent );
+}
+
+// ------------------------------------------------------------------------
+
+Color WinMtf::ReadColor()
+{
+ UINT32 nColor;
+ *pWMF >> nColor;
+ return Color( (BYTE)nColor, (BYTE)( nColor >> 8 ), (BYTE)( nColor >> 16 ) );
+};
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+Point WinMtfOutput::ImplMap( const Point& rPt )
+{
+ if ( mnWinExtX && mnWinExtY )
+ {
+ double fX2, fX = rPt.X();
+ double fY2, fY = rPt.Y();
+
+ fX2 = fX * maXForm.eM11 + fY * maXForm.eM21 + maXForm.eDx;
+ fY2 = fX * maXForm.eM12 + fY * maXForm.eM22 + maXForm.eDy;
+
+ if ( mnGfxMode == GM_COMPATIBLE )
+ {
+ switch( mnMapMode )
+ {
+ case MM_LOENGLISH :
+ {
+ fX2 -= mnWinOrgX;
+ fY2 = mnWinOrgY-fY2;
+ fX2 *= 25.40;
+ fY2 *= 25.40;
+ fX2 += mnDevOrgX;
+ fY2 += mnDevOrgY;
+ }
+ break;
+ case MM_HIENGLISH :
+ {
+ fX2 -= mnWinOrgX;
+ fY2 = mnWinOrgY-fY2;
+ fX2 *= 2.540;
+ fY2 *= 2.540;
+ fX2 += mnDevOrgX;
+ fY2 += mnDevOrgY;
+ }
+ break;
+ case MM_LOMETRIC :
+ {
+ fX2 -= mnWinOrgX;
+ fY2 = mnWinOrgY-fY2;
+ fX2 *= 10;
+ fY2 *= 10;
+ fX2 += mnDevOrgX;
+ fY2 += mnDevOrgY;
+ }
+ break;
+ case MM_HIMETRIC :
+ {
+ fX2 -= mnWinOrgX;
+ fY2 = mnWinOrgY-fY2;
+ fX2 += mnDevOrgX;
+ fY2 += mnDevOrgY;
+ }
+ break;
+ default :
+ {
+ fX2 -= mnWinOrgX;
+ fY2 -= mnWinOrgY;
+ fX2 /= mnWinExtX;
+ fY2 /= mnWinExtY;
+ fX2 *= mnDevWidth;
+ fY2 *= mnDevHeight;
+ fX2 += mnDevOrgX;
+ fY2 += mnDevOrgY; // fX2, fY2 now in device units
+ fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
+ fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
+ }
+ break;
+ }
+ fX2 -= mrclFrame.Left();
+ fY2 -= mrclFrame.Top();
+ }
+ return Point( FRound( fX2 ), FRound( fY2 ) );
+ }
+ else
+ return Point();
+};
+
+// ------------------------------------------------------------------------
+
+Size WinMtfOutput::ImplMap( const Size& rSz )
+{
+ if ( mnWinExtX && mnWinExtY )
+ {
+ double fWidth = rSz.Width() * maXForm.eM11;
+ double fHeight = rSz.Height() * maXForm.eM22;
+
+ if ( mnGfxMode == GM_COMPATIBLE )
+ {
+ switch( mnMapMode )
+ {
+ case MM_LOENGLISH :
+ {
+ fWidth *= 25.40;
+ fHeight*=-25.40;
+ }
+ break;
+ case MM_HIENGLISH :
+ {
+ fWidth *= 2.540;
+ fHeight*=-2.540;
+ }
+ break;
+ case MM_LOMETRIC :
+ {
+ fWidth *= 10;
+ fHeight*=-10;
+ }
+ break;
+ case MM_HIMETRIC :
+ {
+ fHeight *= -1;
+ }
+ break;
+ default :
+ {
+ fWidth /= mnWinExtX;
+ fHeight /= mnWinExtY;
+ fWidth *= mnDevWidth;
+ fHeight *= mnDevHeight;
+ fWidth *= (double)mnMillX * 100 / (double)mnPixX;
+ fHeight *= (double)mnMillY * 100 / (double)mnPixY;
+ }
+ break;
+ }
+ }
+ return Size( FRound( fWidth ), FRound( fHeight ) );
+ }
+ else
+ return Size();
+}
+
+//-----------------------------------------------------------------------------------
+
+Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
+{
+ return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplMap( Font& rFont )
+{
+ // !!! HACK: Wir setzen die Breite jetzt immer auf Null,
+ // da OS die Breite unterschiedlich interpretieren;
+ // muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
+ Size aFontSize = ImplMap ( rFont.GetSize() );
+
+ if( aFontSize.Height() < 0 )
+ aFontSize.Height() *= -1;
+
+ rFont.SetSize( aFontSize );
+
+ if( ( mnWinExtX * mnWinExtY ) < 0 )
+ rFont.SetOrientation( 3600 - rFont.GetOrientation() );
+}
+
+//-----------------------------------------------------------------------------------
+
+Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
+{
+ UINT16 nPoints = rPolygon.GetSize();
+ for ( UINT16 i = 0; i < nPoints; i++ )
+ {
+ rPolygon[ i ] = ImplMap( rPolygon[ i ] );
+ }
+ return rPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
+{
+ UINT16 nPolys = rPolyPolygon.Count();
+ for ( UINT16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) ) ;
+ return rPolyPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SelectObject( INT32 nIndex )
+{
+ GDIObj* pGDIObj = NULL;
+
+ if ( nIndex & ENHMETA_STOCK_OBJECT )
+ pGDIObj = new GDIObj();
+ else
+ {
+ nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
+
+ if ( (UINT32)nIndex < vGDIObj.size() )
+ pGDIObj = vGDIObj[ nIndex ];
+ }
+
+ if( pGDIObj == NULL )
+ return;
+
+ if ( nIndex & ENHMETA_STOCK_OBJECT )
+ {
+ UINT16 nStockId = (BYTE)nIndex;
+ switch( nStockId )
+ {
+ case WHITE_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
+ }
+ break;
+ case LTGRAY_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
+ }
+ break;
+ case GRAY_BRUSH :
+ case DKGRAY_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
+ }
+ break;
+ case BLACK_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
+ }
+ break;
+ case NULL_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), TRUE ) );
+ }
+ break;
+ case WHITE_PEN :
+ {
+ pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_WHITE ) ) );
+ }
+ break;
+ case BLACK_PEN :
+ {
+ pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
+ }
+ break;
+ case NULL_PEN :
+ {
+ pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), TRUE ) );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if ( pGDIObj->pStyle )
+ {
+ switch( pGDIObj->eType )
+ {
+ case GDI_PEN :
+ maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
+ break;
+ case GDI_BRUSH :
+ {
+ maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
+ mbFillStyleSelected = sal_True;
+ }
+ break;
+ case GDI_FONT :
+ maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
+ break;
+ default:
+ break; // -Wall many options not handled.
+ }
+ }
+ if ( nIndex & ENHMETA_STOCK_OBJECT )
+ delete pGDIObj;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetFont( const Font& rFont )
+{
+ maFont = rFont;
+}
+
+//-----------------------------------------------------------------------------------
+
+const Font& WinMtfOutput::GetFont() const
+{
+ return maFont;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode )
+{
+ mnTextLayoutMode = nTextLayoutMode;
+}
+
+//-----------------------------------------------------------------------------------
+
+sal_uInt32 WinMtfOutput::GetTextLayoutMode() const
+{
+ return mnTextLayoutMode;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetBkMode( UINT32 nMode )
+{
+ mnBkMode = nMode;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetBkColor( const Color& rColor )
+{
+ maBkColor = rColor;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetTextColor( const Color& rColor )
+{
+ maTextColor = rColor;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetTextAlign( UINT32 nAlign )
+{
+ mnTextAlign = nAlign;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplResizeObjectArry( UINT32 nNewEntrys )
+{
+ sal_uInt32 i = vGDIObj.size();
+ vGDIObj.resize( nNewEntrys );
+ for ( ; i < nNewEntrys ; i++ )
+ vGDIObj[ i ] = NULL;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+ if ( rPolyPoly.Count() )
+ {
+ ImplSetNonPersistentLineColorTransparenz();
+ if ( rPolyPoly.Count() == 1 )
+ {
+ if ( rPolyPoly.IsRect() )
+ mpGDIMetaFile->AddAction( new MetaRectAction( rPolyPoly.GetBoundRect() ) );
+ else
+ {
+ Polygon aPoly( rPolyPoly[ 0 ] );
+ sal_uInt16 nCount = aPoly.GetSize();
+ if ( nCount )
+ {
+ if ( aPoly[ nCount - 1 ] != aPoly[ 0 ] )
+ {
+ Point aPoint( aPoly[ 0 ] );
+ aPoly.Insert( nCount, aPoint );
+ }
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
+ }
+ }
+ }
+ else
+ mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
+ }
+}
+
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
+{
+ if ( pStyle )
+ {
+ if ( eType == GDI_FONT )
+ {
+ ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
+ if (!((WinMtfFontStyle*)pStyle)->aFont.GetHeight() )
+ ((WinMtfFontStyle*)pStyle)->aFont.SetHeight( 423 ); // defaulting to 12pt
+ }
+ else if ( eType == GDI_PEN )
+ {
+ Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
+ if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
+ {
+ aSize.Width() += 1;
+ long nDotLen = ImplMap( aSize ).Width();
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
+ }
+ }
+ }
+ UINT32 nIndex;
+ for ( nIndex = 0; nIndex < vGDIObj.size(); nIndex++ )
+ {
+ if ( vGDIObj[ nIndex ] == NULL )
+ break;
+ }
+ if ( nIndex == vGDIObj.size() )
+ ImplResizeObjectArry( vGDIObj.size() + 16 );
+
+ vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::CreateObject( INT32 nIndex, GDIObjectType eType, void* pStyle )
+{
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
+ if ( pStyle )
+ {
+ if ( eType == GDI_FONT )
+ ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
+ else if ( eType == GDI_PEN )
+ {
+ Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
+ if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
+ {
+ aSize.Width() += 1;
+ long nDotLen = ImplMap( aSize ).Width();
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
+ }
+ }
+ }
+ if ( (UINT32)nIndex >= vGDIObj.size() )
+ ImplResizeObjectArry( nIndex + 16 );
+
+ if ( vGDIObj[ nIndex ] != NULL )
+ delete vGDIObj[ nIndex ];
+
+ vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
+ }
+ else
+ {
+ switch ( eType )
+ {
+ case GDI_PEN :
+ delete (WinMtfLineStyle*)pStyle;
+ break;
+ case GDI_BRUSH :
+ delete (WinMtfFillStyle*)pStyle;
+ break;
+ case GDI_FONT :
+ delete (WinMtfFontStyle*)pStyle;
+ break;
+
+ default:
+ DBG_ERROR( "unsupported style not deleted" );
+ break;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
+{
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ if ( (sal_uInt32)nIndex < vGDIObj.size() )
+ {
+ delete vGDIObj[ nIndex ];
+ vGDIObj[ nIndex ] = NULL;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
+{
+ aClipPath.IntersectClipRect( ImplMap( rRect ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ExcludeClipRect( const Rectangle& rRect )
+{
+ aClipPath.ExcludeClipRect( ImplMap( rRect ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::MoveClipRegion( const Size& rSize )
+{
+ aClipPath.MoveClipRegion( ImplMap( rSize ) );
+}
+
+void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool bIsMapped )
+{
+ if ( bIsMapped )
+ aClipPath.SetClipPath( rPolyPolygon, nClippingMode );
+ else
+ {
+ PolyPolygon aPP( rPolyPolygon );
+ aClipPath.SetClipPath( ImplMap( aPP ), nClippingMode );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
+ mnLatestTextAlign ( 0 ),
+ mnTextAlign ( TA_LEFT | TA_TOP | TA_NOUPDATECP ),
+ maLatestBkColor ( 0x12345678 ),
+ maBkColor ( COL_WHITE ),
+ mnLatestTextLayoutMode( TEXT_LAYOUT_DEFAULT ),
+ mnTextLayoutMode ( TEXT_LAYOUT_DEFAULT ),
+ mnLatestBkMode ( 0 ),
+ mnBkMode ( OPAQUE ),
+ meLatestRasterOp ( ROP_INVERT ),
+ meRasterOp ( ROP_OVERPAINT ),
+ maActPos ( Point() ),
+ mbNopMode ( sal_False ),
+ mbFillStyleSelected ( sal_False ),
+ mnGfxMode ( GM_COMPATIBLE ),
+ mnMapMode ( MM_TEXT ),
+ mnDevOrgX ( 0 ),
+ mnDevOrgY ( 0 ),
+ mnDevWidth ( 1 ),
+ mnDevHeight ( 1 ),
+ mnWinOrgX ( 0 ),
+ mnWinOrgY ( 0 ),
+ mnWinExtX ( 1 ),
+ mnWinExtY ( 1 ),
+ mnPixX ( 100 ),
+ mnPixY ( 100 ),
+ mnMillX ( 1 ),
+ mnMillY ( 1 ),
+ mpGDIMetaFile ( &rGDIMetaFile )
+{
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); // The original clipregion has to be on top
+ // of the stack so it can always be restored
+ // this is necessary to be able to support
+ // SetClipRgn( NULL ) and similar ClipRgn actions (SJ)
+
+ maFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Arial" )) ); // sj: #i57205#, we do have some scaling problems if using
+ maFont.SetCharSet( gsl_getSystemTextEncoding() ); // the default font then most times a x11 font is used, we
+ maFont.SetHeight( 423 ); // will prevent this defining a font
+
+ maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
+ maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );
+
+ mnRop = R2_BLACK + 1;
+ SetRasterOp( R2_BLACK );
+};
+
+//-----------------------------------------------------------------------------------
+
+WinMtfOutput::~WinMtfOutput()
+{
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
+ if ( mrclFrame.IsEmpty() )
+ mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
+ else
+ mpGDIMetaFile->SetPrefSize( mrclFrame.GetSize() );
+
+ for ( UINT32 i = 0; i < vGDIObj.size(); i++ )
+ delete vGDIObj[ i ];
+};
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::UpdateClipRegion()
+{
+ if ( aClipPath.bNeedsUpdate )
+ {
+ aClipPath.bNeedsUpdate = sal_False;
+
+ mpGDIMetaFile->AddAction( new MetaPopAction() ); // taking the orignal clipregion
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); //
+
+ switch ( aClipPath.GetType() )
+ {
+ case RECTANGLE :
+ case COMPLEX :
+ {
+// we will not generate a RegionClipRegion Action, because this action
+// cannot be saved to the wmf format - saving to wmf always happens
+// if the placeholder graphic for ole objects is generated. (SJ)
+
+// Region aClipRegion( aClipPath.GetClipPath() );
+// mpGDIMetaFile->AddAction( new MetaISectRegionClipRegionAction( aClipRegion ) );
+
+ Rectangle aClipRect( aClipPath.GetClipPath().GetBoundRect() );
+ mpGDIMetaFile->AddAction( new MetaISectRectClipRegionAction( aClipRect ) );
+ }
+ break;
+ case EMPTY:
+ break; // -Wall not handled.
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
+{
+ Color aColor( COL_TRANSPARENT);
+ WinMtfLineStyle aTransparentLine( aColor, TRUE );
+ if ( ! ( maLatestLineStyle == aTransparentLine ) )
+ {
+ maLatestLineStyle = aTransparentLine;
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( aTransparentLine.aLineColor, !aTransparentLine.bTransparent ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::UpdateLineStyle()
+{
+ if (!( maLatestLineStyle == maLineStyle ) )
+ {
+ maLatestLineStyle = maLineStyle;
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::UpdateFillStyle()
+{
+ if ( !mbFillStyleSelected ) // SJ: #i57205# taking care of bkcolor if no brush is selected
+ maFillStyle = WinMtfFillStyle( maBkColor, mnBkMode == TRANSPARENT );
+ if (!( maLatestFillStyle == maFillStyle ) )
+ {
+ maLatestFillStyle = maFillStyle;
+ mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+sal_uInt32 WinMtfOutput::SetRasterOp( UINT32 nRasterOp )
+{
+ sal_uInt32 nRetROP = mnRop;
+ if ( nRasterOp != mnRop )
+ {
+ mnRop = nRasterOp;
+ static WinMtfFillStyle aNopFillStyle;
+ static WinMtfLineStyle aNopLineStyle;
+
+ if ( mbNopMode && ( nRasterOp != R2_NOP ) )
+ { // beim uebergang von R2_NOP auf anderen Modus
+ // gesetzten Pen und Brush aktivieren
+ maFillStyle = aNopFillStyle;
+ maLineStyle = aNopLineStyle;
+ mbNopMode = sal_False;
+ }
+ switch( nRasterOp )
+ {
+ case R2_NOT:
+ meRasterOp = ROP_INVERT;
+ break;
+
+ case R2_XORPEN:
+ meRasterOp = ROP_XOR;
+ break;
+
+ case R2_NOP:
+ {
+ meRasterOp = ROP_OVERPAINT;
+ if( mbNopMode == sal_False )
+ {
+ aNopFillStyle = maFillStyle;
+ aNopLineStyle = maLineStyle;
+ maFillStyle = WinMtfFillStyle( Color( COL_TRANSPARENT ), TRUE );
+ maLineStyle = WinMtfLineStyle( Color( COL_TRANSPARENT ), TRUE );
+ mbNopMode = sal_True;
+ }
+ }
+ break;
+
+ default:
+ meRasterOp = ROP_OVERPAINT;
+ break;
+ }
+ }
+ if ( nRetROP != nRasterOp )
+ mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
+ return nRetROP;
+};
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::StrokeAndFillPath( sal_Bool bStroke, sal_Bool bFill )
+{
+ if ( aPathObj.Count() )
+ {
+ UpdateClipRegion();
+ UpdateLineStyle();
+ UpdateFillStyle();
+ if ( bFill )
+ {
+ if ( !bStroke )
+ {
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), FALSE ) );
+ }
+ if ( aPathObj.Count() == 1 )
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( aPathObj.GetObject( 0 ) ) );
+ else
+ mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( aPathObj ) );
+
+ if ( !bStroke )
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+ else
+ {
+ sal_uInt16 i, nCount = aPathObj.Count();
+ for ( i = 0; i < nCount; i++ )
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( aPathObj[ i ], maLineStyle.aLineInfo ) );
+ }
+ ClearPath();
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawPixel( const Point& rSource, const Color& rColor )
+{
+ mpGDIMetaFile->AddAction( new MetaPixelAction( ImplMap( rSource), rColor ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
+{
+ Point aDest( ImplMap( rPoint ) );
+ if ( bRecordPath )
+ aPathObj.AddPoint( aDest );
+ maActPos = aDest;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
+{
+ UpdateClipRegion();
+
+ Point aDest( ImplMap( rPoint ) );
+ if ( bRecordPath )
+ aPathObj.AddPoint( aDest );
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
+ }
+ maActPos = aDest;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawLine( const Point& rSource, const Point& rDest )
+{
+ UpdateClipRegion();
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaLineAction( ImplMap( rSource), ImplMap( rDest ), maLineStyle.aLineInfo ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawRect( const Rectangle& rRect, BOOL bEdge )
+{
+ UpdateClipRegion();
+ UpdateFillStyle();
+
+ if ( aClipPath.GetType() == COMPLEX )
+ {
+ Polygon aPoly( ImplMap( rRect ) );
+ PolyPolygon aPolyPolyRect( aPoly );
+ PolyPolygon aDest;
+ aClipPath.GetClipPath().GetIntersection( aPolyPolyRect, aDest );
+ ImplDrawClippedPolyPolygon( aDest );
+ }
+ else
+ {
+ if ( bEdge )
+ {
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ ImplSetNonPersistentLineColorTransparenz();
+ mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
+ }
+ }
+ else
+ {
+ ImplSetNonPersistentLineColorTransparenz();
+ mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawRoundRect( const Rectangle& rRect, const Size& rSize )
+{
+ UpdateClipRegion();
+ UpdateLineStyle();
+ UpdateFillStyle();
+ mpGDIMetaFile->AddAction( new MetaRoundRectAction( ImplMap( rRect ), labs( ImplMap( rSize ).Width() ), labs( ImplMap( rSize ).Height() ) ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawEllipse( const Rectangle& rRect )
+{
+ UpdateClipRegion();
+ UpdateFillStyle();
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ Point aCenter( ImplMap( rRect.Center() ) );
+ Size aRad( ImplMap( Size( rRect.GetWidth() / 2, rRect.GetHeight() / 2 ) ) );
+
+ ImplSetNonPersistentLineColorTransparenz();
+ mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, BOOL bTo )
+{
+ UpdateClipRegion();
+ UpdateLineStyle();
+ UpdateFillStyle();
+
+ Rectangle aRect( ImplMap( rRect ) );
+ Point aStart( ImplMap( rStart ) );
+ Point aEnd( ImplMap( rEnd ) );
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ if ( aStart == aEnd )
+ { // SJ: #i53768# if start & end is identical, then we have to draw a full ellipse
+ Point aCenter( aRect.Center() );
+ Size aRad( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
+
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
+ }
+ else
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_ARC ), maLineStyle.aLineInfo ) );
+ }
+ else
+ mpGDIMetaFile->AddAction( new MetaArcAction( aRect, aStart, aEnd ) );
+
+ if ( bTo )
+ maActPos = aEnd;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawPie( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
+{
+ UpdateClipRegion();
+ UpdateFillStyle();
+
+ Rectangle aRect( ImplMap( rRect ) );
+ Point aStart( ImplMap( rStart ) );
+ Point aEnd( ImplMap( rEnd ) );
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ ImplSetNonPersistentLineColorTransparenz();
+ mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_PIE ), maLineStyle.aLineInfo ) );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawChord( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
+{
+ UpdateClipRegion();
+ UpdateFillStyle();
+
+ Rectangle aRect( ImplMap( rRect ) );
+ Point aStart( ImplMap( rStart ) );
+ Point aEnd( ImplMap( rEnd ) );
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ ImplSetNonPersistentLineColorTransparenz();
+ mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_CHORD ), maLineStyle.aLineInfo ) );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
+{
+ UpdateClipRegion();
+ ImplMap( rPolygon );
+ if ( bRecordPath )
+ aPathObj.AddPolygon( rPolygon );
+ else
+ {
+ UpdateFillStyle();
+
+ if ( aClipPath.GetType() == COMPLEX )
+ {
+ PolyPolygon aPolyPoly( rPolygon );
+ PolyPolygon aDest;
+ aClipPath.GetClipPath().GetIntersection( aPolyPoly, aDest );
+ ImplDrawClippedPolyPolygon( aDest );
+ }
+ else
+ {
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ USHORT nCount = rPolygon.GetSize();
+ if ( nCount )
+ {
+ if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
+ {
+ Point aPoint( rPolygon[ 0 ] );
+ rPolygon.Insert( nCount, aPoint );
+ }
+ }
+ ImplSetNonPersistentLineColorTransparenz();
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordPath )
+{
+ UpdateClipRegion();
+
+ ImplMap( rPolyPolygon );
+
+ if ( bRecordPath )
+ aPathObj.AddPolyPolygon( rPolyPolygon );
+ else
+ {
+ UpdateFillStyle();
+
+ if ( aClipPath.GetType() == COMPLEX )
+ {
+ PolyPolygon aDest;
+ aClipPath.GetClipPath().GetIntersection( rPolyPolygon, aDest );
+ ImplDrawClippedPolyPolygon( aDest );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPolygon ) );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawPolyLine( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
+{
+ UpdateClipRegion();
+
+ ImplMap( rPolygon );
+ if ( bTo )
+ {
+ rPolygon[ 0 ] = maActPos;
+ maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
+ }
+ if ( bRecordPath )
+ aPathObj.AddPolyLine( rPolygon );
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawPolyBezier( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
+{
+ UpdateClipRegion();
+
+ sal_uInt16 nPoints = rPolygon.GetSize();
+ if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
+ {
+ ImplMap( rPolygon );
+ if ( bTo )
+ {
+ rPolygon[ 0 ] = maActPos;
+ maActPos = rPolygon[ nPoints - 1 ];
+ }
+ sal_uInt16 i;
+ for ( i = 0; ( i + 2 ) < nPoints; )
+ {
+ rPolygon.SetFlags( i++, POLY_NORMAL );
+ rPolygon.SetFlags( i++, POLY_CONTROL );
+ rPolygon.SetFlags( i++, POLY_CONTROL );
+ }
+ if ( bRecordPath )
+ aPathObj.AddPolyLine( rPolygon );
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry, sal_Bool bRecordPath, sal_Int32 nGfxMode )
+{
+ UpdateClipRegion();
+
+ VirtualDevice* pVDev = NULL;
+
+ rPosition = ImplMap( rPosition );
+
+ sal_Int32 nOldGfxMode = GetGfxMode();
+ SetGfxMode( GM_COMPATIBLE );
+ if ( pDXArry )
+ {
+ sal_Int32 i, nSum, nLen = rText.Len();
+
+ for( i = 0, nSum = 0; i < nLen; i++ )
+ {
+ sal_Int32 nTemp = ImplMap( Size( pDXArry[ i ], 0 ) ).Width();
+ nSum += nTemp;
+ pDXArry[ i ] = nSum;
+ }
+ }
+ if ( mnLatestTextLayoutMode != mnTextLayoutMode )
+ {
+ mnLatestTextLayoutMode = mnTextLayoutMode;
+ mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
+ }
+ SetGfxMode( nGfxMode );
+ sal_Bool bChangeFont = sal_False;
+ if ( mnLatestTextAlign != mnTextAlign )
+ {
+ bChangeFont = sal_True;
+ mnLatestTextAlign = mnTextAlign;
+ TextAlign eTextAlign;
+ if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
+ eTextAlign = ALIGN_BASELINE;
+ else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
+ eTextAlign = ALIGN_BOTTOM;
+ else
+ eTextAlign = ALIGN_TOP;
+ mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
+ }
+ if ( maLatestTextColor != maTextColor )
+ {
+ bChangeFont = sal_True;
+ maLatestTextColor = maTextColor;
+ mpGDIMetaFile->AddAction( new MetaTextColorAction( maTextColor ) );
+ }
+ sal_Bool bChangeFillColor = sal_False;
+ if ( maLatestBkColor != maBkColor )
+ {
+ bChangeFillColor = sal_True;
+ maLatestBkColor = maBkColor;
+ }
+ if ( mnLatestBkMode != mnBkMode )
+ {
+ bChangeFillColor = sal_True;
+ mnLatestBkMode = mnBkMode;
+ }
+ if ( bChangeFillColor )
+ {
+ bChangeFont = sal_True;
+ mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
+ }
+ Font aTmp( maFont );
+ aTmp.SetColor( maTextColor );
+ aTmp.SetFillColor( maBkColor );
+
+ if( mnBkMode == TRANSPARENT )
+ aTmp.SetTransparent( sal_True );
+ else
+ aTmp.SetTransparent( sal_False );
+
+ if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
+ aTmp.SetAlign( ALIGN_BASELINE );
+ else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
+ aTmp.SetAlign( ALIGN_BOTTOM );
+ else
+ aTmp.SetAlign( ALIGN_TOP );
+
+ if ( nGfxMode == GM_ADVANCED )
+ {
+ // check whether there is a font rotation applied via transformation
+ Point aP1( ImplMap( Point() ) );
+ Point aP2( ImplMap( Point( 0, 100 ) ) );
+ aP2.X() -= aP1.X();
+ aP2.Y() -= aP1.Y();
+ double fX = aP2.X();
+ double fY = aP2.Y();
+ if ( fX )
+ {
+ double fOrientation = acos( fX / sqrt( fX * fX + fY * fY ) ) * 57.29577951308;
+ if ( fY > 0 )
+ fOrientation = 360 - fOrientation;
+ fOrientation += 90;
+ fOrientation *= 10;
+ fOrientation += aTmp.GetOrientation();
+ aTmp.SetOrientation( sal_Int16( fOrientation ) );
+ }
+ }
+
+ if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
+ {
+ if ( !pVDev )
+ pVDev = new VirtualDevice;
+ sal_Int32 nTextWidth;
+ pVDev->SetMapMode( MapMode( MAP_100TH_MM ) );
+ pVDev->SetFont( maFont );
+ if( pDXArry )
+ {
+ UINT32 nLen = rText.Len();
+ nTextWidth = pVDev->GetTextWidth( rText.GetChar( (sal_uInt16)( nLen - 1 ) ) );
+ if( nLen > 1 )
+ nTextWidth += pDXArry[ nLen - 2 ];
+ }
+ else
+ nTextWidth = pVDev->GetTextWidth( rText );
+
+ if( mnTextAlign & TA_UPDATECP )
+ rPosition = maActPos;
+
+ if ( mnTextAlign & TA_RIGHT_CENTER )
+ {
+ double fLenght = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
+ rPosition.X() -= (sal_Int32)( fLenght * cos( maFont.GetOrientation() * F_PI1800 ) );
+ rPosition.Y() -= (sal_Int32)(-( fLenght * sin( maFont.GetOrientation() * F_PI1800 ) ) );
+ }
+
+ if( mnTextAlign & TA_UPDATECP )
+ maActPos.X() = rPosition.X() + nTextWidth;
+ }
+ if ( bChangeFont || ( maLatestFont != aTmp ) )
+ {
+ maLatestFont = aTmp;
+ mpGDIMetaFile->AddAction( new MetaFontAction( aTmp ) );
+ mpGDIMetaFile->AddAction( new MetaTextAlignAction( aTmp.GetAlign() ) );
+ mpGDIMetaFile->AddAction( new MetaTextColorAction( aTmp.GetColor() ) );
+ mpGDIMetaFile->AddAction( new MetaTextFillColorAction( aTmp.GetFillColor(), !aTmp.IsTransparent() ) );
+ }
+ if ( bRecordPath )
+ {
+ // ToDo
+ }
+ else
+ {
+ /* because text without dx array is badly scaled, we
+ will create such an array if necessary */
+ sal_Int32* pDX = pDXArry;
+ if ( !pDXArry )
+ {
+ pDX = new sal_Int32[ rText.Len() ];
+ if ( !pVDev )
+ pVDev = new VirtualDevice;
+ pVDev->SetMapMode( MAP_100TH_MM );
+ pVDev->SetFont( maLatestFont );
+ pVDev->GetTextArray( rText, pDX, 0, STRING_LEN );
+ }
+ mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, STRING_LEN ) );
+ if ( !pDXArry ) // this means we have created our own array
+ delete[] pDX; // which must be deleted
+ }
+ SetGfxMode( nOldGfxMode );
+ delete pVDev;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
+{
+ BitmapEx aBmpEx( rBitmap );
+ if ( aClipPath.GetType() == COMPLEX )
+ {
+ VirtualDevice aVDev;
+ MapMode aMapMode( MAP_100TH_MM );
+ aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
+ const Size aOutputSizePixel( aVDev.LogicToPixel( rSize, aMapMode ) );
+ const Size aSizePixel( rBitmap.GetSizePixel() );
+ if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
+ {
+ aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
+ aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
+ }
+ aVDev.SetMapMode( aMapMode );
+ aVDev.SetOutputSizePixel( aSizePixel );
+ aVDev.SetFillColor( Color( COL_BLACK ) );
+ const PolyPolygon aClip( aClipPath.GetClipPath() );
+ aVDev.DrawPolyPolygon( aClip );
+ const Point aEmptyPoint;
+
+ // #i50672# Extract whole VDev content (to match size of rBitmap)
+ aVDev.EnableMapMode( FALSE );
+ Bitmap aMask( aVDev.GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) );
+
+ if ( aBmpEx.IsTransparent() )
+ {
+ if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
+ aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
+ else
+ aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
+ aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
+ }
+ else
+ aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
+ }
+ if ( aBmpEx.IsTransparent() )
+ mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
+ else
+ mpGDIMetaFile->AddAction( new MetaBmpScaleAction( rPos, rSize, aBmpEx.GetBitmap() ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ResolveBitmapActions( List& rSaveList )
+{
+ UpdateClipRegion();
+
+ sal_uInt32 nObjects = rSaveList.Count();
+ sal_uInt32 nObjectsLeft = nObjects;
+
+ while ( nObjectsLeft )
+ {
+ sal_uInt32 i, nObjectsOfSameSize = 0;
+ sal_uInt32 nObjectStartIndex = nObjects - nObjectsLeft;
+
+ BSaveStruct* pSave = (BSaveStruct*)rSaveList.GetObject( nObjectStartIndex );
+ Rectangle aRect( pSave->aOutRect );
+
+ for ( i = nObjectStartIndex; i < nObjects; )
+ {
+ nObjectsOfSameSize++;
+ if ( ++i < nObjects )
+ {
+ pSave = (BSaveStruct*)rSaveList.GetObject( i );
+ if ( pSave->aOutRect != aRect )
+ break;
+ }
+ }
+ Point aPos( ImplMap( aRect.TopLeft() ) );
+ Size aSize( ImplMap( aRect.GetSize() ) );
+
+ for ( i = nObjectStartIndex; i < ( nObjectStartIndex + nObjectsOfSameSize ); i++ )
+ {
+ pSave = (BSaveStruct*)rSaveList.GetObject( i );
+
+ sal_uInt32 nWinRop = pSave->nWinRop;
+ sal_uInt8 nRasterOperation = (sal_uInt8)( nWinRop >> 16 );
+
+ sal_uInt32 nUsed = 0;
+ if ( ( nRasterOperation & 0xf ) != ( nRasterOperation >> 4 ) )
+ nUsed |= 1; // pattern is used
+ if ( ( nRasterOperation & 0x33 ) != ( ( nRasterOperation & 0xcc ) >> 2 ) )
+ nUsed |= 2; // source is used
+ if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
+ nUsed |= 4; // destination is used
+
+ if ( (nUsed & 1) && (( nUsed & 2 ) == 0) )
+ { // patterns aren't well supported yet
+ sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT ); // in this case nRasterOperation is either 0 or 0xff
+ UpdateFillStyle();
+ DrawRect( aRect, FALSE );
+ SetRasterOp( nOldRop );
+ }
+ else
+ {
+ sal_Bool bDrawn = sal_False;
+
+ if ( i == nObjectStartIndex ) // optimizing, sometimes it is possible to create just one transparent bitmap
+ {
+ if ( nObjectsOfSameSize == 2 )
+ {
+ BSaveStruct* pSave2 = (BSaveStruct*)rSaveList.GetObject( i + 1 );
+ if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
+ ( pSave->aBmp.GetPrefMapMode() == pSave2->aBmp.GetPrefMapMode() ) )
+ {
+ // TODO: Strictly speaking, we should
+ // check whether mask is monochrome, and
+ // whether image is black (upper branch)
+ // or white (lower branch). Otherwise, the
+ // effect is not the same as a masked
+ // bitmap.
+ if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
+ {
+ Bitmap aMask( pSave->aBmp ); aMask.Invert();
+ BitmapEx aBmpEx( pSave2->aBmp, aMask );
+ ImplDrawBitmap( aPos, aSize, aBmpEx );
+ bDrawn = sal_True;
+ i++;
+ }
+ // #i20085# This is just the other way
+ // around as above. Only difference: mask
+ // is inverted
+ else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
+ {
+ Bitmap aMask( pSave->aBmp );
+ BitmapEx aBmpEx( pSave2->aBmp, aMask );
+ ImplDrawBitmap( aPos, aSize, aBmpEx );
+ bDrawn = sal_True;
+ i++;
+ }
+ }
+ }
+ }
+
+ if ( !bDrawn )
+ {
+ Push();
+ sal_uInt32 nOldRop = SetRasterOp( R2_COPYPEN );
+ Bitmap aBitmap( pSave->aBmp );
+ sal_uInt32 nOperation = ( nRasterOperation & 0xf );
+ switch( nOperation )
+ {
+ case 0x1 :
+ case 0xe :
+ {
+ SetRasterOp( R2_XORPEN );
+ ImplDrawBitmap( aPos, aSize, aBitmap );
+ SetRasterOp( R2_COPYPEN );
+ Bitmap aMask( aBitmap );
+ aMask.Invert();
+ BitmapEx aBmpEx( aBitmap, aMask );
+ ImplDrawBitmap( aPos, aSize, aBmpEx );
+ if ( nOperation == 0x1 )
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ }
+ }
+ break;
+ case 0x7 :
+ case 0x8 :
+ {
+ Bitmap aMask( aBitmap );
+ if ( ( nUsed & 1 ) && ( nRasterOperation & 0xb0 ) == 0xb0 ) // pattern used
+ {
+ aBitmap.Convert( BMP_CONVERSION_24BIT );
+ aBitmap.Erase( maFillStyle.aFillColor );
+ }
+ BitmapEx aBmpEx( aBitmap, aMask );
+ ImplDrawBitmap( aPos, aSize, aBmpEx );
+ if ( nOperation == 0x7 )
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ }
+ }
+ break;
+
+ case 0x4 :
+ case 0xb :
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ SetRasterOp( R2_COPYPEN );
+ Bitmap aMask( aBitmap );
+ aBitmap.Invert();
+ BitmapEx aBmpEx( aBitmap, aMask );
+ ImplDrawBitmap( aPos, aSize, aBmpEx );
+ SetRasterOp( R2_XORPEN );
+ ImplDrawBitmap( aPos, aSize, aBitmap );
+ if ( nOperation == 0xb )
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ }
+ }
+ break;
+
+ case 0x2 :
+ case 0xd :
+ {
+ Bitmap aMask( aBitmap );
+ aMask.Invert();
+ BitmapEx aBmpEx( aBitmap, aMask );
+ ImplDrawBitmap( aPos, aSize, aBmpEx );
+ SetRasterOp( R2_XORPEN );
+ ImplDrawBitmap( aPos, aSize, aBitmap );
+ if ( nOperation == 0xd )
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ }
+ }
+ break;
+ case 0x6 :
+ case 0x9 :
+ {
+ SetRasterOp( R2_XORPEN );
+ ImplDrawBitmap( aPos, aSize, aBitmap );
+ if ( nOperation == 0x9 )
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ }
+ }
+ break;
+
+ case 0x0 : // WHITENESS
+ case 0xf : // BLACKNESS
+ { // in this case nRasterOperation is either 0 or 0xff
+ maFillStyle = WinMtfFillStyle( Color( nRasterOperation, nRasterOperation, nRasterOperation ) );
+ UpdateFillStyle();
+ DrawRect( aRect, FALSE );
+ }
+ break;
+
+ case 0x3 : // only source is used
+ case 0xc :
+ {
+ if ( nRasterOperation == 0x33 )
+ aBitmap.Invert();
+ ImplDrawBitmap( aPos, aSize, aBitmap );
+ }
+ break;
+
+ case 0x5 : // only destination is used
+ {
+ SetRasterOp( R2_NOT );
+ DrawRect( aRect, FALSE );
+ }
+ case 0xa : // no operation
+ break;
+ }
+ SetRasterOp( nOldRop );
+ Pop();
+ }
+ }
+ }
+ nObjectsLeft -= nObjectsOfSameSize;
+ }
+
+ void* pPtr;
+ for ( pPtr = rSaveList.First(); pPtr; pPtr = rSaveList.Next() )
+ delete (BSaveStruct*)pPtr;
+ rSaveList.Clear();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetDevOrg( const Point& rPoint )
+{
+ mnDevOrgX = rPoint.X();
+ mnDevOrgY = rPoint.Y();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetDevOrgOffset( INT32 nXAdd, INT32 nYAdd )
+{
+ mnDevOrgX += nXAdd;
+ mnDevOrgY += nYAdd;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetDevExt( const Size& rSize )
+{
+ if ( rSize.Width() && rSize.Height() )
+ {
+ switch( mnMapMode )
+ {
+ case MM_ISOTROPIC :
+ case MM_ANISOTROPIC :
+ {
+ mnDevWidth = rSize.Width();
+ mnDevHeight = rSize.Height();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ScaleDevExt( double fX, double fY )
+{
+ mnDevWidth = FRound( mnDevWidth * fX );
+ mnDevHeight = FRound( mnDevHeight * fY );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetWinOrg( const Point& rPoint )
+{
+ mnWinOrgX = rPoint.X();
+ mnWinOrgY = rPoint.Y();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetWinOrgOffset( INT32 nXAdd, INT32 nYAdd )
+{
+ mnWinOrgX += nXAdd;
+ mnWinOrgY += nYAdd;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetWinExt( const Size& rSize )
+{
+
+ if( rSize.Width() && rSize.Height() )
+ {
+ switch( mnMapMode )
+ {
+ case MM_ISOTROPIC :
+ case MM_ANISOTROPIC :
+ {
+ mnWinExtX = rSize.Width();
+ mnWinExtY = rSize.Height();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ScaleWinExt( double fX, double fY )
+{
+ mnWinExtX = FRound( mnWinExtX * fX );
+ mnWinExtY = FRound( mnWinExtY * fY );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetrclBounds( const Rectangle& rRect )
+{
+ mrclBounds = rRect;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetrclFrame( const Rectangle& rRect )
+{
+ mrclFrame = rRect;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetRefPix( const Size& rSize )
+{
+ mnPixX = rSize.Width();
+ mnPixY = rSize.Height();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetRefMill( const Size& rSize )
+{
+ mnMillX = rSize.Width();
+ mnMillY = rSize.Height();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
+{
+ mnMapMode = nMapMode;
+ if ( nMapMode == MM_TEXT )
+ {
+ mnWinExtX = mnDevWidth;
+ mnWinExtY = mnDevHeight;
+ }
+ else if ( mnMapMode == MM_HIMETRIC )
+ {
+ mnWinExtX = mnMillX * 100;
+ mnWinExtY = mnMillY * 100;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
+{
+ maXForm.eM11 = rXForm.eM11;
+ maXForm.eM12 = rXForm.eM12;
+ maXForm.eM21 = rXForm.eM21;
+ maXForm.eM22 = rXForm.eM22;
+ maXForm.eDx = rXForm.eDx;
+ maXForm.eDy = rXForm.eDy;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ModifyWorldTransform( const XForm& rXForm, UINT32 nMode )
+{
+ switch( nMode )
+ {
+ case MWT_IDENTITY :
+ {
+ maXForm.eM11 = maXForm.eM12 = maXForm.eM21 = maXForm.eM22 = 1.0f;
+ maXForm.eDx = maXForm.eDy = 0.0f;
+ }
+ break;
+
+ case MWT_RIGHTMULTIPLY :
+ case MWT_LEFTMULTIPLY :
+ {
+ const XForm* pLeft;
+ const XForm* pRight;
+
+ if ( nMode == MWT_LEFTMULTIPLY )
+ {
+ pLeft = &rXForm;
+ pRight = &maXForm;
+ }
+ else
+ {
+ pLeft = &maXForm;
+ pRight = &rXForm;
+ }
+
+ float aF[3][3];
+ float bF[3][3];
+ float cF[3][3];
+
+ aF[0][0] = pLeft->eM11;
+ aF[0][1] = pLeft->eM12;
+ aF[0][2] = 0;
+ aF[1][0] = pLeft->eM21;
+ aF[1][1] = pLeft->eM22;
+ aF[1][2] = 0;
+ aF[2][0] = pLeft->eDx;
+ aF[2][1] = pLeft->eDy;
+ aF[2][2] = 1;
+
+ bF[0][0] = pRight->eM11;
+ bF[0][1] = pRight->eM12;
+ bF[0][2] = 0;
+ bF[1][0] = pRight->eM21;
+ bF[1][1] = pRight->eM22;
+ bF[1][2] = 0;
+ bF[2][0] = pRight->eDx;
+ bF[2][1] = pRight->eDy;
+ bF[2][2] = 1;
+
+ int i, j, k;
+ for ( i = 0; i < 3; i++ )
+ {
+ for ( j = 0; j < 3; j++ )
+ {
+ cF[i][j] = 0;
+ for ( k = 0; k < 3; k++ )
+ cF[i][j] += aF[i][k] * bF[k][j];
+ }
+ }
+ maXForm.eM11 = cF[0][0];
+ maXForm.eM12 = cF[0][1];
+ maXForm.eM21 = cF[1][0];
+ maXForm.eM22 = cF[1][1];
+ maXForm.eDx = cF[2][0];
+ maXForm.eDy = cF[2][1];
+ }
+ break;
+ }
+ }
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::Push() // !! to be able to access the original ClipRegion it
+{ // is not allowed to use the MetaPushAction()
+ UpdateClipRegion(); // (the original clip region is on top of the stack) (SJ)
+ SaveStructPtr pSave( new SaveStruct );
+
+ pSave->aLineStyle = maLineStyle;
+ pSave->aFillStyle = maFillStyle;
+
+ pSave->aFont = maFont;
+ pSave->aTextColor = maTextColor;
+ pSave->nTextAlign = mnTextAlign;
+ pSave->nTextLayoutMode = mnTextLayoutMode;
+ pSave->nMapMode = mnMapMode;
+ pSave->nGfxMode = mnGfxMode;
+ pSave->nBkMode = mnBkMode;
+ pSave->aBkColor = maBkColor;
+ pSave->bFillStyleSelected = mbFillStyleSelected;
+
+ pSave->aActPos = maActPos;
+ pSave->aXForm = maXForm;
+ pSave->eRasterOp = meRasterOp;
+
+ pSave->nWinOrgX = mnWinOrgX;
+ pSave->nWinOrgY = mnWinOrgY;
+ pSave->nWinExtX = mnWinExtX;
+ pSave->nWinExtY = mnWinExtY;
+ pSave->nDevOrgX = mnDevOrgX;
+ pSave->nDevOrgY = mnDevOrgY;
+ pSave->nDevWidth = mnDevWidth;
+ pSave->nDevHeight = mnDevHeight;
+
+ pSave->aPathObj = aPathObj;
+ pSave->aClipPath = aClipPath;
+
+ vSaveStack.push_back( pSave );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::Pop()
+{
+ // Die aktuellen Daten vom Stack holen
+ if( vSaveStack.size() )
+ {
+ // Die aktuelle Daten auf dem Stack sichern
+ SaveStructPtr pSave( vSaveStack.back() );
+
+ maLineStyle = pSave->aLineStyle;
+ maFillStyle = pSave->aFillStyle;
+
+ maFont = pSave->aFont;
+ maTextColor = pSave->aTextColor;
+ mnTextAlign = pSave->nTextAlign;
+ mnTextLayoutMode = pSave->nTextLayoutMode;
+ mnBkMode = pSave->nBkMode;
+ mnGfxMode = pSave->nGfxMode;
+ mnMapMode = pSave->nMapMode;
+ maBkColor = pSave->aBkColor;
+ mbFillStyleSelected = pSave->bFillStyleSelected;
+
+ maActPos = pSave->aActPos;
+ maXForm = pSave->aXForm;
+ meRasterOp = pSave->eRasterOp;
+
+ mnWinOrgX = pSave->nWinOrgX;
+ mnWinOrgY = pSave->nWinOrgY;
+ mnWinExtX = pSave->nWinExtX;
+ mnWinExtY = pSave->nWinExtY;
+ mnDevOrgX = pSave->nDevOrgX;
+ mnDevOrgY = pSave->nDevOrgY;
+ mnDevWidth = pSave->nDevWidth;
+ mnDevHeight = pSave->nDevHeight;
+
+ aPathObj = pSave->aPathObj;
+ if ( ! ( aClipPath == pSave->aClipPath ) )
+ {
+ aClipPath = pSave->aClipPath;
+ aClipPath.bNeedsUpdate = sal_True;
+ }
+ if ( meLatestRasterOp != meRasterOp )
+ mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
+ vSaveStack.pop_back();
+ }
+}
+
+void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
+{
+ rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
+}
+
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
new file mode 100644
index 000000000000..fb4fd2fe0c57
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -0,0 +1,777 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WINMTF_HXX
+#define _WINMTF_HXX
+
+#ifdef DBG_UTIL
+#define WIN_MTF_ASSERT
+#endif
+
+#include <sot/object.hxx>
+#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
+#include <boost/shared_ptr.hpp>
+#endif
+#ifndef _TOOL_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#include <tools/stack.hxx>
+#include <tools/table.hxx>
+#include <tools/dynary.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/poly.hxx>
+#include <vcl/font.hxx>
+#include <vcl/bmpacc.hxx>
+#include <vcl/lineinfo.hxx>
+#include <svtools/fltcall.hxx>
+
+#include <vector>
+#include <math.h>
+#include <stdlib.h>
+
+#define ERROR 0
+#define NULLREGION 1
+#define SIMPLEREGION 2
+#define COMPLEXREGION 3
+
+#define RGN_AND 1
+#define RGN_OR 2
+#define RGN_XOR 3
+#define RGN_DIFF 4
+#define RGN_COPY 5
+
+#define TRANSPARENT 1
+#define OPAQUE 2
+#define BKMODE_LAST 2
+
+/* xform stuff */
+#define MWT_IDENTITY 1
+#define MWT_LEFTMULTIPLY 2
+#define MWT_RIGHTMULTIPLY 3
+
+#define ENHMETA_STOCK_OBJECT 0x80000000
+
+/* Stock Logical Objects */
+#define WHITE_BRUSH 0
+#define LTGRAY_BRUSH 1
+#define GRAY_BRUSH 2
+#define DKGRAY_BRUSH 3
+#define BLACK_BRUSH 4
+#define NULL_BRUSH 5
+#define HOLLOW_BRUSH NULL_BRUSH
+#define WHITE_PEN 6
+#define BLACK_PEN 7
+#define NULL_PEN 8
+#define OEM_FIXED_FONT 10
+#define ANSI_FIXED_FONT 11
+#define ANSI_VAR_FONT 12
+#define SYSTEM_FONT 13
+#define DEVICE_DEFAULT_FONT 14
+#define DEFAULT_PALETTE 15
+#define SYSTEM_FIXED_FONT 16
+
+
+#define R2_BLACK 1
+#define R2_NOTMERGEPEN 2
+#define R2_MASKNOTPEN 3
+#define R2_NOTCOPYPEN 4
+#define R2_MASKPENNOT 5
+#define R2_NOT 6
+#define R2_XORPEN 7
+#define R2_NOTMASKPEN 8
+#define R2_MASKPEN 9
+#define R2_NOTXORPEN 10
+#define R2_NOP 11
+#define R2_MERGENOTPEN 12
+#define R2_COPYPEN 13
+#define R2_MERGEPENNOT 14
+#define R2_MERGEPEN 15
+#define R2_WHITE 16
+
+/* Mapping Modes */
+#define MM_TEXT 1
+#define MM_LOMETRIC 2
+#define MM_HIMETRIC 3
+#define MM_LOENGLISH 4
+#define MM_HIENGLISH 5
+#define MM_TWIPS 6
+#define MM_ISOTROPIC 7
+#define MM_ANISOTROPIC 8
+
+
+/* Graphics Modes */
+#define GM_COMPATIBLE 1
+#define GM_ADVANCED 2
+#define GM_LAST 2
+
+/* StretchBlt() Modes */
+#define BLACKONWHITE 1
+#define WHITEONBLACK 2
+#define COLORONCOLOR 3
+#define HALFTONE 4
+#define MAXSTRETCHBLTMODE 4
+#define STRETCH_ANDSCANS BLACKONWHITE
+#define STRETCH_ORSCANS WHITEONBLACK
+#define STRETCH_DELETESCANS COLORONCOLOR
+#define STRETCH_HALFTONE HALFTONE
+
+#define LF_FACESIZE 32
+
+struct LOGFONTW
+{
+ INT32 lfHeight;
+ INT32 lfWidth;
+ INT32 lfEscapement;
+ INT32 lfOrientation;
+ INT32 lfWeight;
+ BYTE lfItalic;
+ BYTE lfUnderline;
+ BYTE lfStrikeOut;
+ BYTE lfCharSet;
+ BYTE lfOutPrecision;
+ BYTE lfClipPrecision;
+ BYTE lfQuality;
+ BYTE lfPitchAndFamily;
+ String alfFaceName;
+};
+
+#define TA_NOUPDATECP 0x0000
+#define TA_UPDATECP 0x0001
+#define TA_LEFT 0x0000
+#define TA_RIGHT 0x0002
+#define TA_CENTER 0x0006
+#define TA_RIGHT_CENTER (TA_RIGHT | TA_CENTER)
+#define TA_TOP 0x0000
+#define TA_BOTTOM 0x0008
+#define TA_BASELINE 0x0018
+
+#define SRCCOPY 0x00CC0020L
+#define SRCPAINT 0x00EE0086L
+#define SRCAND 0x008800C6L
+#define SRCINVERT 0x00660046L
+#define SRCERASE 0x00440328L
+#define NOTSRCCOPY 0x00330008L
+#define NOTSRCERASE 0x001100A6L
+#define MERGECOPY 0x00C000CAL
+#define MERGEPAINT 0x00BB0226L
+#define PATCOPY 0x00F00021L
+#define PATPAINT 0x00FB0A09L
+#define PATINVERT 0x005A0049L
+#define DSTINVERT 0x00550009L
+#define BLACKNESS 0x00000042L
+#define WHITENESS 0x00FF0062L
+
+#define PS_SOLID 0
+#define PS_DASH 1
+#define PS_DOT 2
+#define PS_DASHDOT 3
+#define PS_DASHDOTDOT 4
+#define PS_NULL 5
+#define PS_INSIDEFRAME 6
+#define PS_USERSTYLE 7
+#define PS_ALTERNATE 8
+#define PS_STYLE_MASK 15
+
+#define PS_ENDCAP_ROUND 0x000
+#define PS_ENDCAP_SQUARE 0x100
+#define PS_ENDCAP_FLAT 0x200
+#define PS_ENDCAP_MASK 0xF00
+
+#define PS_JOIN_ROUND 0x0000
+#define PS_JOIN_BEVEL 0x1000
+#define PS_JOIN_MITER 0x2000
+#define PS_JOIN_MASK 0xF000
+
+#define PS_COSMETIC 0x00000
+#define PS_GEOMETRIC 0x10000
+#define PS_TYPE_MASK 0xF0000
+
+#define ANSI_CHARSET 0
+#define DEFAULT_CHARSET 1
+#define SYMBOL_CHARSET 2
+#define SHIFTJIS_CHARSET 128
+#define HANGEUL_CHARSET 129
+#define GB2312_CHARSET 134
+#define CHINESEBIG5_CHARSET 136
+#define OEM_CHARSET 255
+/*WINVER >= 0x0400*/
+#define JOHAB_CHARSET 130
+#define HEBREW_CHARSET 177
+#define ARABIC_CHARSET 178
+#define GREEK_CHARSET 161
+#define TURKISH_CHARSET 162
+#define VIETNAMESE_CHARSET 163
+#define THAI_CHARSET 222
+#define EASTEUROPE_CHARSET 238
+#define RUSSIAN_CHARSET 204
+#define MAC_CHARSET 77
+#define BALTIC_CHARSET 186
+
+#define ETO_OPAQUE 0x0002
+#define ETO_CLIPPED 0x0004
+/*WINVER >= 0x0400*/
+#define ETO_GLYPH_INDEX 0x0010
+#define ETO_RTLREADING 0x0080
+#define ETO_NUMERICSLOCAL 0x0400
+#define ETO_NUMERICSLATIN 0x0800
+#define ETO_IGNORELANGUAGE 0x1000
+/*_WIN32_WINNT >= 0x0500*/
+#define ETO_PDY 0x2000
+
+
+#define DEFAULT_PITCH 0x00
+#define FIXED_PITCH 0x01
+#define VARIABLE_PITCH 0x02
+
+/* Font Families */
+#define FF_DONTCARE 0x00
+#define FF_ROMAN 0x10
+#define FF_SWISS 0x20
+#define FF_MODERN 0x30
+#define FF_SCRIPT 0x40
+#define FF_DECORATIVE 0x50
+
+#define FW_DONTCARE 0
+#define FW_THIN 100
+#define FW_EXTRALIGHT 200
+#define FW_LIGHT 300
+#define FW_NORMAL 400
+#define FW_MEDIUM 500
+#define FW_SEMIBOLD 600
+#define FW_BOLD 700
+#define FW_EXTRABOLD 800
+#define FW_HEAVY 900
+#define FW_ULTRALIGHT 200
+#define FW_REGULAR 400
+#define FW_DEMIBOLD 600
+#define FW_ULTRABOLD 800
+#define FW_BLACK 900
+
+#define BS_SOLID 0
+#define BS_NULL 1
+#define BS_HOLLOW 1
+#define BS_HATCHED 2
+#define BS_PATTERN 3
+#define BS_INDEXED 4
+#define BS_DIBPATTERN 5
+#define BS_DIBPATTERNPT 6
+#define BS_PATTERN8X8 7
+#define BS_DIBPATTERN8X8 8
+#define BS_MONOPATTERN 9
+
+#define W_HS_HORIZONTAL 0
+#define W_HS_VERTICAL 1
+#define W_HS_FDIAGONAL 2
+#define W_HS_BDIAGONAL 3
+#define W_HS_CROSS 4
+#define W_HS_DIAGCROSS 5
+
+#define RDH_RECTANGLES 1
+
+#define W_MFCOMMENT 15
+
+#define PRIVATE_ESCAPE_UNICODE 2
+
+//============================ WMFReader ==================================
+
+
+#ifdef WIN_MTF_ASSERT
+#define WIN_MTF_ASSERT_INIT 0x80000000
+#define WIN_MTF_ASSERT_ONCE 0x40000000
+#define WIN_MTF_ASSERT_MIFE 0x20000000
+
+void WinMtfAssertHandler( const sal_Char*, sal_uInt32 nFlags = WIN_MTF_ASSERT_MIFE );
+#endif
+
+enum WinMtfClipPathType{ EMPTY, RECTANGLE, COMPLEX };
+
+class WinMtfClipPath
+{
+ PolyPolygon aPolyPoly;
+ WinMtfClipPathType eType;
+ sal_Int32 nDepth;
+
+ void ImpUpdateType();
+
+ public :
+
+ sal_Bool bNeedsUpdate;
+
+ WinMtfClipPath(): eType(EMPTY), nDepth( 0 ), bNeedsUpdate( sal_False ){};
+
+ void SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode );
+ void IntersectClipRect( const Rectangle& rRect );
+ void ExcludeClipRect( const Rectangle& rRect );
+ void MoveClipRegion( const Size& rSize );
+
+ WinMtfClipPathType GetType() const { return eType; };
+ const PolyPolygon& GetClipPath() const { return aPolyPoly; };
+
+ sal_Bool operator==( const WinMtfClipPath& rPath )
+ {
+ return ( rPath.eType == eType ) &&
+ ( rPath.aPolyPoly == aPolyPoly );
+ };
+};
+
+class WinMtfPathObj : public PolyPolygon
+{
+ sal_Bool bClosed;
+
+ public :
+
+ WinMtfPathObj() { bClosed = sal_True; }
+ void Init() { Clear(); bClosed = sal_True; };
+ void ClosePath();
+
+ void AddPoint( const Point& rPoint );
+ void AddPolygon( const Polygon& rPoly );
+ void AddPolyLine( const Polygon& rPoly );
+ void AddPolyPolygon( const PolyPolygon& rPolyPolygon );
+};
+
+struct WinMtfFontStyle
+{
+ Font aFont;
+
+ WinMtfFontStyle( LOGFONTW& rLogFont );
+};
+
+// -----------------------------------------------------------------------------
+
+struct WinMtfFillStyle
+{
+ Color aFillColor;
+ BOOL bTransparent;
+
+ WinMtfFillStyle() :
+ aFillColor ( Color( COL_BLACK ) ),
+ bTransparent( FALSE )
+ {
+ };
+
+ WinMtfFillStyle( const Color& rColor, BOOL bTrans = FALSE ) :
+ aFillColor ( rColor ),
+ bTransparent( bTrans )
+ {
+ };
+
+ BOOL operator==( const WinMtfFillStyle& rStyle )
+ { return ( ( aFillColor == rStyle.aFillColor ) && ( bTransparent == rStyle.bTransparent ) ); };
+ BOOL operator==( WinMtfFillStyle* pStyle )
+ { return ( ( aFillColor == pStyle->aFillColor ) && ( bTransparent == pStyle->bTransparent ) ); };
+ void operator=( const WinMtfFillStyle& rStyle ) { aFillColor = rStyle.aFillColor; bTransparent = rStyle.bTransparent; };
+ void operator=( WinMtfFillStyle* pStyle ) { aFillColor = pStyle->aFillColor; bTransparent = pStyle->bTransparent; };
+};
+
+// -----------------------------------------------------------------------------
+
+struct WinMtfLineStyle
+{
+ Color aLineColor;
+ LineInfo aLineInfo;
+ BOOL bTransparent;
+
+ WinMtfLineStyle() :
+ aLineColor ( COL_BLACK ),
+ bTransparent( FALSE ) {};
+
+ WinMtfLineStyle( const Color& rColor, BOOL bTrans = FALSE ) :
+ aLineColor ( rColor ),
+ bTransparent( bTrans ) {};
+
+ WinMtfLineStyle( const Color& rColor, const LineInfo rStyle, BOOL bTrans = FALSE ) :
+ aLineColor ( rColor ),
+ aLineInfo ( rStyle ),
+ bTransparent( bTrans ) {};
+
+ BOOL operator==( const WinMtfLineStyle& rStyle ) { return ( ( aLineColor == rStyle.aLineColor ) && ( bTransparent == rStyle.bTransparent ) && ( aLineInfo == rStyle.aLineInfo ) ); };
+ BOOL operator==( WinMtfLineStyle* pStyle ) { return ( ( aLineColor == pStyle->aLineColor ) && ( bTransparent == pStyle->bTransparent ) && ( aLineInfo == pStyle->aLineInfo ) ); };
+ void operator=( const WinMtfLineStyle& rStyle )
+ {
+ aLineColor = rStyle.aLineColor;
+ bTransparent = rStyle.bTransparent;
+ aLineInfo = rStyle.aLineInfo;
+ };
+
+ void operator=( WinMtfLineStyle* pStyle )
+ {
+ aLineColor = pStyle->aLineColor;
+ bTransparent = pStyle->bTransparent;
+ aLineInfo = pStyle->aLineInfo;
+ };
+};
+
+// -----------------------------------------------------------------------------
+
+struct XForm
+{
+ float eM11;
+ float eM12;
+ float eM21;
+ float eM22;
+ float eDx;
+ float eDy;
+ XForm()
+ {
+ eM11 = eM22 = 1.0f;
+ eDx = eDy = eM12 = eM21 = 0.0f;
+ };
+
+ friend SvStream& operator>>( SvStream& rIn, XForm& rXForm );
+};
+
+// -----------------------------------------------------------------------------
+
+struct SaveStruct
+{
+ sal_uInt32 nBkMode, nMapMode, nGfxMode, nTextLayoutMode;
+ sal_Int32 nWinOrgX, nWinOrgY, nWinExtX, nWinExtY;
+ sal_Int32 nDevOrgX, nDevOrgY, nDevWidth, nDevHeight;
+
+ WinMtfLineStyle aLineStyle;
+ WinMtfFillStyle aFillStyle;
+
+ Font aFont;
+ Color aBkColor;
+ Color aTextColor;
+ sal_uInt32 nTextAlign;
+ RasterOp eRasterOp;
+
+ Point aActPos;
+ WinMtfPathObj aPathObj;
+ WinMtfClipPath aClipPath;
+ XForm aXForm;
+
+ sal_Bool bRecordPath;
+ sal_Bool bFillStyleSelected;
+};
+
+typedef ::boost::shared_ptr< SaveStruct > SaveStructPtr;
+
+// -----------------------------------------------------------------------------
+
+struct BSaveStruct
+{
+ Bitmap aBmp;
+ Rectangle aOutRect;
+ UINT32 nWinRop;
+
+ BSaveStruct( const Bitmap& rBmp, const Rectangle& rOutRect, UINT32 nRop ) :
+ aBmp( rBmp ), aOutRect( rOutRect ), nWinRop( nRop ){};
+};
+
+// -----------------------------------------------------------------------------
+
+enum GDIObjectType { GDI_DUMMY = 0, GDI_PEN = 1, GDI_BRUSH = 2, GDI_FONT = 3, GDI_PALETTE = 4, GDI_BITMAP = 5, GDI_REGION = 6 };
+
+struct GDIObj
+{
+ void* pStyle;
+ GDIObjectType eType;
+
+ GDIObj() :
+ pStyle ( NULL ),
+ eType ( GDI_DUMMY )
+ {
+ };
+
+ GDIObj( GDIObjectType eT, void* pS ) { pStyle = pS; eType = eT; };
+ void Set( GDIObjectType eT, void* pS ) { pStyle = pS; eType = eT; };
+ void Delete()
+ {
+ if ( pStyle )
+ {
+ switch ( eType )
+ {
+ case GDI_PEN :
+ delete (WinMtfLineStyle*)pStyle;
+ break;
+ case GDI_BRUSH :
+ delete (WinMtfFillStyle*)pStyle;
+ break;
+ case GDI_FONT :
+ delete (WinMtfFontStyle*)pStyle;
+ break;
+
+ default:
+ DBG_ERROR( "unsupported style deleted" );
+ break;
+ }
+ pStyle = NULL;
+ }
+ };
+
+ ~GDIObj()
+ {
+ Delete();
+ }
+};
+
+// -----------------------------------------------------------------------------
+
+class WinMtfOutput
+{
+
+ WinMtfPathObj aPathObj;
+ WinMtfClipPath aClipPath;
+
+ WinMtfLineStyle maLatestLineStyle;
+ WinMtfLineStyle maLineStyle;
+ WinMtfFillStyle maLatestFillStyle;
+ WinMtfFillStyle maFillStyle;
+ Font maLatestFont;
+ Font maFont;
+ sal_uInt32 mnLatestTextAlign;
+ sal_uInt32 mnTextAlign;
+ Color maLatestTextColor;
+ Color maTextColor;
+ Color maLatestBkColor;
+ Color maBkColor;
+ sal_uInt32 mnLatestTextLayoutMode;
+ sal_uInt32 mnTextLayoutMode;
+ sal_uInt32 mnLatestBkMode;
+ sal_uInt32 mnBkMode;
+ RasterOp meLatestRasterOp;
+ RasterOp meRasterOp;
+
+ std::vector< GDIObj* > vGDIObj;
+
+ Point maActPos;
+
+ sal_uInt32 mnRop;
+ sal_Bool mbNopMode;
+ sal_Bool mbFillStyleSelected;
+
+ std::vector< SaveStructPtr > vSaveStack;
+
+ sal_uInt32 mnGfxMode;
+ sal_uInt32 mnMapMode;
+ XForm maXForm;
+ sal_Int32 mnDevOrgX, mnDevOrgY;
+ sal_Int32 mnDevWidth, mnDevHeight;
+ sal_Int32 mnWinOrgX, mnWinOrgY; // aktuelles Window-Origin
+ sal_Int32 mnWinExtX, mnWinExtY; // aktuelles Window-Extent
+
+ sal_Int32 mnPixX, mnPixY; // Reference Device in pixel
+ sal_Int32 mnMillX, mnMillY; // Reference Device in Mill
+ Rectangle mrclFrame; // rectangle in logical units 1/100th mm
+ Rectangle mrclBounds;
+
+ GDIMetaFile* mpGDIMetaFile;
+
+ void UpdateLineStyle();
+ void UpdateFillStyle();
+
+ Point ImplMap( const Point& rPt );
+ Size ImplMap( const Size& rSz );
+ Rectangle ImplMap( const Rectangle& rRectangle );
+ void ImplMap( Font& rFont );
+ Polygon& ImplMap( Polygon& rPolygon );
+ PolyPolygon& ImplMap( PolyPolygon& rPolyPolygon );
+ void ImplResizeObjectArry( UINT32 nNewEntry );
+ void ImplSetNonPersistentLineColorTransparenz();
+ void ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly );
+ void ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap );
+
+ public:
+
+ void SetDevOrg( const Point& rPoint );
+ void SetDevOrgOffset( INT32 nXAdd, INT32 nYAdd );
+ void SetDevExt( const Size& rSize );
+ void ScaleDevExt( double fX, double fY );
+
+ void SetWinOrg( const Point& rPoint );
+ void SetWinOrgOffset( INT32 nX, INT32 nY );
+ void SetWinExt( const Size& rSize );
+ void ScaleWinExt( double fX, double fY );
+
+ void SetrclBounds( const Rectangle& rRect );
+ void SetrclFrame( const Rectangle& rRect );
+ void SetRefPix( const Size& rSize );
+ void SetRefMill( const Size& rSize );
+
+ sal_uInt32 GetMapMode() const { return mnMapMode; };
+ void SetMapMode( sal_uInt32 mnMapMode );
+ void SetWorldTransform( const XForm& rXForm );
+ void ModifyWorldTransform( const XForm& rXForm, UINT32 nMode );
+
+ void Push();
+ void Pop();
+
+ UINT32 SetRasterOp( UINT32 nRasterOp );
+ void StrokeAndFillPath( sal_Bool bStroke, sal_Bool bFill );
+
+ void SetGfxMode( sal_Int32 nGfxMode ){ mnGfxMode = nGfxMode; };
+ sal_Int32 GetGfxMode() const { return mnGfxMode; };
+ void SetBkMode( UINT32 nMode );
+ void SetBkColor( const Color& rColor );
+ void SetTextColor( const Color& rColor );
+ void SetTextAlign( UINT32 nAlign );
+ void CreateObject( GDIObjectType, void* pStyle = NULL );
+ void CreateObject( INT32 nIndex, GDIObjectType, void* pStyle = NULL );
+ void DeleteObject( INT32 nIndex );
+ void SelectObject( INT32 nIndex );
+ CharSet GetCharSet(){ return maFont.GetCharSet(); };
+ void SetFont( const Font& rFont );
+ const Font& GetFont() const;
+ void SetTextLayoutMode( const sal_uInt32 nLayoutMode );
+ sal_uInt32 GetTextLayoutMode() const;
+
+ void ClearPath(){ aPathObj.Init(); };
+ void ClosePath(){ aPathObj.ClosePath(); };
+ const PolyPolygon& GetPathObj(){ return aPathObj; };
+
+ void MoveTo( const Point& rPoint, sal_Bool bRecordPath = sal_False );
+ void LineTo( const Point& rPoint, sal_Bool bRecordPath = sal_False );
+ void DrawPixel( const Point& rSource, const Color& rColor );
+ void DrawLine( const Point& rSource, const Point& rDest );
+ void DrawRect( const Rectangle& rRect, BOOL bEdge = TRUE );
+ void DrawRoundRect( const Rectangle& rRect, const Size& rSize );
+ void DrawEllipse( const Rectangle& rRect );
+ void DrawArc( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle, BOOL bDrawTo = FALSE );
+ void DrawPie( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle );
+ void DrawChord( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle );
+ void DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath = sal_False );
+ void DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordPath = sal_False );
+ void DrawPolyLine( Polygon& rPolygon, sal_Bool bDrawTo = sal_False, sal_Bool bRecordPath = sal_False );
+ void DrawPolyBezier( Polygon& rPolygin, sal_Bool bDrawTo = sal_False, sal_Bool bRecordPath = sal_False );
+ void DrawText( Point& rPosition, String& rString, sal_Int32* pDXArry = NULL, sal_Bool bRecordPath = sal_False,
+ sal_Int32 nGraphicsMode = GM_COMPATIBLE );
+ void ResolveBitmapActions( List& rSaveList );
+
+ void IntersectClipRect( const Rectangle& rRect );
+ void ExcludeClipRect( const Rectangle& rRect );
+ void MoveClipRegion( const Size& rSize );
+ void SetClipPath( const PolyPolygon& rPolyPoly, sal_Int32 nClippingMode, sal_Bool bIsMapped );
+ void UpdateClipRegion();
+ void AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile );
+
+ WinMtfOutput( GDIMetaFile& rGDIMetaFile );
+ virtual ~WinMtfOutput();
+};
+
+// -----------------------------------------------------------------------------
+
+class WinMtf
+{
+ protected:
+
+ WinMtfOutput* pOut; //
+ SvStream* pWMF; // Die einzulesende WMF/EMF-Datei
+
+ UINT32 nStartPos, nEndPos;
+ List aBmpSaveList;
+
+ FilterConfigItem* pFilterConfigItem;
+
+ com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
+
+ // Sorgt dafuer, das aSampledBrush der aktuelle Brush des GDIMetaFiles ist.
+
+ Color ReadColor();
+ void Callback( USHORT nPercent );
+
+ WinMtf( WinMtfOutput* pOut, SvStream& rStreamWMF, FilterConfigItem* pConfigItem = NULL );
+ ~WinMtf();
+
+ public:
+
+};
+
+//============================ EMFReader ==================================
+
+class EnhWMFReader : public WinMtf
+{
+ sal_Bool bRecordPath;
+ sal_Int32 nRecordCount;
+
+ BOOL ReadHeader();
+ Rectangle ReadRectangle( INT32, INT32, INT32, INT32 ); // Liesst und konvertiert ein Rechteck
+ void ImplExtTextOut( BOOL bWideCharakter );
+
+public:
+ EnhWMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, FilterConfigItem* pConfigItem = NULL )
+ : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ), bRecordPath( sal_False ) {};
+ ~EnhWMFReader();
+
+ BOOL ReadEnhWMF();
+};
+
+//============================ WMFReader ==================================
+
+class WMFReader : public WinMtf
+{
+private:
+
+ VirtualDevice aVDev; // just for the purpose of "IsFontAvailable"
+ UINT16 nUnitsPerInch;
+ sal_uInt32 nRecSize;
+
+ // embedded EMF data
+ SvMemoryStream* pEMFStream;
+
+ // total number of comment records containing EMF data
+ sal_uInt32 nEMFRecCount;
+
+ // number of EMF records read
+ sal_uInt32 nEMFRec;
+
+ // total size of embedded EMF data
+ sal_uInt32 nEMFSize;
+
+ sal_uInt32 nSkipActions;
+ sal_uInt32 nCurrentAction;
+ sal_uInt32 nUnicodeEscapeAction;
+
+ // Liesst den Kopf der WMF-Datei
+ BOOL ReadHeader();
+
+ // Liesst die Parameter des Rocords mit der Funktionsnummer nFunction.
+ void ReadRecordParams( USHORT nFunction );
+
+ Point ReadPoint(); // Liesst und konvertiert einen Punkt (erst X dann Y)
+ Point ReadYX(); // Liesst und konvertiert einen Punkt (erst Y dann X)
+ Rectangle ReadRectangle(); // Liesst und konvertiert ein Rechteck
+ Size ReadYXExt();
+ sal_Bool GetPlaceableBound( Rectangle& rSize, SvStream* pStrm );
+
+public:
+
+ WMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, FilterConfigItem* pConfigItem = NULL )
+ : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ) {};
+
+ ~WMFReader();
+
+ // Liesst aus dem Stream eine WMF-Datei und fuellt das GDIMetaFile
+ void ReadWMF();
+};
+
+#endif
+
+
diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter.vcl/wmf/winwmf.cxx
new file mode 100644
index 000000000000..f7c4f51ce1e2
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/winwmf.cxx
@@ -0,0 +1,1426 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "winmtf.hxx"
+#include <vcl/gdimtf.hxx>
+#include <rtl/crc.h>
+#include <rtl/tencinfo.h>
+#include <osl/endian.h>
+
+//====================== MS-Windows-defines ===============================
+
+#define W_META_SETBKCOLOR 0x0201
+#define W_META_SETBKMODE 0x0102
+#define W_META_SETMAPMODE 0x0103
+#define W_META_SETROP2 0x0104
+#define W_META_SETRELABS 0x0105
+#define W_META_SETPOLYFILLMODE 0x0106
+#define W_META_SETSTRETCHBLTMODE 0x0107
+#define W_META_SETTEXTCHAREXTRA 0x0108
+#define W_META_SETTEXTCOLOR 0x0209
+#define W_META_SETTEXTJUSTIFICATION 0x020A
+#define W_META_SETWINDOWORG 0x020B
+#define W_META_SETWINDOWEXT 0x020C
+#define W_META_SETVIEWPORTORG 0x020D
+#define W_META_SETVIEWPORTEXT 0x020E
+#define W_META_OFFSETWINDOWORG 0x020F
+#define W_META_SCALEWINDOWEXT 0x0410
+#define W_META_OFFSETVIEWPORTORG 0x0211
+#define W_META_SCALEVIEWPORTEXT 0x0412
+#define W_META_LINETO 0x0213
+#define W_META_MOVETO 0x0214
+#define W_META_EXCLUDECLIPRECT 0x0415
+#define W_META_INTERSECTCLIPRECT 0x0416
+#define W_META_ARC 0x0817
+#define W_META_ELLIPSE 0x0418
+#define W_META_FLOODFILL 0x0419
+#define W_META_PIE 0x081A
+#define W_META_RECTANGLE 0x041B
+#define W_META_ROUNDRECT 0x061C
+#define W_META_PATBLT 0x061D
+#define W_META_SAVEDC 0x001E
+#define W_META_SETPIXEL 0x041F
+#define W_META_OFFSETCLIPRGN 0x0220
+#define W_META_TEXTOUT 0x0521
+#define W_META_BITBLT 0x0922
+#define W_META_STRETCHBLT 0x0B23
+#define W_META_POLYGON 0x0324
+#define W_META_POLYLINE 0x0325
+#define W_META_ESCAPE 0x0626
+#define W_META_RESTOREDC 0x0127
+#define W_META_FILLREGION 0x0228
+#define W_META_FRAMEREGION 0x0429
+#define W_META_INVERTREGION 0x012A
+#define W_META_PAINTREGION 0x012B
+#define W_META_SELECTCLIPREGION 0x012C
+#define W_META_SELECTOBJECT 0x012D
+#define W_META_SETTEXTALIGN 0x012E
+#define W_META_DRAWTEXT 0x062F
+#define W_META_CHORD 0x0830
+#define W_META_SETMAPPERFLAGS 0x0231
+#define W_META_EXTTEXTOUT 0x0a32
+#define W_META_SETDIBTODEV 0x0d33
+#define W_META_SELECTPALETTE 0x0234
+#define W_META_REALIZEPALETTE 0x0035
+#define W_META_ANIMATEPALETTE 0x0436
+#define W_META_SETPALENTRIES 0x0037
+#define W_META_POLYPOLYGON 0x0538
+#define W_META_RESIZEPALETTE 0x0139
+#define W_META_DIBBITBLT 0x0940
+#define W_META_DIBSTRETCHBLT 0x0b41
+#define W_META_DIBCREATEPATTERNBRUSH 0x0142
+#define W_META_STRETCHDIB 0x0f43
+#define W_META_EXTFLOODFILL 0x0548
+#define W_META_RESETDC 0x014C
+#define W_META_STARTDOC 0x014D
+#define W_META_STARTPAGE 0x004F
+#define W_META_ENDPAGE 0x0050
+#define W_META_ABORTDOC 0x0052
+#define W_META_ENDDOC 0x005E
+#define W_META_DELETEOBJECT 0x01f0
+#define W_META_CREATEPALETTE 0x00f7
+#define W_META_CREATEBRUSH 0x00F8
+#define W_META_CREATEPATTERNBRUSH 0x01F9
+#define W_META_CREATEPENINDIRECT 0x02FA
+#define W_META_CREATEFONTINDIRECT 0x02FB
+#define W_META_CREATEBRUSHINDIRECT 0x02FC
+#define W_META_CREATEBITMAPINDIRECT 0x02FD
+#define W_META_CREATEBITMAP 0x06FE
+#define W_META_CREATEREGION 0x06FF
+
+//=================== Methoden von WMFReader ==============================
+
+inline Point WMFReader::ReadPoint()
+{
+ short nX, nY;
+ *pWMF >> nX >> nY;
+ return Point( nX, nY );
+}
+
+// ------------------------------------------------------------------------
+
+inline Point WMFReader::ReadYX()
+{
+ short nX, nY;
+ *pWMF >> nY >> nX;
+ return Point( nX, nY );
+}
+
+// ------------------------------------------------------------------------
+
+Rectangle WMFReader::ReadRectangle()
+{
+ Point aBR, aTL;
+ aBR = ReadYX();
+ aTL = ReadYX();
+ aBR.X()--;
+ aBR.Y()--;
+ return Rectangle( aTL, aBR );
+}
+
+// ------------------------------------------------------------------------
+
+Size WMFReader::ReadYXExt()
+{
+ short nW, nH;
+ *pWMF >> nH >> nW;
+ return Size( nW, nH );
+}
+
+// ------------------------------------------------------------------------
+
+void WMFReader::ReadRecordParams( USHORT nFunc )
+{
+ switch( nFunc )
+ {
+ case W_META_SETBKCOLOR:
+ {
+ pOut->SetBkColor( ReadColor() );
+ }
+ break;
+
+ case W_META_SETBKMODE:
+ {
+ USHORT nDat;
+ *pWMF >> nDat;
+ pOut->SetBkMode( nDat );
+ }
+ break;
+
+ // !!!
+ case W_META_SETMAPMODE:
+ {
+ sal_Int16 nMapMode;
+ *pWMF >> nMapMode;
+ pOut->SetMapMode( nMapMode );
+ }
+ break;
+
+ case W_META_SETROP2:
+ {
+ UINT16 nROP2;
+ *pWMF >> nROP2;
+ pOut->SetRasterOp( nROP2 );
+ }
+ break;
+
+ case W_META_SETTEXTCOLOR:
+ {
+ pOut->SetTextColor( ReadColor() );
+ }
+ break;
+
+ case W_META_SETWINDOWORG:
+ {
+ pOut->SetWinOrg( ReadYX() );
+ }
+ break;
+
+ case W_META_SETWINDOWEXT:
+ {
+ short nWidth, nHeight;
+ *pWMF >> nHeight >> nWidth;
+ pOut->SetWinExt( Size( nWidth, nHeight ) );
+ }
+ break;
+
+ case W_META_OFFSETWINDOWORG:
+ {
+ short nXAdd, nYAdd;
+ *pWMF >> nYAdd >> nXAdd;
+ pOut->SetWinOrgOffset( nXAdd, nYAdd );
+ }
+ break;
+
+ case W_META_SCALEWINDOWEXT:
+ {
+ short nXNum, nXDenom, nYNum, nYDenom;
+ *pWMF >> nYDenom >> nYNum >> nXDenom >> nXNum;
+ pOut->ScaleWinExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
+ }
+ break;
+
+ case W_META_SETVIEWPORTORG:
+ case W_META_SETVIEWPORTEXT:
+ break;
+
+ case W_META_OFFSETVIEWPORTORG:
+ {
+ short nXAdd, nYAdd;
+ *pWMF >> nYAdd >> nXAdd;
+ pOut->SetDevOrgOffset( nXAdd, nYAdd );
+ }
+ break;
+
+ case W_META_SCALEVIEWPORTEXT:
+ {
+ short nXNum, nXDenom, nYNum, nYDenom;
+ *pWMF >> nYDenom >> nYNum >> nXDenom >> nXNum;
+ pOut->ScaleDevExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
+ }
+ break;
+
+ case W_META_LINETO:
+ {
+ pOut->LineTo( ReadYX() );
+ }
+ break;
+
+ case W_META_MOVETO:
+ {
+ pOut->MoveTo( ReadYX() );
+ }
+ break;
+
+ case W_META_INTERSECTCLIPRECT:
+ {
+ pOut->IntersectClipRect( ReadRectangle() );
+ }
+ break;
+
+ case W_META_RECTANGLE:
+ {
+ pOut->DrawRect( ReadRectangle() );
+ }
+ break;
+
+ case W_META_ROUNDRECT:
+ {
+ Size aSize( ReadYXExt() );
+ pOut->DrawRoundRect( ReadRectangle(), Size( aSize.Width() / 2, aSize.Height() / 2 ) );
+ }
+ break;
+
+ case W_META_ELLIPSE:
+ {
+ pOut->DrawEllipse( ReadRectangle() );
+ }
+ break;
+
+ case W_META_ARC:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ Rectangle aRect( ReadRectangle() );
+ aRect.Justify();
+ pOut->DrawArc( aRect, aStart, aEnd );
+ }
+ break;
+
+ case W_META_PIE:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ Rectangle aRect( ReadRectangle() );
+ aRect.Justify();
+
+ // #i73608# OutputDevice deviates from WMF
+ // semantics. start==end means full ellipse here.
+ if( aStart == aEnd )
+ pOut->DrawEllipse( aRect );
+ else
+ pOut->DrawPie( aRect, aStart, aEnd );
+ }
+ break;
+
+ case W_META_CHORD:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ Rectangle aRect( ReadRectangle() );
+ aRect.Justify();
+ pOut->DrawChord( aRect, aStart, aEnd );
+ }
+ break;
+
+ case W_META_POLYGON:
+ {
+ USHORT i,nPoints;
+ *pWMF >> nPoints;
+ Polygon aPoly( nPoints );
+ for( i = 0; i < nPoints; i++ )
+ aPoly[ i ] = ReadPoint();
+ pOut->DrawPolygon( aPoly );
+ }
+ break;
+
+ case W_META_POLYPOLYGON:
+ {
+ USHORT i, nPoly, nPoints;
+ USHORT* pnPoints;
+ Point* pPtAry;
+ // Anzahl der Polygone:
+ *pWMF >> nPoly;
+ // Anzahl der Punkte eines jeden Polygons holen, Gesammtzahl der Punkte ermitteln:
+ pnPoints = new USHORT[ nPoly ];
+ nPoints = 0;
+ for( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> pnPoints[i];
+ nPoints = nPoints + pnPoints[i];
+ }
+ // Polygonpunkte holen:
+ pPtAry = (Point*) new char[ nPoints * sizeof(Point) ];
+ for ( i = 0; i < nPoints; i++ )
+ pPtAry[ i ] = ReadPoint();
+ // PolyPolygon Actions erzeugen
+ PolyPolygon aPolyPoly( nPoly, pnPoints, pPtAry );
+ pOut->DrawPolyPolygon( aPolyPoly );
+ delete[] (char*) pPtAry;
+ delete[] pnPoints;
+ }
+ break;
+
+ case W_META_POLYLINE:
+ {
+ USHORT i,nPoints;
+ *pWMF >> nPoints;
+ Polygon aPoly( nPoints );
+ for( i = 0; i < nPoints; i++ )
+ aPoly[ i ] = ReadPoint();
+ pOut->DrawPolyLine( aPoly );
+ }
+ break;
+
+ case W_META_SAVEDC:
+ {
+ pOut->Push();
+ }
+ break;
+
+ case W_META_RESTOREDC:
+ {
+ pOut->Pop();
+ }
+ break;
+
+ case W_META_SETPIXEL:
+ {
+ const Color aColor = ReadColor();
+ pOut->DrawPixel( ReadYX(), aColor );
+ }
+ break;
+
+ case W_META_OFFSETCLIPRGN:
+ {
+ pOut->MoveClipRegion( ReadYXExt() );
+ }
+ break;
+
+ case W_META_TEXTOUT:
+ {
+ USHORT nLength;
+ *pWMF >> nLength;
+ if ( nLength )
+ {
+ char* pChar = new char[ ( nLength + 1 ) &~ 1 ];
+ pWMF->Read( pChar, ( nLength + 1 ) &~ 1 );
+ String aText( pChar, nLength, pOut->GetCharSet() );
+ delete[] pChar;
+ Point aPosition( ReadYX() );
+ pOut->DrawText( aPosition, aText );
+ }
+ }
+ break;
+
+ case W_META_EXTTEXTOUT:
+ {
+ sal_Int16 nDx, nDxTmp;
+ sal_uInt16 i, nLen, nOptions;
+ sal_Int32 nRecordPos, nRecordSize, nOriginalTextLen, nNewTextLen;
+ Point aPosition;
+ Rectangle aRect;
+ sal_Int32* pDXAry = NULL;
+
+ pWMF->SeekRel(-6);
+ nRecordPos = pWMF->Tell();
+ *pWMF >> nRecordSize;
+ pWMF->SeekRel(2);
+ aPosition = ReadYX();
+ *pWMF >> nLen >> nOptions;
+
+ sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT;
+ if ( nOptions & ETO_RTLREADING )
+ nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
+ pOut->SetTextLayoutMode( nTextLayoutMode );
+ DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in WMF" );
+
+ // Nur wenn der Text auch Zeichen enthaelt, macht die Ausgabe Sinn
+ if( nLen )
+ {
+ nOriginalTextLen = nLen;
+ if( nOptions & ETO_CLIPPED )
+ {
+ const Point aPt1( ReadPoint() );
+ const Point aPt2( ReadPoint() );
+ aRect = Rectangle( aPt1, aPt2 );
+ }
+ char* pChar = new char[ ( nOriginalTextLen + 1 ) &~ 1 ];
+ pWMF->Read( pChar, ( nOriginalTextLen + 1 ) &~ 1 );
+ String aText( pChar, (sal_uInt16)nOriginalTextLen, pOut->GetCharSet() );// after this conversion the text may contain
+ nNewTextLen = aText.Len(); // less character (japanese version), so the
+ delete[] pChar; // dxAry will not fit
+
+ if ( nNewTextLen )
+ {
+ sal_uInt32 nMaxStreamPos = nRecordPos + ( nRecordSize << 1 );
+ sal_Int32 nDxArySize = nMaxStreamPos - pWMF->Tell();
+ sal_Int32 nDxAryEntries = nDxArySize >> 1;
+ sal_Bool bUseDXAry = FALSE;
+
+ if ( ( ( nDxAryEntries % nOriginalTextLen ) == 0 ) && ( nNewTextLen <= nOriginalTextLen ) )
+ {
+ pDXAry = new sal_Int32[ nNewTextLen ];
+ for ( i = 0; i < nNewTextLen; i++ )
+ {
+ if ( pWMF->Tell() >= nMaxStreamPos )
+ break;
+ *pWMF >> nDx;
+ if ( nNewTextLen != nOriginalTextLen )
+ {
+ ByteString aTmp( aText.GetChar( i ), pOut->GetCharSet() );
+ if ( aTmp.Len() > 1 )
+ {
+ sal_Int32 nDxCount = aTmp.Len() - 1;
+ if ( ( ( nDxCount * 2 ) + pWMF->Tell() ) > nMaxStreamPos )
+ break;
+ while ( nDxCount-- )
+ {
+ *pWMF >> nDxTmp;
+ nDx = nDx + nDxTmp;
+ }
+ }
+ }
+ pDXAry[ i ] = nDx;
+ }
+ if ( i == nNewTextLen )
+ bUseDXAry = TRUE;
+ }
+ if ( pDXAry && bUseDXAry )
+ pOut->DrawText( aPosition, aText, pDXAry );
+ else
+ pOut->DrawText( aPosition, aText );
+ }
+ }
+ delete[] pDXAry;
+
+ }
+ break;
+
+ case W_META_SELECTOBJECT:
+ {
+ INT16 nObjIndex;
+ *pWMF >> nObjIndex;
+ pOut->SelectObject( nObjIndex );
+ }
+ break;
+
+ case W_META_SETTEXTALIGN:
+ {
+ UINT16 nAlign;
+ *pWMF >> nAlign;
+ pOut->SetTextAlign( nAlign );
+ }
+ break;
+
+ case W_META_BITBLT:
+ {
+ // 0-3 : nWinROP #93454#
+ // 4-5 : y offset of source bitmap
+ // 6-7 : x offset of source bitmap
+ // 8-9 : used height of source bitmap
+ // 10-11 : used width of source bitmap
+ // 12-13 : destination position y (in pixel)
+ // 14-15 : destination position x (in pixel)
+ // 16-17 : dont know
+ // 18-19 : Width Bitmap in Pixel
+ // 20-21 : Height Bitmap in Pixel
+ // 22-23 : bytes per scanline
+ // 24 : planes
+ // 25 : bitcount
+
+ sal_Int32 nWinROP;
+ sal_uInt16 nSx, nSy, nSxe, nSye, nDontKnow, nWidth, nHeight, nBytesPerScan;
+ sal_uInt8 nPlanes, nBitCount;
+
+ *pWMF >> nWinROP
+ >> nSy >> nSx >> nSye >> nSxe;
+ Point aPoint( ReadYX() );
+ *pWMF >> nDontKnow >> nWidth >> nHeight >> nBytesPerScan >> nPlanes >> nBitCount;
+
+ if ( nWidth && nHeight && ( nPlanes == 1 ) && ( nBitCount == 1 ) )
+ {
+ Bitmap aBmp( Size( nWidth, nHeight ), nBitCount );
+ BitmapWriteAccess* pAcc;
+ pAcc = aBmp.AcquireWriteAccess();
+ if ( pAcc )
+ {
+ sal_uInt16 y, x, scan;
+ sal_Int8 i, nEightPixels;
+ for ( y = 0; y < nHeight; y++ )
+ {
+ x = 0;
+ for ( scan = 0; scan < nBytesPerScan; scan++ )
+ {
+ *pWMF >> nEightPixels;
+ for ( i = 7; i >= 0; i-- )
+ {
+ if ( x < nWidth )
+ {
+ pAcc->SetPixel( y, x, (nEightPixels>>i)&1 );
+ }
+ x++;
+ }
+ }
+ }
+ aBmp.ReleaseAccess( pAcc );
+ if ( nSye && nSxe &&
+ ( ( nSx + nSxe ) <= aBmp.GetSizePixel().Width() ) &&
+ ( ( nSy + nSye <= aBmp.GetSizePixel().Height() ) ) )
+ {
+ Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
+ aBmp.Crop( aCropRect );
+ }
+ Rectangle aDestRect( aPoint, Size( nSxe, nSye ) );
+ aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
+ }
+ }
+ }
+ break;
+
+ case W_META_STRETCHBLT:
+ case W_META_DIBBITBLT:
+ case W_META_DIBSTRETCHBLT:
+ case W_META_STRETCHDIB:
+ {
+ sal_Int32 nWinROP;
+ sal_uInt16 nSx, nSy, nSxe, nSye, nUsage;
+ Bitmap aBmp;
+
+ *pWMF >> nWinROP;
+
+ if( nFunc == W_META_STRETCHDIB )
+ *pWMF >> nUsage;
+
+ // nSye and nSxe is the number of pixels that has to been used
+ if( nFunc == W_META_STRETCHDIB || nFunc == W_META_STRETCHBLT || nFunc == W_META_DIBSTRETCHBLT )
+ *pWMF >> nSye >> nSxe;
+ else
+ nSye = nSxe = 0; // set this to zero as indicator not to scale the bitmap later
+
+ // nSy and nx is the offset of the first pixel
+ *pWMF >> nSy >> nSx;
+
+ if( nFunc == W_META_STRETCHDIB || nFunc == W_META_DIBBITBLT || nFunc == W_META_DIBSTRETCHBLT )
+ {
+ if ( nWinROP == PATCOPY )
+ *pWMF >> nUsage; // i don't know anything of this parameter, so its called nUsage
+ // pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), FALSE );
+
+ Size aDestSize( ReadYXExt() );
+ if ( aDestSize.Width() && aDestSize.Height() ) // #92623# do not try to read buggy bitmaps
+ {
+ Rectangle aDestRect( ReadYX(), aDestSize );
+ if ( nWinROP != PATCOPY )
+ aBmp.Read( *pWMF, FALSE );
+
+ // test if it is sensible to crop
+ if ( nSye && nSxe &&
+ ( ( nSx + nSxe ) <= aBmp.GetSizePixel().Width() ) &&
+ ( ( nSy + nSye <= aBmp.GetSizePixel().Height() ) ) )
+ {
+ Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
+ aBmp.Crop( aCropRect );
+ }
+ aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
+ }
+ }
+ }
+ break;
+
+ case W_META_DIBCREATEPATTERNBRUSH:
+ {
+ Bitmap aBmp;
+ BitmapReadAccess* pBmp;
+ UINT32 nRed = 0, nGreen = 0, nBlue = 0, nCount = 1;
+ UINT16 nFunction;
+
+ *pWMF >> nFunction >> nFunction;
+
+ aBmp.Read( *pWMF, FALSE );
+ pBmp = aBmp.AcquireReadAccess();
+ if ( pBmp )
+ {
+ for ( INT32 y = 0; y < pBmp->Height(); y++ )
+ {
+ for ( INT32 x = 0; x < pBmp->Width(); x++ )
+ {
+ const BitmapColor aColor( pBmp->GetColor( y, x ) );
+
+ nRed += aColor.GetRed();
+ nGreen += aColor.GetGreen();
+ nBlue += aColor.GetBlue();
+ }
+ }
+ nCount = pBmp->Height() * pBmp->Width();
+ if ( !nCount )
+ nCount++;
+ aBmp.ReleaseAccess( pBmp );
+ }
+ Color aColor( (BYTE)( nRed / nCount ), (BYTE)( nGreen / nCount ), (BYTE)( nBlue / nCount ) );
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( aColor, FALSE ) );
+ }
+ break;
+
+ case W_META_DELETEOBJECT:
+ {
+ INT16 nIndex;
+ *pWMF >> nIndex;
+ pOut->DeleteObject( nIndex );
+ }
+ break;
+
+ case W_META_CREATEPALETTE:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_CREATEBRUSH:
+ {
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), FALSE ) );
+ }
+ break;
+
+ case W_META_CREATEPATTERNBRUSH:
+ {
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), FALSE ) );
+ }
+ break;
+
+ case W_META_CREATEPENINDIRECT:
+ {
+ LineInfo aLineInfo;
+ USHORT nStyle, nWidth, nHeight;
+
+ *pWMF >> nStyle >> nWidth >> nHeight;
+
+ if ( nWidth )
+ aLineInfo.SetWidth( nWidth );
+
+ BOOL bTransparent = FALSE;
+ UINT16 nDashCount = 0;
+ UINT16 nDotCount = 0;
+ switch( nStyle )
+ {
+ case PS_DASHDOTDOT :
+ nDotCount++;
+ case PS_DASHDOT :
+ nDashCount++;
+ case PS_DOT :
+ nDotCount++;
+ break;
+ case PS_DASH :
+ nDashCount++;
+ break;
+ case PS_NULL :
+ bTransparent = TRUE;
+ aLineInfo.SetStyle( LINE_NONE );
+ break;
+ default :
+ case PS_INSIDEFRAME :
+ case PS_SOLID :
+ aLineInfo.SetStyle( LINE_SOLID );
+ }
+ if ( nDashCount | nDotCount )
+ {
+ aLineInfo.SetStyle( LINE_DASH );
+ aLineInfo.SetDashCount( nDashCount );
+ aLineInfo.SetDotCount( nDotCount );
+ }
+ pOut->CreateObject( GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
+ }
+ break;
+
+ case W_META_CREATEBRUSHINDIRECT:
+ {
+ USHORT nStyle;
+ *pWMF >> nStyle;
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? TRUE : FALSE ) );
+ }
+ break;
+
+ case W_META_CREATEFONTINDIRECT:
+ {
+ Size aFontSize;
+ char lfFaceName[ LF_FACESIZE ];
+ INT16 lfEscapement, lfOrientation, lfWeight; // ( ehemals USHORT )
+
+ LOGFONTW aLogFont;
+ aFontSize = ReadYXExt();
+ *pWMF >> lfEscapement >> lfOrientation >> lfWeight
+ >> aLogFont.lfItalic >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision
+ >> aLogFont.lfClipPrecision >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily;
+ pWMF->Read( lfFaceName, LF_FACESIZE );
+ aLogFont.lfWidth = aFontSize.Width();
+ aLogFont.lfHeight = aFontSize.Height();
+ aLogFont.lfEscapement = lfEscapement;
+ aLogFont.lfOrientation = lfOrientation;
+ aLogFont.lfWeight = lfWeight;
+
+ CharSet eCharSet;
+ if ( ( aLogFont.lfCharSet == OEM_CHARSET ) || ( aLogFont.lfCharSet == DEFAULT_CHARSET ) )
+ eCharSet = gsl_getSystemTextEncoding();
+ else
+ eCharSet = rtl_getTextEncodingFromWindowsCharset( aLogFont.lfCharSet );
+ if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
+ eCharSet = gsl_getSystemTextEncoding();
+ if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
+ eCharSet = RTL_TEXTENCODING_MS_1252;
+ aLogFont.alfFaceName = UniString( lfFaceName, eCharSet );
+
+ pOut->CreateObject( GDI_FONT, new WinMtfFontStyle( aLogFont ) );
+ }
+ break;
+
+ case W_META_CREATEBITMAPINDIRECT:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_CREATEBITMAP:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_CREATEREGION:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_EXCLUDECLIPRECT :
+ {
+ pOut->ExcludeClipRect( ReadRectangle() );
+ }
+ break;
+
+ case W_META_PATBLT:
+ {
+ UINT32 nROP, nOldROP;
+ *pWMF >> nROP;
+ Size aSize = ReadYXExt();
+ nOldROP = pOut->SetRasterOp( nROP );
+ pOut->DrawRect( Rectangle( ReadYX(), aSize ), FALSE );
+ pOut->SetRasterOp( nOldROP );
+ }
+ break;
+
+ case W_META_SELECTCLIPREGION:
+ {
+ sal_Int16 nObjIndex;
+ *pWMF >> nObjIndex;
+ if ( !nObjIndex )
+ {
+ PolyPolygon aEmptyPolyPoly;
+ pOut->SetClipPath( aEmptyPolyPoly, RGN_COPY, sal_True );
+ }
+ }
+ break;
+
+ case W_META_ESCAPE :
+ {
+ // nRecSize has been checked previously to be greater than 3
+ sal_uInt64 nMetaRecSize = static_cast< sal_uInt64 >( nRecSize - 2 ) * 2;
+ sal_uInt64 nMetaRecEndPos = pWMF->Tell() + nMetaRecSize;
+
+ // taking care that nRecSize does not exceed the maximal stream position
+ if ( nMetaRecEndPos > nEndPos )
+ {
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ break;
+ }
+ if ( nRecSize >= 4 ) // minimal escape lenght
+ {
+ sal_uInt16 nMode, nLen;
+ *pWMF >> nMode
+ >> nLen;
+ if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 4 ) )
+ {
+ sal_uInt32 nNewMagic; // we have to read int32 for
+ *pWMF >> nNewMagic; // META_ESCAPE_ENHANCED_METAFILE CommentIdentifier
+
+ if( nNewMagic == 0x2c2a4f4f && nLen >= 14 )
+ {
+ sal_uInt16 nMagic2;
+ *pWMF >> nMagic2;
+ if( nMagic2 == 0x0a ) // 2nd half of magic
+ { // continue with private escape
+ sal_uInt32 nCheck, nEsc;
+ *pWMF >> nCheck
+ >> nEsc;
+
+ sal_uInt32 nEscLen = nLen - 14;
+ if ( nEscLen <= ( nRecSize * 2 ) )
+ {
+#ifdef OSL_BIGENDIAN
+ sal_uInt32 nTmp = SWAPLONG( nEsc );
+ sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
+#else
+ sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
+#endif
+ sal_Int8* pData = NULL;
+
+ if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos )
+ {
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ break;
+ }
+ if ( nEscLen > 0 )
+ {
+ pData = new sal_Int8[ nEscLen ];
+ pWMF->Read( pData, nEscLen );
+ nCheckSum = rtl_crc32( nCheckSum, pData, nEscLen );
+ }
+ if ( nCheck == nCheckSum )
+ {
+ switch( nEsc )
+ {
+ case PRIVATE_ESCAPE_UNICODE :
+ { // we will use text instead of polygons only if we have the correct font
+ if ( aVDev.IsFontAvailable( pOut->GetFont().GetName() ) )
+ {
+ Point aPt;
+ String aString;
+ sal_uInt32 i, nStringLen, nDXCount;
+ sal_Int32* pDXAry = NULL;
+ SvMemoryStream aMemoryStream( nEscLen );
+ aMemoryStream.Write( pData, nEscLen );
+ aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN );
+ aMemoryStream >> aPt.X()
+ >> aPt.Y()
+ >> nStringLen;
+
+ if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) )
+ {
+ sal_Unicode* pBuf = aString.AllocBuffer( (xub_StrLen)nStringLen );
+ for ( i = 0; i < nStringLen; i++ )
+ aMemoryStream >> pBuf[ i ];
+ aMemoryStream >> nDXCount;
+ if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) )
+ nDXCount = 0;
+ if ( nDXCount )
+ pDXAry = new sal_Int32[ nDXCount ];
+ for ( i = 0; i < nDXCount; i++ )
+ aMemoryStream >> pDXAry[ i ];
+ aMemoryStream >> nSkipActions;
+ pOut->DrawText( aPt, aString, pDXAry );
+ delete[] pDXAry;
+ }
+ }
+ }
+ break;
+ }
+ }
+ delete[] pData;
+ }
+ }
+ }
+ else if ( (nNewMagic == static_cast< sal_uInt32 >(0x43464D57)) && (nLen >= 34) && ( (sal_Int32)(nLen + 10) <= (sal_Int32)(nRecSize * 2) ))
+ {
+ sal_uInt32 nComType, nVersion, nFlags, nComRecCount,
+ nCurRecSize, nRemainingSize, nEMFTotalSize;
+ sal_uInt16 nCheck;
+
+ *pWMF >> nComType >> nVersion >> nCheck >> nFlags
+ >> nComRecCount >> nCurRecSize
+ >> nRemainingSize >> nEMFTotalSize; // the nRemainingSize is not mentioned in MSDN documentation
+ // but it seems to be required to read in data produced by OLE
+
+ if( nComType == 0x01 && nVersion == 0x10000 && nComRecCount )
+ {
+ if( !nEMFRec )
+ { // first EMF comment
+ nEMFRecCount = nComRecCount;
+ nEMFSize = nEMFTotalSize;
+ pEMFStream = new SvMemoryStream( nEMFSize );
+ }
+ else if( ( nEMFRecCount != nComRecCount ) || ( nEMFSize != nEMFTotalSize ) ) // add additional checks here
+ {
+ // total records should be the same as in previous comments
+ nEMFRecCount = 0xFFFFFFFF;
+ delete pEMFStream;
+ pEMFStream = NULL;
+ }
+ nEMFRec++;
+
+ if( pEMFStream && nCurRecSize + 34 > nLen )
+ {
+ nEMFRecCount = 0xFFFFFFFF;
+ delete pEMFStream;
+ pEMFStream = NULL;
+ }
+
+ if( pEMFStream )
+ {
+ sal_Int8* pBuf = new sal_Int8[ nCurRecSize ];
+ sal_uInt32 nCount = pWMF->Read( pBuf, nCurRecSize );
+ if( nCount == nCurRecSize )
+ pEMFStream->Write( pBuf, nCount );
+ delete[] pBuf;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case W_META_SETRELABS:
+ case W_META_SETPOLYFILLMODE:
+ case W_META_SETSTRETCHBLTMODE:
+ case W_META_SETTEXTCHAREXTRA:
+ case W_META_SETTEXTJUSTIFICATION:
+ case W_META_FLOODFILL :
+ case W_META_FILLREGION:
+ case W_META_FRAMEREGION:
+ case W_META_INVERTREGION:
+ case W_META_PAINTREGION:
+ case W_META_DRAWTEXT:
+ case W_META_SETMAPPERFLAGS:
+ case W_META_SETDIBTODEV:
+ case W_META_SELECTPALETTE:
+ case W_META_REALIZEPALETTE:
+ case W_META_ANIMATEPALETTE:
+ case W_META_SETPALENTRIES:
+ case W_META_RESIZEPALETTE:
+ case W_META_EXTFLOODFILL:
+ case W_META_RESETDC:
+ case W_META_STARTDOC:
+ case W_META_STARTPAGE:
+ case W_META_ENDPAGE:
+ case W_META_ABORTDOC:
+ case W_META_ENDDOC:
+ break;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL WMFReader::ReadHeader()
+{
+ Rectangle aPlaceableBound;
+ sal_uInt32 nl, nStrmPos = pWMF->Tell();
+
+ // Einlesen des METAFILEHEADER, falls vorhanden
+ *pWMF >> nl;
+
+ Size aWMFSize;
+ if ( nl == 0x9ac6cdd7L )
+ {
+ INT16 nVal;
+
+ // hmf (Unused) ueberlesen wir
+ pWMF->SeekRel(2);
+
+ // BoundRect
+ *pWMF >> nVal; aPlaceableBound.Left() = nVal;
+ *pWMF >> nVal; aPlaceableBound.Top() = nVal;
+ *pWMF >> nVal; aPlaceableBound.Right() = nVal;
+ *pWMF >> nVal; aPlaceableBound.Bottom() = nVal;
+
+ // inch
+ *pWMF >> nUnitsPerInch;
+
+ // reserved
+ pWMF->SeekRel( 4 );
+
+ // checksum pruefen wir lieber nicht
+ pWMF->SeekRel( 2 );
+ }
+ else
+ {
+ nUnitsPerInch = 96;
+ pWMF->Seek( nStrmPos + 18 ); // set the streampos to the start of the the metaactions
+ GetPlaceableBound( aPlaceableBound, pWMF );
+ pWMF->Seek( nStrmPos );
+ }
+
+ pOut->SetWinOrg( aPlaceableBound.TopLeft() );
+ aWMFSize = Size( labs( aPlaceableBound.GetWidth() ), labs( aPlaceableBound.GetHeight() ) );
+ pOut->SetWinExt( aWMFSize );
+
+ Size aDevExt( 10000, 10000 );
+ if( ( labs( aWMFSize.Width() ) > 1 ) && ( labs( aWMFSize.Height() ) > 1 ) )
+ {
+ const Fraction aFrac( 1, nUnitsPerInch );
+ MapMode aWMFMap( MAP_INCH, Point(), aFrac, aFrac );
+ Size aSize100( OutputDevice::LogicToLogic( aWMFSize, aWMFMap, MAP_100TH_MM ) );
+ aDevExt = Size( labs( aSize100.Width() ), labs( aSize100.Height() ) );
+ }
+ pOut->SetDevExt( aDevExt );
+
+ // Einlesen des METAHEADER
+ *pWMF >> nl; // Typ und Headergroesse
+
+ if( nl != 0x00090001 )
+ {
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return FALSE;
+ }
+
+ pWMF->SeekRel( 2 ); // Version (von Windows)
+ pWMF->SeekRel( 4 ); // Size (der Datei in Words)
+ pWMF->SeekRel( 2 ); // NoObjects (Maximale Anzahl der gleichzeitigen Objekte)
+ pWMF->SeekRel( 4 ); // MaxRecord (Groesse des groessten Records in Words)
+ pWMF->SeekRel( 2 ); // NoParameters (Unused
+
+ return TRUE;
+}
+
+void WMFReader::ReadWMF()
+{
+ USHORT nFunction;
+ ULONG nPos, nPercent, nLastPercent;
+
+ nSkipActions = 0;
+ nCurrentAction = 0;
+ nUnicodeEscapeAction = 0;
+
+ pEMFStream = NULL;
+ nEMFRecCount = 0;
+ nEMFRec = 0;
+ nEMFSize = 0;
+
+ pOut->SetMapMode( MM_ANISOTROPIC );
+ pOut->SetWinOrg( Point() );
+ pOut->SetWinExt( Size( 1, 1 ) );
+ pOut->SetDevExt( Size( 10000, 10000 ) );
+
+ nEndPos=pWMF->Seek( STREAM_SEEK_TO_END );
+ pWMF->Seek( nStartPos );
+ Callback( (USHORT) ( nLastPercent = 0 ) );
+
+ if ( ReadHeader() )
+ {
+
+ nPos = pWMF->Tell();
+
+ if( nEndPos - nStartPos )
+ {
+ while( TRUE )
+ {
+ nCurrentAction++;
+ nPercent = ( nPos - nStartPos ) * 100 / ( nEndPos - nStartPos );
+
+ if( nLastPercent + 4 <= nPercent )
+ {
+ Callback( (USHORT) nPercent );
+ nLastPercent = nPercent;
+ }
+ *pWMF >> nRecSize >> nFunction;
+
+ if( pWMF->GetError() || ( nRecSize < 3 ) || ( nRecSize==3 && nFunction==0 ) || pWMF->IsEof() )
+ {
+
+ if( pWMF->IsEof() )
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ break;
+ }
+ if( aBmpSaveList.Count() &&
+ ( nFunction != W_META_STRETCHDIB ) &&
+ ( nFunction != W_META_DIBBITBLT ) &&
+ ( nFunction != W_META_DIBSTRETCHBLT ) )
+ {
+ pOut->ResolveBitmapActions( aBmpSaveList );
+ }
+ if ( !nSkipActions )
+ ReadRecordParams( nFunction );
+ else
+ nSkipActions--;
+
+ if( pEMFStream && nEMFRecCount == nEMFRec )
+ {
+ GDIMetaFile aMeta;
+ pEMFStream->Seek( 0 );
+ EnhWMFReader* pEMFReader = new EnhWMFReader ( *pEMFStream, aMeta );
+ BOOL bRead = pEMFReader->ReadEnhWMF();
+ delete pEMFReader; // destroy first!!!
+
+ if( bRead )
+ {
+ pOut->AddFromGDIMetaFile( aMeta );
+ pOut->SetrclFrame( Rectangle(0, 0, aMeta.GetPrefSize().Width(), aMeta.GetPrefSize().Height() ));
+ // we have successfully read the embedded EMF data
+ // no need to process WMF data further
+ break;
+ }
+ else
+ {
+ // something went wrong
+ // continue with WMF, don't try this again
+ delete pEMFStream;
+ pEMFStream = NULL;
+ }
+
+ }
+
+ nPos += nRecSize * 2;
+ if ( nPos <= nEndPos )
+ pWMF->Seek( nPos );
+ else
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ }
+ }
+ else
+ pWMF->SetError( SVSTREAM_GENERALERROR );
+
+ if( !pWMF->GetError() && aBmpSaveList.Count() )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+ }
+ if ( pWMF->GetError() )
+ pWMF->Seek( nStartPos );
+}
+
+// ------------------------------------------------------------------------
+
+static void GetWinExtMax( const Point& rSource, Rectangle& rPlaceableBound, const sal_Int16 nMapMode )
+{
+ Point aSource( rSource );
+ if ( nMapMode == MM_HIMETRIC )
+ aSource.Y() = -rSource.Y();
+ if ( aSource.X() < rPlaceableBound.Left() )
+ rPlaceableBound.Left() = aSource.X();
+ if ( aSource.X() > rPlaceableBound.Right() )
+ rPlaceableBound.Right() = aSource.X();
+ if ( aSource.Y() < rPlaceableBound.Top() )
+ rPlaceableBound.Top() = aSource.Y();
+ if ( aSource.Y() > rPlaceableBound.Bottom() )
+ rPlaceableBound.Bottom() = aSource.Y();
+}
+
+static void GetWinExtMax( const Rectangle& rSource, Rectangle& rPlaceableBound, const sal_Int16 nMapMode )
+{
+ GetWinExtMax( rSource.TopLeft(), rPlaceableBound, nMapMode );
+ GetWinExtMax( rSource.BottomRight(), rPlaceableBound, nMapMode );
+}
+
+sal_Bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pStm )
+{
+ sal_Bool bRet = sal_True;
+
+ rPlaceableBound.Left() = (sal_Int32)0x7fffffff;
+ rPlaceableBound.Top() = (sal_Int32)0x7fffffff;
+ rPlaceableBound.Right() = (sal_Int32)0x80000000;
+ rPlaceableBound.Bottom() = (sal_Int32)0x80000000;
+
+ sal_Int16 nMapMode = MM_ANISOTROPIC;
+
+ sal_uInt16 nFunction;
+ sal_uInt32 nRSize;
+ sal_uInt32 nPos = pStm->Tell();
+ sal_uInt32 nEnd = pStm->Seek( STREAM_SEEK_TO_END );
+
+ pStm->Seek( nPos );
+
+ if( nEnd - nPos )
+ {
+ while( bRet )
+ {
+ *pStm >> nRSize >> nFunction;
+
+ if( pStm->GetError() || ( nRSize < 3 ) || ( nRSize==3 && nFunction==0 ) || pStm->IsEof() )
+ {
+ if( pStm->IsEof() )
+ {
+ pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ bRet = sal_False;
+ }
+ break;
+ }
+ switch( nFunction )
+ {
+ case W_META_SETWINDOWORG:
+ {
+ Point aWinOrg;
+ aWinOrg = ReadYX();
+ rPlaceableBound.SetPos( aWinOrg );
+ }
+ break;
+
+ case W_META_SETWINDOWEXT:
+ {
+ Point aPos0( 0, 0 );
+ sal_Int16 nWidth, nHeight;
+ *pStm >> nHeight >> nWidth;
+ rPlaceableBound.SetSize( Size( nWidth, nHeight ) );
+ }
+ break;
+
+ case W_META_SETMAPMODE :
+ *pStm >> nMapMode;
+ break;
+
+ case W_META_MOVETO:
+ case W_META_LINETO:
+ GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
+ break;
+
+ case W_META_RECTANGLE:
+ case W_META_INTERSECTCLIPRECT:
+ case W_META_EXCLUDECLIPRECT :
+ case W_META_ELLIPSE:
+ GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
+ break;
+
+ case W_META_ROUNDRECT:
+ {
+ Size aSize( ReadYXExt() );
+ GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
+ }
+ break;
+
+ case W_META_ARC:
+ case W_META_PIE:
+ case W_META_CHORD:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
+ }
+ break;
+
+ case W_META_POLYGON:
+ {
+ USHORT i,nPoints;
+ *pStm >> nPoints;
+ for( i = 0; i < nPoints; i++ )
+ GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
+ }
+ break;
+
+ case W_META_POLYPOLYGON:
+ {
+ USHORT i, nPoly, nPoints = 0;
+ *pStm >> nPoly;
+ for( i = 0; i < nPoly; i++ )
+ {
+ sal_uInt16 nP;
+ *pStm >> nP;
+ nPoints = nPoints + nP;
+ }
+ for ( i = 0; i < nPoints; i++ )
+ GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
+ }
+ break;
+
+ case W_META_POLYLINE:
+ {
+ USHORT i,nPoints;
+ *pStm >> nPoints;
+ for( i = 0; i < nPoints; i++ )
+ GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
+ }
+ break;
+
+ case W_META_SETPIXEL:
+ {
+ const Color aColor = ReadColor();
+ GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
+ }
+ break;
+
+ case W_META_TEXTOUT:
+ {
+ USHORT nLength;
+ *pStm >> nLength;
+ // todo: we also have to take care of the text width
+ if ( nLength )
+ {
+ pStm->SeekRel( ( nLength + 1 ) &~ 1 );
+ GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
+ }
+ }
+ break;
+
+ case W_META_EXTTEXTOUT:
+ {
+ sal_uInt16 nLen, nOptions;
+ sal_Int32 nRecordPos, nRecordSize;
+ Point aPosition;
+ Rectangle aRect;
+
+ pStm->SeekRel(-6);
+ nRecordPos = pStm->Tell();
+ *pStm >> nRecordSize;
+ pStm->SeekRel(2);
+ aPosition = ReadYX();
+ *pStm >> nLen >> nOptions;
+ // todo: we also have to take care of the text width
+ if( nLen )
+ GetWinExtMax( aPosition, rPlaceableBound, nMapMode );
+ }
+ break;
+ case W_META_BITBLT:
+ case W_META_STRETCHBLT:
+ case W_META_DIBBITBLT:
+ case W_META_DIBSTRETCHBLT:
+ case W_META_STRETCHDIB:
+ {
+ sal_Int32 nWinROP;
+ sal_uInt16 nSx, nSy, nSxe, nSye, nUsage;
+ *pStm >> nWinROP;
+
+ if( nFunction == W_META_STRETCHDIB )
+ *pStm >> nUsage;
+
+ // nSye and nSxe is the number of pixels that has to been used
+ if( nFunction == W_META_STRETCHDIB || nFunction == W_META_STRETCHBLT || nFunction == W_META_DIBSTRETCHBLT )
+ *pStm >> nSye >> nSxe;
+ else
+ nSye = nSxe = 0; // set this to zero as indicator not to scale the bitmap later
+
+ // nSy and nx is the offset of the first pixel
+ *pStm >> nSy >> nSx;
+
+ if( nFunction == W_META_STRETCHDIB || nFunction == W_META_DIBBITBLT || nFunction == W_META_DIBSTRETCHBLT )
+ {
+ if ( nWinROP == PATCOPY )
+ *pStm >> nUsage; // i don't know anything of this parameter, so its called nUsage
+ // pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), FALSE );
+
+ Size aDestSize( ReadYXExt() );
+ if ( aDestSize.Width() && aDestSize.Height() ) // #92623# do not try to read buggy bitmaps
+ {
+ Rectangle aDestRect( ReadYX(), aDestSize );
+ GetWinExtMax( aDestRect, rPlaceableBound, nMapMode );
+ }
+ }
+ }
+ break;
+
+ case W_META_PATBLT:
+ {
+ UINT32 nROP;
+ *pStm >> nROP;
+ Size aSize = ReadYXExt();
+ GetWinExtMax( Rectangle( ReadYX(), aSize ), rPlaceableBound, nMapMode );
+ }
+ break;
+ }
+ nPos += nRSize * 2;
+ if ( nPos <= nEnd )
+ pStm->Seek( nPos );
+ else
+ {
+ pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ bRet = sal_False;
+ }
+
+ }
+ }
+ else
+ {
+ pStm->SetError( SVSTREAM_GENERALERROR );
+ bRet = sal_False;
+ }
+ return bRet;
+}
+
+WMFReader::~WMFReader()
+{
+ if( pEMFStream )
+ delete pEMFStream;
+}
+
diff --git a/svtools/source/filter.vcl/wmf/wmf.cxx b/svtools/source/filter.vcl/wmf/wmf.cxx
new file mode 100644
index 000000000000..25ca9f721b33
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/wmf.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "winmtf.hxx"
+#include "emfwr.hxx"
+#include "wmfwr.hxx"
+#include <svtools/wmf.hxx>
+
+// -----------------------------------------------------------------------------
+
+BOOL ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem )
+{
+ UINT32 nMetaType;
+ UINT32 nOrgPos = rStreamWMF.Tell();
+ UINT16 nOrigNumberFormat = rStreamWMF.GetNumberFormatInt();
+ rStreamWMF.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStreamWMF.Seek( 0x28 );
+ rStreamWMF >> nMetaType;
+ rStreamWMF.Seek( nOrgPos );
+ if ( nMetaType == 0x464d4520 )
+ {
+ if ( EnhWMFReader( rStreamWMF, rGDIMetaFile, pConfigItem ).ReadEnhWMF() == FALSE )
+ rStreamWMF.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ }
+ else
+ {
+ WMFReader( rStreamWMF, rGDIMetaFile, pConfigItem ).ReadWMF();
+ }
+ rStreamWMF.SetNumberFormatInt( nOrigNumberFormat );
+ return !rStreamWMF.GetError();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF, FilterConfigItem* pFilterConfigItem )
+{
+ UINT32 nMetaType;
+ UINT32 nOrgPos = rStream.Tell();
+ UINT16 nOrigNumberFormat = rStream.GetNumberFormatInt();
+ rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStream.Seek( 0x28 );
+ rStream >> nMetaType;
+ rStream.Seek( nOrgPos );
+ if ( nMetaType == 0x464d4520 )
+ {
+ if ( EnhWMFReader( rStream, rMTF, NULL ).ReadEnhWMF() == FALSE )
+ rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ }
+ else
+ {
+ WMFReader( rStream, rMTF, pFilterConfigItem ).ReadWMF();
+ }
+ rStream.SetNumberFormatInt( nOrigNumberFormat );
+ return !rStream.GetError();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ConvertGDIMetaFileToWMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
+ FilterConfigItem* pConfigItem, BOOL bPlaceable)
+{
+ WMFWriter aWMFWriter;
+ return aWMFWriter.WriteWMF( rMTF, rTargetStream, pConfigItem, bPlaceable );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ConvertGDIMetaFileToEMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
+ FilterConfigItem* pConfigItem )
+{
+ EMFWriter aEMFWriter;
+ return aEMFWriter.WriteEMF( rMTF, rTargetStream, pConfigItem );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL WriteWindowMetafile( SvStream& rStream, const GDIMetaFile& rMTF )
+{
+ return WMFWriter().WriteWMF( rMTF, rStream, NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL WriteWindowMetafileBits( SvStream& rStream, const GDIMetaFile& rMTF )
+{
+ return WMFWriter().WriteWMF( rMTF, rStream, NULL, FALSE );
+}
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.cxx b/svtools/source/filter.vcl/wmf/wmfwr.cxx
new file mode 100644
index 000000000000..4dff9732c7d0
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/wmfwr.cxx
@@ -0,0 +1,2096 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <vcl/salbtype.hxx>
+#include "wmfwr.hxx"
+#include <unotools/fontcvt.hxx>
+#include "emfwr.hxx"
+#include <rtl/crc.h>
+#include <rtl/tencinfo.h>
+#include <tools/tenccvt.hxx>
+#include <osl/endian.h>
+#ifndef INCLUDED_I18NUTIL_UNICODE_HXX
+#include <i18nutil/unicode.hxx> //unicode::getUnicodeScriptType
+#endif
+
+#include <vcl/metric.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+
+//====================== MS-Windows-defines ===============================
+
+#define W_META_SETBKCOLOR 0x0201
+#define W_META_SETBKMODE 0x0102
+#define W_META_SETMAPMODE 0x0103
+#define W_META_SETROP2 0x0104
+#define W_META_SETRELABS 0x0105
+#define W_META_SETPOLYFILLMODE 0x0106
+#define W_META_SETSTRETCHBLTMODE 0x0107
+#define W_META_SETTEXTCHAREXTRA 0x0108
+#define W_META_SETTEXTCOLOR 0x0209
+#define W_META_SETTEXTJUSTIFICATION 0x020A
+#define W_META_SETWINDOWORG 0x020B
+#define W_META_SETWINDOWEXT 0x020C
+#define W_META_SETVIEWPORTORG 0x020D
+#define W_META_SETVIEWPORTEXT 0x020E
+#define W_META_OFFSETWINDOWORG 0x020F
+#define W_META_SCALEWINDOWEXT 0x0410
+#define W_META_OFFSETVIEWPORTORG 0x0211
+#define W_META_SCALEVIEWPORTEXT 0x0412
+#define W_META_LINETO 0x0213
+#define W_META_MOVETO 0x0214
+#define W_META_EXCLUDECLIPRECT 0x0415
+#define W_META_INTERSECTCLIPRECT 0x0416
+#define W_META_ARC 0x0817
+#define W_META_ELLIPSE 0x0418
+#define W_META_FLOODFILL 0x0419
+#define W_META_PIE 0x081A
+#define W_META_RECTANGLE 0x041B
+#define W_META_ROUNDRECT 0x061C
+#define W_META_PATBLT 0x061D
+#define W_META_SAVEDC 0x001E
+#define W_META_SETPIXEL 0x041F
+#define W_META_OFFSETCLIPRGN 0x0220
+#define W_META_TEXTOUT 0x0521
+#define W_META_BITBLT 0x0922
+#define W_META_STRETCHBLT 0x0B23
+#define W_META_POLYGON 0x0324
+#define W_META_POLYLINE 0x0325
+#define W_META_ESCAPE 0x0626
+#define W_META_RESTOREDC 0x0127
+#define W_META_FILLREGION 0x0228
+#define W_META_FRAMEREGION 0x0429
+#define W_META_INVERTREGION 0x012A
+#define W_META_PAINTREGION 0x012B
+#define W_META_SELECTCLIPREGION 0x012C
+#define W_META_SELECTOBJECT 0x012D
+#define W_META_SETTEXTALIGN 0x012E
+#define W_META_DRAWTEXT 0x062F
+#define W_META_CHORD 0x0830
+#define W_META_SETMAPPERFLAGS 0x0231
+#define W_META_EXTTEXTOUT 0x0a32
+#define W_META_SETDIBTODEV 0x0d33
+#define W_META_SELECTPALETTE 0x0234
+#define W_META_REALIZEPALETTE 0x0035
+#define W_META_ANIMATEPALETTE 0x0436
+#define W_META_SETPALENTRIES 0x0037
+#define W_META_POLYPOLYGON 0x0538
+#define W_META_RESIZEPALETTE 0x0139
+#define W_META_DIBBITBLT 0x0940
+#define W_META_DIBSTRETCHBLT 0x0b41
+#define W_META_DIBCREATEPATTERNBRUSH 0x0142
+#define W_META_STRETCHDIB 0x0f43
+#define W_META_EXTFLOODFILL 0x0548
+#define W_META_RESETDC 0x014C
+#define W_META_STARTDOC 0x014D
+#define W_META_STARTPAGE 0x004F
+#define W_META_ENDPAGE 0x0050
+#define W_META_ABORTDOC 0x0052
+#define W_META_ENDDOC 0x005E
+#define W_META_DELETEOBJECT 0x01f0
+#define W_META_CREATEPALETTE 0x00f7
+#define W_META_CREATEBRUSH 0x00F8
+#define W_META_CREATEPATTERNBRUSH 0x01F9
+#define W_META_CREATEPENINDIRECT 0x02FA
+#define W_META_CREATEFONTINDIRECT 0x02FB
+#define W_META_CREATEBRUSHINDIRECT 0x02FC
+#define W_META_CREATEBITMAPINDIRECT 0x02FD
+#define W_META_CREATEBITMAP 0x06FE
+#define W_META_CREATEREGION 0x06FF
+
+#define W_TRANSPARENT 1
+#define W_OPAQUE 2
+
+#define W_R2_BLACK 1
+#define W_R2_NOTMERGEPEN 2
+#define W_R2_MASKNOTPEN 3
+#define W_R2_NOTCOPYPEN 4
+#define W_R2_MASKPENNOT 5
+#define W_R2_NOT 6
+#define W_R2_XORPEN 7
+#define W_R2_NOTMASKPEN 8
+#define W_R2_MASKPEN 9
+#define W_R2_NOTXORPEN 10
+#define W_R2_NOP 11
+#define W_R2_MERGENOTPEN 12
+#define W_R2_COPYPEN 13
+#define W_R2_MERGEPENNOT 14
+#define W_R2_MERGEPEN 15
+#define W_R2_WHITE 16
+
+#define W_TA_NOUPDATECP 0x0000
+#define W_TA_UPDATECP 0x0001
+#define W_TA_LEFT 0x0000
+#define W_TA_RIGHT 0x0002
+#define W_TA_CENTER 0x0006
+#define W_TA_TOP 0x0000
+#define W_TA_BOTTOM 0x0008
+#define W_TA_BASELINE 0x0018
+#define W_TA_RTLREADING 0x0100
+
+#define W_SRCCOPY 0x00CC0020L
+#define W_SRCPAINT 0x00EE0086L
+#define W_SRCAND 0x008800C6L
+#define W_SRCINVERT 0x00660046L
+#define W_SRCERASE 0x00440328L
+#define W_NOTSRCCOPY 0x00330008L
+#define W_NOTSRCERASE 0x001100A6L
+#define W_MERGECOPY 0x00C000CAL
+#define W_MERGEPAINT 0x00BB0226L
+#define W_PATCOPY 0x00F00021L
+#define W_PATPAINT 0x00FB0A09L
+#define W_PATINVERT 0x005A0049L
+#define W_DSTINVERT 0x00550009L
+#define W_BLACKNESS 0x00000042L
+#define W_WHITENESS 0x00FF0062L
+
+#define W_PS_SOLID 0
+#define W_PS_DASH 1
+#define W_PS_DOT 2
+#define W_PS_DASHDOT 3
+#define W_PS_DASHDOTDOT 4
+#define W_PS_NULL 5
+#define W_PS_INSIDEFRAME 6
+
+#define W_LF_FACESIZE 32
+
+#define W_ANSI_CHARSET 0
+#define W_DEFAULT_CHARSET 1
+#define W_SYMBOL_CHARSET 2
+#define W_SHIFTJIS_CHARSET 128
+#define W_HANGEUL_CHARSET 129
+#define W_GB2312_CHARSET 134
+#define W_CHINESEBIG5_CHARSET 136
+#define W_OEM_CHARSET 255
+/*WINVER >= 0x0400*/
+#define W_JOHAB_CHARSET 130
+#define W_HEBREW_CHARSET 177
+#define W_ARABIC_CHARSET 178
+#define W_GREEK_CHARSET 161
+#define W_TURKISH_CHARSET 162
+#define W_VIETNAMESE_CHARSET 163
+#define W_THAI_CHARSET 222
+#define W_EASTEUROPE_CHARSET 238
+#define W_RUSSIAN_CHARSET 204
+#define W_MAC_CHARSET 77
+#define W_BALTIC_CHARSET 186
+
+#define W_DEFAULT_PITCH 0x00
+#define W_FIXED_PITCH 0x01
+#define W_VARIABLE_PITCH 0x02
+
+#define W_FF_DONTCARE 0x00
+#define W_FF_ROMAN 0x10
+#define W_FF_SWISS 0x20
+#define W_FF_MODERN 0x30
+#define W_FF_SCRIPT 0x40
+#define W_FF_DECORATIVE 0x50
+
+#define W_FW_DONTCARE 0
+#define W_FW_THIN 100
+#define W_FW_EXTRALIGHT 200
+#define W_FW_LIGHT 300
+#define W_FW_NORMAL 400
+#define W_FW_MEDIUM 500
+#define W_FW_SEMIBOLD 600
+#define W_FW_BOLD 700
+#define W_FW_EXTRABOLD 800
+#define W_FW_HEAVY 900
+#define W_FW_ULTRALIGHT 200
+#define W_FW_REGULAR 400
+#define W_FW_DEMIBOLD 600
+#define W_FW_ULTRABOLD 800
+#define W_FW_BLACK 900
+
+#define W_BS_SOLID 0
+#define W_BS_HOLLOW 1
+#define W_BS_HATCHED 2
+#define W_BS_PATTERN 3
+#define W_BS_INDEXED 4
+#define W_BS_DIBPATTERN 5
+
+#define W_HS_HORIZONTAL 0
+#define W_HS_VERTICAL 1
+#define W_HS_FDIAGONAL 2
+#define W_HS_BDIAGONAL 3
+#define W_HS_CROSS 4
+#define W_HS_DIAGCROSS 5
+
+#define W_MFCOMMENT 15
+
+#define PRIVATE_ESCAPE_UNICODE 2
+
+/// copied from writerwordglue.cxx
+
+/*
+ Utility to categorize unicode characters into the best fit windows charset
+ range for exporting to ww6, or as a hint to non \u unicode token aware rtf
+ readers
+*/
+rtl_TextEncoding getScriptClass(sal_Unicode cChar)
+{
+ using namespace com::sun::star::i18n;
+
+ static ScriptTypeList aScripts[] =
+ {
+ { UnicodeScript_kBasicLatin, UnicodeScript_kBasicLatin, RTL_TEXTENCODING_MS_1252},
+ { UnicodeScript_kLatin1Supplement, UnicodeScript_kLatin1Supplement, RTL_TEXTENCODING_MS_1252},
+ { UnicodeScript_kLatinExtendedA, UnicodeScript_kLatinExtendedA, RTL_TEXTENCODING_MS_1250},
+ { UnicodeScript_kLatinExtendedB, UnicodeScript_kLatinExtendedB, RTL_TEXTENCODING_MS_1257},
+ { UnicodeScript_kGreek, UnicodeScript_kGreek, RTL_TEXTENCODING_MS_1253},
+ { UnicodeScript_kCyrillic, UnicodeScript_kCyrillic, RTL_TEXTENCODING_MS_1251},
+ { UnicodeScript_kHebrew, UnicodeScript_kHebrew, RTL_TEXTENCODING_MS_1255},
+ { UnicodeScript_kArabic, UnicodeScript_kArabic, RTL_TEXTENCODING_MS_1256},
+ { UnicodeScript_kThai, UnicodeScript_kThai, RTL_TEXTENCODING_MS_1258},
+ { UnicodeScript_kScriptCount, UnicodeScript_kScriptCount, RTL_TEXTENCODING_MS_1252}
+ };
+ return unicode::getUnicodeScriptType(cChar, aScripts,
+ RTL_TEXTENCODING_MS_1252);
+}
+
+//========================== Methoden von WMFWriter ==========================
+
+void WMFWriter::MayCallback()
+{
+ if ( xStatusIndicator.is() )
+ {
+ ULONG nPercent;
+
+ // Wir gehen mal einfach so davon aus, dass 16386 Actions einer Bitmap entsprechen
+ // (in der Regel wird ein Metafile entweder nur Actions oder einige Bitmaps und fast
+ // keine Actions enthalten. Dann ist das Verhaeltnis ziemlich unwichtig)
+
+ nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
+ *100
+ /((nNumberOfBitmaps<<14)+nNumberOfActions);
+
+ if ( nPercent >= nLastPercent + 3 )
+ {
+ nLastPercent = nPercent;
+ if( nPercent <= 100 )
+ xStatusIndicator->setValue( nPercent );
+ }
+ }
+}
+
+void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile & rMTF )
+{
+ ULONG nAction, nActionCount;
+
+ nActionCount = rMTF.GetActionCount();
+
+ for ( nAction=0; nAction<nActionCount; nAction++ )
+ {
+ MetaAction* pMA = rMTF.GetAction( nAction );
+
+ switch( pMA->GetType() )
+ {
+ case META_BMP_ACTION:
+ case META_BMPSCALE_ACTION:
+ case META_BMPSCALEPART_ACTION:
+ case META_BMPEX_ACTION:
+ case META_BMPEXSCALE_ACTION:
+ case META_BMPEXSCALEPART_ACTION:
+ nNumberOfBitmaps++;
+ break;
+ }
+ nNumberOfActions++;
+ }
+}
+
+
+void WMFWriter::WritePointXY(const Point & rPoint)
+{
+ Point aPt( pVirDev->LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aPt.X()) << ((short)aPt.Y());
+}
+
+
+void WMFWriter::WritePointYX(const Point & rPoint)
+{
+ Point aPt( pVirDev->LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aPt.Y()) << ((short)aPt.X());
+}
+
+
+sal_Int32 WMFWriter::ScaleWidth( sal_Int32 nDX )
+{
+ Size aSz( pVirDev->LogicToLogic(Size(nDX,0),aSrcMapMode,aTargetMapMode) );
+ return aSz.Width();
+}
+
+
+void WMFWriter::WriteSize(const Size & rSize)
+{
+ Size aSz( pVirDev->LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aSz.Width()) << ((short)aSz.Height());
+}
+
+
+void WMFWriter::WriteHeightWidth(const Size & rSize)
+{
+ Size aSz( pVirDev->LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aSz.Height()) << ((short)aSz.Width());
+}
+
+
+void WMFWriter::WriteRectangle(const Rectangle & rRect)
+{
+ WritePointYX(Point(rRect.Right()+1,rRect.Bottom()+1));
+ WritePointYX(rRect.TopLeft());
+}
+
+
+void WMFWriter::WriteColor(const Color & rColor)
+{
+ *pWMF << (BYTE) rColor.GetRed() << (BYTE) rColor.GetGreen() << (BYTE) rColor.GetBlue() << (BYTE) 0;
+}
+
+
+void WMFWriter::WriteRecordHeader(sal_uInt32 nSizeWords, sal_uInt16 nType)
+{
+ nActRecordPos=pWMF->Tell();
+ if (nSizeWords>nMaxRecordSize) nMaxRecordSize=nSizeWords;
+ *pWMF << nSizeWords << nType;
+}
+
+
+void WMFWriter::UpdateRecordHeader()
+{
+ ULONG nPos;
+ sal_uInt32 nSize;
+
+ nPos=pWMF->Tell(); nSize=nPos-nActRecordPos;
+ if ((nSize & 1)!=0) {
+ *pWMF << (BYTE)0;
+ nPos++; nSize++;
+ }
+ nSize/=2;
+ if (nSize>nMaxRecordSize) nMaxRecordSize=nSize;
+ pWMF->Seek(nActRecordPos);
+ *pWMF << nSize;
+ pWMF->Seek(nPos);
+}
+
+
+void WMFWriter::WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
+{
+ WriteRecordHeader(0x0000000b,W_META_ARC);
+ WritePointYX(rEndPt);
+ WritePointYX(rStartPt);
+ WriteRectangle(rRect);
+}
+
+void WMFWriter::WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
+{
+ WriteRecordHeader(0x0000000b,W_META_CHORD);
+ WritePointYX(rEndPt);
+ WritePointYX(rStartPt);
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_CreateBrushIndirect(const Color& rColor)
+{
+ WriteRecordHeader(0x00000007,W_META_CREATEBRUSHINDIRECT);
+
+ if( rColor==Color(COL_TRANSPARENT) )
+ *pWMF << (UINT16) W_BS_HOLLOW;
+ else
+ *pWMF << (UINT16) W_BS_SOLID;
+
+ WriteColor( rColor );
+ *pWMF << (UINT16) 0;
+}
+
+
+void WMFWriter::WMFRecord_CreateFontIndirect(const Font & rFont)
+{
+ USHORT nWeight,i;
+ BYTE nPitchFamily;
+
+ WriteRecordHeader(0x00000000,W_META_CREATEFONTINDIRECT);
+ WriteHeightWidth(Size(rFont.GetSize().Width(),-rFont.GetSize().Height()));
+ *pWMF << (short)rFont.GetOrientation() << (short)rFont.GetOrientation();
+
+ switch (rFont.GetWeight()) {
+ case WEIGHT_THIN: nWeight=W_FW_THIN; break;
+ case WEIGHT_ULTRALIGHT: nWeight=W_FW_ULTRALIGHT; break;
+ case WEIGHT_LIGHT: nWeight=W_FW_LIGHT; break;
+ case WEIGHT_SEMILIGHT: nWeight=W_FW_LIGHT; break;
+ case WEIGHT_NORMAL: nWeight=W_FW_NORMAL; break;
+ case WEIGHT_MEDIUM: nWeight=W_FW_MEDIUM; break;
+ case WEIGHT_SEMIBOLD: nWeight=W_FW_SEMIBOLD; break;
+ case WEIGHT_BOLD: nWeight=W_FW_BOLD; break;
+ case WEIGHT_ULTRABOLD: nWeight=W_FW_ULTRABOLD; break;
+ case WEIGHT_BLACK: nWeight=W_FW_BLACK; break;
+ default: nWeight=W_FW_DONTCARE;
+ }
+ *pWMF << nWeight;
+
+ if (rFont.GetItalic()==ITALIC_NONE) *pWMF << (BYTE)0; else *pWMF << (BYTE)1;
+ if (rFont.GetUnderline()==UNDERLINE_NONE) *pWMF << (BYTE)0; else *pWMF << (BYTE)1;
+ if (rFont.GetStrikeout()==STRIKEOUT_NONE) *pWMF << (BYTE)0; else *pWMF << (BYTE)1;
+
+ CharSet eFontNameEncoding = rFont.GetCharSet();
+ sal_uInt8 nCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontNameEncoding );
+ if ( eFontNameEncoding == RTL_TEXTENCODING_SYMBOL )
+ eFontNameEncoding = RTL_TEXTENCODING_MS_1252;
+ if ( nCharSet == 1 )
+ nCharSet = W_ANSI_CHARSET;
+ *pWMF << nCharSet;
+
+ *pWMF << (BYTE)0 << (BYTE)0 << (BYTE)0;
+
+ switch (rFont.GetPitch()) {
+ case PITCH_FIXED: nPitchFamily=W_FIXED_PITCH; break;
+ case PITCH_VARIABLE: nPitchFamily=W_VARIABLE_PITCH; break;
+ default: nPitchFamily=W_DEFAULT_PITCH;
+ }
+ switch (rFont.GetFamily()) {
+ case FAMILY_DECORATIVE: nPitchFamily|=W_FF_DECORATIVE; break;
+ case FAMILY_MODERN: nPitchFamily|=W_FF_MODERN; break;
+ case FAMILY_ROMAN: nPitchFamily|=W_FF_ROMAN; break;
+ case FAMILY_SCRIPT: nPitchFamily|=W_FF_SCRIPT; break;
+ case FAMILY_SWISS: nPitchFamily|=W_FF_SWISS; break;
+ default: nPitchFamily|=W_FF_DONTCARE;
+ }
+ *pWMF << nPitchFamily;
+
+ ByteString aFontName( rFont.GetName(), eFontNameEncoding );
+ for ( i = 0; i < W_LF_FACESIZE; i++ )
+ {
+ sal_Char nChar = ( i < aFontName.Len() ) ? aFontName.GetChar( i ) : 0;
+ *pWMF << nChar;
+ }
+ UpdateRecordHeader();
+}
+
+void WMFWriter::WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo )
+{
+ WriteRecordHeader(0x00000008,W_META_CREATEPENINDIRECT);
+ USHORT nStyle = rColor == Color( COL_TRANSPARENT ) ? W_PS_NULL : W_PS_SOLID;
+ switch( rLineInfo.GetStyle() )
+ {
+ case LINE_DASH :
+ {
+ if ( rLineInfo.GetDotCount() )
+ {
+ if ( !rLineInfo.GetDashCount() )
+ nStyle = W_PS_DOT;
+ else
+ {
+ if ( !rLineInfo.GetDotCount() == 1 )
+ nStyle = W_PS_DASHDOT;
+ else
+ nStyle = W_PS_DASHDOTDOT;
+ }
+ }
+ else
+ nStyle = W_PS_DASH;
+ }
+ break;
+ case LINE_NONE :
+ nStyle = W_PS_NULL;
+ break;
+ default:
+ break;
+ }
+ *pWMF << nStyle;
+
+ WriteSize( Size( rLineInfo.GetWidth(), 0 ) );
+ WriteColor( rColor );
+}
+
+void WMFWriter::WMFRecord_DeleteObject(USHORT nObjectHandle)
+{
+ WriteRecordHeader(0x00000004,W_META_DELETEOBJECT);
+ *pWMF << nObjectHandle;
+}
+
+
+void WMFWriter::WMFRecord_Ellipse(const Rectangle & rRect)
+{
+ WriteRecordHeader(0x00000007,W_META_ELLIPSE);
+ WriteRectangle(rRect);
+}
+
+bool IsStarSymbol(const String &rStr)
+{
+ return rStr.EqualsIgnoreCaseAscii("starsymbol") ||
+ rStr.EqualsIgnoreCaseAscii("opensymbol");
+}
+
+void WMFWriter::WMFRecord_Escape( sal_uInt32 nEsc, sal_uInt32 nLen, const sal_Int8* pData )
+{
+#ifdef OSL_BIGENDIAN
+ sal_uInt32 nTmp = SWAPLONG( nEsc );
+ sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
+#else
+ sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
+#endif
+ if ( nLen )
+ nCheckSum = rtl_crc32( nCheckSum, pData, nLen );
+
+ WriteRecordHeader( 3 + 9 + ( ( nLen + 1 ) >> 1 ), W_META_ESCAPE );
+ *pWMF << (sal_uInt16)W_MFCOMMENT
+ << (sal_uInt16)( nLen + 14 ) // we will always have a fourteen byte escape header:
+ << (sal_uInt16)0x4f4f // OO
+ << (sal_uInt32)0xa2c2a // evil magic number
+ << (sal_uInt32)nCheckSum // crc32 checksum about nEsc & pData
+ << (sal_uInt32)nEsc; // escape number
+ pWMF->Write( pData, nLen );
+ if ( nLen & 1 )
+ *pWMF << (sal_uInt8)0; // pad byte
+}
+
+/* if return value is true, then a complete unicode string and also a polygon replacement has been written,
+ so there is no more action necessary
+*/
+sal_Bool WMFWriter::WMFRecord_Escape_Unicode( const Point& rPoint, const String& rUniStr, const sal_Int32* pDXAry )
+{
+ sal_Bool bEscapeUsed = sal_False;
+
+ sal_uInt32 i, nStringLen = rUniStr.Len();
+ if ( nStringLen )
+ {
+ // first we will check if a comment is necessary
+ if ( aSrcFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) // symbol is always byte character, so there is no unicode loss
+ {
+ const sal_Unicode* pBuf = rUniStr.GetBuffer();
+ const rtl_TextEncoding aTextEncodingOrg = aSrcFont.GetCharSet();
+ ByteString aByteStr( rUniStr, aTextEncodingOrg );
+ String aUniStr2( aByteStr, aTextEncodingOrg );
+ const sal_Unicode* pConversion = aUniStr2.GetBuffer(); // this is the unicode array after bytestring <-> unistring conversion
+ for ( i = 0; i < nStringLen; i++ )
+ {
+ if ( *pBuf++ != *pConversion++ )
+ break;
+ }
+
+ if ( i != nStringLen ) // after conversion the characters are not original,
+ { // try again, with determining a better charset from unicode char
+ pBuf = rUniStr.GetBuffer();
+ const sal_Unicode* pCheckChar = pBuf;
+ rtl_TextEncoding aTextEncoding = getScriptClass (*pCheckChar); // try the first character
+ for ( i = 1; i < nStringLen; i++)
+ {
+ if (aTextEncoding != aTextEncodingOrg) // found something
+ break;
+ pCheckChar++;
+ aTextEncoding = getScriptClass (*pCheckChar); // try the next character
+ }
+
+ aByteStr = ByteString ( rUniStr, aTextEncoding );
+ aUniStr2 = String ( aByteStr, aTextEncoding );
+ pConversion = aUniStr2.GetBuffer(); // this is the unicode array after bytestring <-> unistring conversion
+ for ( i = 0; i < nStringLen; i++ )
+ {
+ if ( *pBuf++ != *pConversion++ )
+ break;
+ }
+ if (i == nStringLen)
+ {
+ aSrcFont.SetCharSet (aTextEncoding);
+ SetAllAttr();
+ }
+ }
+
+ if ( ( i != nStringLen ) || IsStarSymbol( aSrcFont.GetName() ) ) // after conversion the characters are not original, so we
+ { // will store the unicode string and a polypoly replacement
+ Color aOldFillColor( aSrcFillColor );
+ Color aOldLineColor( aSrcLineColor );
+ aSrcLineInfo = LineInfo();
+ aSrcFillColor = aSrcTextColor;
+ aSrcLineColor = Color( COL_TRANSPARENT );
+ SetLineAndFillAttr();
+ pVirDev->SetFont( aSrcFont );
+ std::vector<PolyPolygon> aPolyPolyVec;
+ if ( pVirDev->GetTextOutlines( aPolyPolyVec, rUniStr ) )
+ {
+ sal_uInt32 nDXCount = pDXAry ? nStringLen : 0;
+ sal_uInt32 nSkipActions = aPolyPolyVec.size();
+ sal_Int32 nStrmLen = 8 +
+ + sizeof( nStringLen ) + ( nStringLen * 2 )
+ + sizeof( nDXCount ) + ( nDXCount * 4 )
+ + sizeof( nSkipActions );
+
+ SvMemoryStream aMemoryStream( nStrmLen );
+ Point aPt( pVirDev->LogicToLogic( rPoint, aSrcMapMode, aTargetMapMode ) );
+ aMemoryStream << aPt.X()
+ << aPt.Y()
+ << nStringLen;
+ for ( i = 0; i < nStringLen; i++ )
+ aMemoryStream << rUniStr.GetChar( (sal_uInt16)i );
+ aMemoryStream << nDXCount;
+ for ( i = 0; i < nDXCount; i++ )
+ aMemoryStream << pDXAry[ i ];
+ aMemoryStream << nSkipActions;
+ WMFRecord_Escape( PRIVATE_ESCAPE_UNICODE, nStrmLen, (const sal_Int8*)aMemoryStream.GetData() );
+
+ std::vector<PolyPolygon>::iterator aIter( aPolyPolyVec.begin() );
+ while ( aIter != aPolyPolyVec.end() )
+ {
+ PolyPolygon aPolyPoly( *aIter++ );
+ aPolyPoly.Move( rPoint.X(), rPoint.Y() );
+ WMFRecord_PolyPolygon( aPolyPoly );
+ }
+ aSrcFillColor = aOldFillColor;
+ aSrcLineColor = aOldLineColor;
+ bEscapeUsed = sal_True;
+ }
+ }
+ }
+ }
+ return bEscapeUsed;
+}
+
+void WMFWriter::WMFRecord_ExtTextOut( const Point & rPoint,
+ const String & rString, const sal_Int32 * pDXAry )
+{
+ sal_uInt16 nOriginalTextLen = rString.Len();
+
+ if ( (nOriginalTextLen <= 1) || (pDXAry == NULL) )
+ {
+ WMFRecord_TextOut(rPoint, rString);
+ return;
+ }
+ rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
+ ByteString aByteString(rString, eChrSet);
+ TrueExtTextOut(rPoint,rString,aByteString,pDXAry);
+}
+
+void WMFWriter::TrueExtTextOut( const Point & rPoint, const String & rString,
+ const ByteString & rByteString, const sal_Int32 * pDXAry )
+{
+ WriteRecordHeader( 0, W_META_EXTTEXTOUT );
+ WritePointYX( rPoint );
+ sal_uInt16 nNewTextLen = rByteString.Len();
+ *pWMF << nNewTextLen << (sal_uInt16)0;
+
+ sal_uInt16 i;
+ for ( i = 0; i < nNewTextLen; i++ )
+ *pWMF << (sal_uInt8)rByteString.GetChar( i );
+ if ( nNewTextLen & 1 )
+ *pWMF << (sal_uInt8)0;
+
+ sal_uInt16 nOriginalTextLen = rString.Len();
+ sal_Int16* pConvertedDXAry = new sal_Int16[ nOriginalTextLen ];
+ sal_Int32 j = 0;
+ pConvertedDXAry[ j++ ] = (sal_Int16)ScaleWidth( pDXAry[ 0 ] );
+ for ( i = 1; i < ( nOriginalTextLen - 1 ); i++ )
+ pConvertedDXAry[ j++ ] = (sal_Int16)ScaleWidth( pDXAry[ i ] - pDXAry[ i - 1 ] );
+ pConvertedDXAry[ j ] = (sal_Int16)ScaleWidth( pDXAry[ nOriginalTextLen - 2 ] / ( nOriginalTextLen - 1 ) );
+
+ for ( i = 0; i < nOriginalTextLen; i++ )
+ {
+ sal_Int16 nDx = pConvertedDXAry[ i ];
+ *pWMF << nDx;
+ if ( nOriginalTextLen < nNewTextLen )
+ {
+ ByteString aTemp( rString.GetChar( i ), aSrcFont.GetCharSet());
+ j = aTemp.Len();
+ while ( --j > 0 )
+ *pWMF << (sal_uInt16)0;
+ }
+ }
+ delete[] pConvertedDXAry;
+ UpdateRecordHeader();
+}
+
+void WMFWriter::WMFRecord_LineTo(const Point & rPoint)
+{
+ WriteRecordHeader(0x00000005,W_META_LINETO);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_MoveTo(const Point & rPoint)
+{
+ WriteRecordHeader(0x00000005,W_META_MOVETO);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_Pie(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
+{
+ WriteRecordHeader(0x0000000b,W_META_PIE);
+ WritePointYX(rEndPt);
+ WritePointYX(rStartPt);
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_Polygon(const Polygon & rPoly)
+{
+ USHORT nSize,i;
+
+ Polygon aSimplePoly;
+ if ( rPoly.HasFlags() )
+ rPoly.AdaptiveSubdivide( aSimplePoly );
+ else
+ aSimplePoly = rPoly;
+ nSize = aSimplePoly.GetSize();
+ WriteRecordHeader(((ULONG)nSize)*2+4,W_META_POLYGON);
+ *pWMF << nSize;
+ for (i=0; i<nSize; i++) WritePointXY(aSimplePoly.GetPoint(i));
+}
+
+
+void WMFWriter::WMFRecord_PolyLine(const Polygon & rPoly)
+{
+ USHORT nSize,i;
+ Polygon aSimplePoly;
+ if ( rPoly.HasFlags() )
+ rPoly.AdaptiveSubdivide( aSimplePoly );
+ else
+ aSimplePoly = rPoly;
+ nSize=aSimplePoly.GetSize();
+ WriteRecordHeader(((ULONG)nSize)*2+4,W_META_POLYLINE);
+ *pWMF << nSize;
+ for (i=0; i<nSize; i++) WritePointXY(aSimplePoly.GetPoint(i));
+}
+
+
+void WMFWriter::WMFRecord_PolyPolygon(const PolyPolygon & rPolyPoly)
+{
+ const Polygon * pPoly;
+ USHORT nCount,nSize,i,j;
+
+ nCount=rPolyPoly.Count();
+ PolyPolygon aSimplePolyPoly( rPolyPoly );
+ for ( i = 0; i < nCount; i++ )
+ {
+ if ( aSimplePolyPoly[ i ].HasFlags() )
+ {
+ Polygon aSimplePoly;
+ aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
+ aSimplePolyPoly[ i ] = aSimplePoly;
+ }
+ }
+ WriteRecordHeader(0,W_META_POLYPOLYGON);
+ *pWMF << nCount;
+ for (i=0; i<nCount; i++) *pWMF << ((USHORT)(aSimplePolyPoly.GetObject(i).GetSize()));
+ for (i=0; i<nCount; i++) {
+ pPoly=&(aSimplePolyPoly.GetObject(i));
+ nSize=pPoly->GetSize();
+ for (j=0; j<nSize; j++) WritePointXY(pPoly->GetPoint(j));
+ }
+ UpdateRecordHeader();
+}
+
+
+void WMFWriter::WMFRecord_Rectangle(const Rectangle & rRect)
+{
+ WriteRecordHeader( 0x00000007,W_META_RECTANGLE );
+ WriteRectangle( rRect );
+}
+
+
+void WMFWriter::WMFRecord_RestoreDC()
+{
+ WriteRecordHeader(0x00000004,W_META_RESTOREDC);
+ *pWMF << (short)-1;
+}
+
+
+void WMFWriter::WMFRecord_RoundRect(const Rectangle & rRect, long nHorzRound, long nVertRound)
+{
+ WriteRecordHeader(0x00000009,W_META_ROUNDRECT);
+ WriteHeightWidth(Size(nHorzRound,nVertRound));
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_SaveDC()
+{
+ WriteRecordHeader(0x00000003,W_META_SAVEDC);
+}
+
+
+void WMFWriter::WMFRecord_SelectObject(USHORT nObjectHandle)
+{
+ WriteRecordHeader(0x00000004,W_META_SELECTOBJECT);
+ *pWMF << nObjectHandle;
+}
+
+
+void WMFWriter::WMFRecord_SetBkColor(const Color & rColor)
+{
+ WriteRecordHeader(0x00000005,W_META_SETBKCOLOR);
+ WriteColor(rColor);
+}
+
+
+void WMFWriter::WMFRecord_SetBkMode(BOOL bTransparent)
+{
+ WriteRecordHeader(0x00000004,W_META_SETBKMODE);
+ if (bTransparent==TRUE) *pWMF << (USHORT)W_TRANSPARENT;
+ else *pWMF << (USHORT)W_OPAQUE;
+}
+
+void WMFWriter::WMFRecord_SetStretchBltMode()
+{
+ WriteRecordHeader( 0x00000004, W_META_SETSTRETCHBLTMODE );
+ *pWMF << (USHORT) 3; // STRETCH_DELETESCANS
+}
+
+void WMFWriter::WMFRecord_SetPixel(const Point & rPoint, const Color & rColor)
+{
+ WriteRecordHeader(0x00000007,W_META_SETPIXEL);
+ WriteColor(rColor);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_SetROP2(RasterOp eROP)
+{
+ USHORT nROP2;
+
+ switch (eROP) {
+ case ROP_INVERT: nROP2=W_R2_NOT; break;
+ case ROP_XOR: nROP2=W_R2_XORPEN; break;
+ default: nROP2=W_R2_COPYPEN;
+ }
+ WriteRecordHeader(0x00000004,W_META_SETROP2);
+ *pWMF << nROP2;
+}
+
+
+void WMFWriter::WMFRecord_SetTextAlign(FontAlign eFontAlign, UINT32 eHorTextAlign)
+{
+ USHORT nAlign;
+
+ switch (eFontAlign) {
+ case ALIGN_TOP: nAlign=W_TA_TOP; break;
+ case ALIGN_BOTTOM: nAlign=W_TA_BOTTOM; break;
+ default: nAlign=W_TA_BASELINE;
+ }
+ nAlign|=eHorTextAlign;
+ nAlign|=W_TA_NOUPDATECP;
+
+ WriteRecordHeader(0x00000004,W_META_SETTEXTALIGN);
+ *pWMF << nAlign;
+}
+
+
+void WMFWriter::WMFRecord_SetTextColor(const Color & rColor)
+{
+ WriteRecordHeader(0x00000005,W_META_SETTEXTCOLOR);
+ WriteColor(rColor);
+}
+
+
+void WMFWriter::WMFRecord_SetWindowExt(const Size & rSize)
+{
+ WriteRecordHeader(0x00000005,W_META_SETWINDOWEXT);
+ WriteHeightWidth(rSize);
+}
+
+
+void WMFWriter::WMFRecord_SetWindowOrg(const Point & rPoint)
+{
+ WriteRecordHeader(0x00000005,W_META_SETWINDOWORG);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_StretchDIB( const Point & rPoint, const Size & rSize,
+ const Bitmap & rBitmap, sal_uInt32 nROP )
+{
+ ULONG nPosAnf,nPosEnd;
+
+ nActBitmapPercent=50;
+ MayCallback();
+
+ WriteRecordHeader(0x00000000,W_META_STRETCHDIB);
+
+ // Die Reihenfolge im Metafile soll jetzt sein:
+ // einige Parameter (laenge 22), dann die Bitmap ohne FILEHEADER.
+ // Da aber *pWMF << rBitmap einen FILEHEADER der Laenge 14
+ // erzeugt, schreiben wir zuerst die Bitmap an die richtige Position
+ // Und ueberschreiben hinterher den FILEHEADER mit den Parametern.
+ nPosAnf=pWMF->Tell(); // Position merken, wo Parameter hin sollen
+ *pWMF << (long)0 << (long)0; // 8 bytes auffuellen (diese 8 bytes +
+ // 14 bytes ueberfluessigen FILEHEADER
+ // = 22 bytes Parameter)
+ *pWMF << rBitmap; // Bitmap schreiben
+
+ // Parameter schreiben:
+ nPosEnd=pWMF->Tell();
+ pWMF->Seek(nPosAnf);
+
+ // Raster-Op bestimmen, falls nichts uebergeben wurde
+ if( !nROP )
+ {
+ switch( eSrcRasterOp )
+ {
+ case ROP_INVERT: nROP = W_DSTINVERT; break;
+ case ROP_XOR: nROP = W_SRCINVERT; break;
+ default: nROP = W_SRCCOPY;
+ }
+ }
+
+ *pWMF << nROP <<
+ (short) 0 <<
+ (short) rBitmap.GetSizePixel().Height() <<
+ (short) rBitmap.GetSizePixel().Width() <<
+ (short) 0 <<
+ (short) 0;
+
+ WriteHeightWidth(rSize);
+ WritePointYX(rPoint);
+ pWMF->Seek(nPosEnd);
+
+ UpdateRecordHeader();
+
+ nWrittenBitmaps++;
+ nActBitmapPercent=0;
+}
+
+
+void WMFWriter::WMFRecord_TextOut(const Point & rPoint, const String & rStr)
+{
+ rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
+ ByteString aString( rStr, eChrSet );
+ TrueTextOut(rPoint, aString);
+}
+
+void WMFWriter::TrueTextOut(const Point & rPoint, const ByteString& rString)
+{
+ USHORT nLen,i;
+
+ WriteRecordHeader(0,W_META_TEXTOUT);
+ nLen=rString.Len();
+ *pWMF << nLen;
+ for ( i = 0; i < nLen; i++ )
+ *pWMF << (BYTE)rString.GetChar( i );
+ if ((nLen&1)!=0) *pWMF << (BYTE)0;
+ WritePointYX(rPoint);
+ UpdateRecordHeader();
+}
+
+void WMFWriter::WMFRecord_EndOfFile()
+{
+ WriteRecordHeader(0x00000003,0x0000);
+}
+
+
+void WMFWriter::WMFRecord_IntersectClipRect( const Rectangle& rRect )
+{
+ WriteRecordHeader( 0x00000007, W_META_INTERSECTCLIPRECT );
+ WriteRectangle(rRect);
+}
+
+
+USHORT WMFWriter::AllocHandle()
+{
+ USHORT i;
+
+ for (i=0; i<MAXOBJECTHANDLES; i++) {
+ if (bHandleAllocated[i]==FALSE) {
+ bHandleAllocated[i]=TRUE;
+ return i;
+ }
+ }
+ bStatus=FALSE;
+ return 0xffff;
+}
+
+
+void WMFWriter::FreeHandle(USHORT nObjectHandle)
+{
+ if (nObjectHandle<MAXOBJECTHANDLES) bHandleAllocated[nObjectHandle]=FALSE;
+}
+
+
+void WMFWriter::CreateSelectDeletePen( const Color& rColor, const LineInfo& rLineInfo )
+{
+ USHORT nOldHandle;
+
+ nOldHandle=nDstPenHandle;
+ nDstPenHandle=AllocHandle();
+ WMFRecord_CreatePenIndirect( rColor, rLineInfo );
+ WMFRecord_SelectObject(nDstPenHandle);
+ if (nOldHandle<MAXOBJECTHANDLES) {
+ WMFRecord_DeleteObject(nOldHandle);
+ FreeHandle(nOldHandle);
+ }
+}
+
+
+void WMFWriter::CreateSelectDeleteFont(const Font & rFont)
+{
+ USHORT nOldHandle;
+
+ nOldHandle=nDstFontHandle;
+ nDstFontHandle=AllocHandle();
+ WMFRecord_CreateFontIndirect(rFont);
+ WMFRecord_SelectObject(nDstFontHandle);
+ if (nOldHandle<MAXOBJECTHANDLES) {
+ WMFRecord_DeleteObject(nOldHandle);
+ FreeHandle(nOldHandle);
+ }
+}
+
+
+void WMFWriter::CreateSelectDeleteBrush(const Color& rColor)
+{
+ USHORT nOldHandle;
+
+ nOldHandle=nDstBrushHandle;
+ nDstBrushHandle=AllocHandle();
+ WMFRecord_CreateBrushIndirect(rColor);
+ WMFRecord_SelectObject(nDstBrushHandle);
+ if (nOldHandle<MAXOBJECTHANDLES) {
+ WMFRecord_DeleteObject(nOldHandle);
+ FreeHandle(nOldHandle);
+ }
+}
+
+
+void WMFWriter::SetLineAndFillAttr()
+{
+ if ( eDstROP2 != eSrcRasterOp )
+ {
+ eDstROP2=eSrcRasterOp;
+ WMFRecord_SetROP2(eDstROP2);
+ }
+ if ( ( aDstLineColor != aSrcLineColor ) || ( aDstLineInfo != aSrcLineInfo ) )
+ {
+ aDstLineColor = aSrcLineColor;
+ aDstLineInfo = aSrcLineInfo;
+ CreateSelectDeletePen( aDstLineColor, aDstLineInfo );
+ }
+ if ( aDstFillColor != aSrcFillColor )
+ {
+ aDstFillColor = aSrcFillColor;
+ CreateSelectDeleteBrush( aDstFillColor );
+ }
+ if ( bDstIsClipping != bSrcIsClipping ||
+ (bSrcIsClipping==TRUE && aDstClipRegion!=aSrcClipRegion)) {
+ bDstIsClipping=bSrcIsClipping;
+ aDstClipRegion=aSrcClipRegion;
+ }
+}
+
+void WMFWriter::SetAllAttr()
+{
+ SetLineAndFillAttr();
+ if ( aDstTextColor != aSrcTextColor )
+ {
+ aDstTextColor = aSrcTextColor;
+ WMFRecord_SetTextColor(aDstTextColor);
+ }
+ if ( eDstTextAlign != eSrcTextAlign || eDstHorTextAlign != eSrcHorTextAlign )
+ {
+ eDstTextAlign = eSrcTextAlign;
+ eDstHorTextAlign = eSrcHorTextAlign;
+ WMFRecord_SetTextAlign( eDstTextAlign, eDstHorTextAlign );
+ }
+ if ( aDstFont != aSrcFont )
+ {
+ pVirDev->SetFont(aSrcFont);
+ if ( aDstFont.GetName() != aSrcFont.GetName() )
+ {
+ FontCharMap aFontCharMap;
+ if ( pVirDev->GetFontCharMap( aFontCharMap ) )
+ {
+ if ( ( aFontCharMap.GetFirstChar() & 0xff00 ) == 0xf000 )
+ aSrcFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ else if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
+ aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
+ }
+ }
+ aDstFont = aSrcFont;
+ CreateSelectDeleteFont(aDstFont);
+ }
+}
+
+
+void WMFWriter::HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
+{
+ if(rLinePolygon.count())
+ {
+ basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
+ basegfx::B2DPolyPolygon aFillPolyPolygon;
+
+ rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
+
+ if(aLinePolyPolygon.count())
+ {
+ aSrcLineInfo = rInfo;
+ SetLineAndFillAttr();
+
+ for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
+ {
+ const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
+ WMFRecord_PolyLine(Polygon(aCandidate));
+ }
+ }
+
+ if(aFillPolyPolygon.count())
+ {
+ const Color aOldLineColor(aSrcLineColor);
+ const Color aOldFillColor(aSrcFillColor);
+
+ aSrcLineColor = Color( COL_TRANSPARENT );
+ aSrcFillColor = aOldLineColor;
+ SetLineAndFillAttr();
+
+ for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
+ {
+ const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
+ WMFRecord_Polygon(Polygon(aPolygon));
+ }
+
+ aSrcLineColor = aOldLineColor;
+ aSrcFillColor = aOldFillColor;
+ SetLineAndFillAttr();
+ }
+ }
+}
+
+void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
+{
+ ULONG nA, nACount;
+ MetaAction* pMA;
+
+ if( bStatus )
+ {
+ nACount = rMTF.GetActionCount();
+
+ WMFRecord_SetStretchBltMode();
+
+ for( nA=0; nA<nACount; nA++ )
+ {
+ pMA = rMTF.GetAction( nA );
+
+ switch( pMA->GetType() )
+ {
+ case META_PIXEL_ACTION:
+ {
+ const MetaPixelAction* pA = (const MetaPixelAction *) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_SetPixel( pA->GetPoint(), pA->GetColor() );
+ }
+ break;
+
+ case META_POINT_ACTION:
+ {
+ const MetaPointAction* pA = (const MetaPointAction*) pMA;
+ const Point& rPt = pA->GetPoint();
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_MoveTo( rPt);
+ WMFRecord_LineTo( rPt );
+ }
+ break;
+
+ case META_LINE_ACTION:
+ {
+ const MetaLineAction* pA = (const MetaLineAction *) pMA;
+ if(pA->GetLineInfo().IsDefault())
+ {
+ aSrcLineInfo = pA->GetLineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_MoveTo( pA->GetStartPoint() );
+ WMFRecord_LineTo( pA->GetEndPoint() );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
+ aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
+ HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
+ }
+ }
+ break;
+
+ case META_RECT_ACTION:
+ {
+ const MetaRectAction* pA = (const MetaRectAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Rectangle( pA->GetRect() );
+ }
+ break;
+
+ case META_ROUNDRECT_ACTION:
+ {
+ const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_RoundRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
+ }
+ break;
+
+ case META_ELLIPSE_ACTION:
+ {
+ const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Ellipse( pA->GetRect() );
+ }
+ break;
+
+ case META_ARC_ACTION:
+ {
+ const MetaArcAction* pA = (const MetaArcAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Arc( pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint() );
+ }
+ break;
+
+ case META_PIE_ACTION:
+ {
+ const MetaPieAction* pA = (const MetaPieAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Pie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
+ }
+ break;
+
+
+ case META_CHORD_ACTION:
+ {
+ const MetaChordAction* pA = (const MetaChordAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Chord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
+ }
+ break;
+
+ case META_POLYLINE_ACTION:
+ {
+ const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
+ const Polygon& rPoly = pA->GetPolygon();
+
+ if( rPoly.GetSize() )
+ {
+ if(pA->GetLineInfo().IsDefault())
+ {
+ aSrcLineInfo = pA->GetLineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_PolyLine( rPoly );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
+ }
+ }
+ }
+ break;
+
+ case META_POLYGON_ACTION:
+ {
+ const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Polygon( pA->GetPolygon() );
+ }
+ break;
+
+ case META_POLYPOLYGON_ACTION:
+ {
+ const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_PolyPolygon( pA->GetPolyPolygon() );
+ }
+ break;
+
+ case META_TEXTRECT_ACTION:
+ {
+ const MetaTextRectAction * pA = (const MetaTextRectAction*)pMA;
+ String aTemp( pA->GetText() );
+ aSrcLineInfo = LineInfo();
+ SetAllAttr();
+
+ Point aPos( pA->GetRect().TopLeft() );
+ if ( !WMFRecord_Escape_Unicode( aPos, aTemp, NULL ) )
+ WMFRecord_TextOut( aPos, aTemp );
+ }
+ break;
+
+ case META_TEXT_ACTION:
+ {
+ const MetaTextAction * pA = (const MetaTextAction*) pMA;
+ String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ aSrcLineInfo = LineInfo();
+ SetAllAttr();
+ if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, NULL ) )
+ WMFRecord_TextOut( pA->GetPoint(), aTemp );
+ }
+ break;
+
+ case META_TEXTARRAY_ACTION:
+ {
+ const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
+
+ String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ aSrcLineInfo = LineInfo();
+ SetAllAttr();
+ if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pA->GetDXArray() ) )
+ WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pA->GetDXArray() );
+ }
+ break;
+
+ case META_STRETCHTEXT_ACTION:
+ {
+ const MetaStretchTextAction* pA = (const MetaStretchTextAction *) pMA;
+ String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ sal_uInt16 nLen,i;
+ sal_Int32 nNormSize;
+
+ pVirDev->SetFont( aSrcFont );
+ nLen = aTemp.Len();
+ sal_Int32* pDXAry = nLen ? new sal_Int32[ nLen ] : NULL;
+ nNormSize = pVirDev->GetTextArray( aTemp, pDXAry );
+ for ( i = 0; i < ( nLen - 1 ); i++ )
+ pDXAry[ i ] = pDXAry[ i ] * (sal_Int32)pA->GetWidth() / nNormSize;
+ if ( ( nLen <= 1 ) || ( (sal_Int32)pA->GetWidth() == nNormSize ) )
+ delete[] pDXAry, pDXAry = NULL;
+ aSrcLineInfo = LineInfo();
+ SetAllAttr();
+ if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pDXAry ) )
+ WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pDXAry );
+ delete[] pDXAry;
+ }
+ break;
+
+ case META_BMP_ACTION:
+ {
+ const MetaBmpAction* pA = (const MetaBmpAction *) pMA;
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetBitmap().GetSizePixel(), pA->GetBitmap() );
+ }
+ break;
+
+ case META_BMPSCALE_ACTION:
+ {
+ const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
+ }
+ break;
+
+ case META_BMPSCALEPART_ACTION:
+ {
+ const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
+ Bitmap aTmp( pA->GetBitmap() );
+
+ if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
+ }
+ break;
+
+ case META_BMPEX_ACTION:
+ {
+ const MetaBmpExAction* pA = (const MetaBmpExAction *) pMA;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ WMFRecord_StretchDIB( pA->GetPoint(), aMsk.GetSizePixel(), aBmp, W_SRCPAINT );
+ WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp, W_SRCAND );
+ }
+ else
+ WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp );
+ }
+ break;
+
+ case META_BMPEXSCALE_ACTION:
+ {
+ const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
+ }
+ else
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
+ }
+ break;
+
+ case META_BMPEXSCALEPART_ACTION:
+ {
+ const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
+ BitmapEx aBmpEx( pA->GetBitmapEx() );
+ aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
+ Bitmap aBmp( aBmpEx.GetBitmap() );
+ Bitmap aMsk( aBmpEx.GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aMsk, W_SRCPAINT );
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp, W_SRCAND );
+ }
+ else
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
+ }
+ break;
+
+ case META_GRADIENT_ACTION:
+ {
+ const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
+ GDIMetaFile aTmpMtf;
+
+ pVirDev->AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
+ WriteRecords( aTmpMtf );
+ }
+ break;
+
+ case META_HATCH_ACTION:
+ {
+ const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
+ GDIMetaFile aTmpMtf;
+
+ pVirDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
+ WriteRecords( aTmpMtf );
+ }
+ break;
+
+ case META_WALLPAPER_ACTION:
+ {
+ const MetaWallpaperAction* pA = (const MetaWallpaperAction*) pMA;
+ const Color& rColor = pA->GetWallpaper().GetColor();
+ const Color aOldLineColor( aSrcLineColor );
+ const Color aOldFillColor( aSrcFillColor );
+
+ aSrcLineColor = rColor;
+ aSrcFillColor = rColor;
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_Rectangle( pA->GetRect() );
+ aSrcLineColor = aOldLineColor;
+ aSrcFillColor = aOldFillColor;
+ }
+ break;
+
+ case META_ISECTRECTCLIPREGION_ACTION:
+ {
+ const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
+ WMFRecord_IntersectClipRect( pA->GetRect() );
+ }
+ break;
+
+ case META_LINECOLOR_ACTION:
+ {
+ const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
+
+ if( pA->IsSetting() )
+ aSrcLineColor = pA->GetColor();
+ else
+ aSrcLineColor = Color( COL_TRANSPARENT );
+ }
+ break;
+
+ case META_FILLCOLOR_ACTION:
+ {
+ const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
+
+ if( pA->IsSetting() )
+ aSrcFillColor = pA->GetColor();
+ else
+ aSrcFillColor = Color( COL_TRANSPARENT );
+ }
+ break;
+
+ case META_TEXTCOLOR_ACTION:
+ {
+ const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
+ aSrcTextColor = pA->GetColor();
+ }
+ break;
+
+ case META_TEXTFILLCOLOR_ACTION:
+ {
+ const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
+ if( pA->IsSetting() )
+ aSrcFont.SetFillColor( pA->GetColor() );
+ else
+ aSrcFont.SetFillColor( Color( COL_TRANSPARENT ) );
+ }
+ break;
+
+ case META_TEXTALIGN_ACTION:
+ {
+ const MetaTextAlignAction* pA = (const MetaTextAlignAction*) pMA;
+ eSrcTextAlign = pA->GetTextAlign();
+ }
+ break;
+
+ case META_MAPMODE_ACTION:
+ {
+ const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
+
+ if (aSrcMapMode!=pA->GetMapMode())
+ {
+ if( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
+ {
+ MapMode aMM = pA->GetMapMode();
+ Fraction aScaleX = aMM.GetScaleX();
+ Fraction aScaleY = aMM.GetScaleY();
+
+ Point aOrigin = aSrcMapMode.GetOrigin();
+ BigInt aX( aOrigin.X() );
+ aX *= BigInt( aScaleX.GetDenominator() );
+ if( aOrigin.X() >= 0 )
+ if( aScaleX.GetNumerator() >= 0 )
+ aX += BigInt( aScaleX.GetNumerator()/2 );
+ else
+ aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
+ else
+ if( aScaleX.GetNumerator() >= 0 )
+ aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
+ else
+ aX += BigInt( aScaleX.GetNumerator()/2 );
+ aX /= BigInt( aScaleX.GetNumerator() );
+ aOrigin.X() = (long)aX + aMM.GetOrigin().X();
+ BigInt aY( aOrigin.Y() );
+ aY *= BigInt( aScaleY.GetDenominator() );
+ if( aOrigin.Y() >= 0 )
+ if( aScaleY.GetNumerator() >= 0 )
+ aY += BigInt( aScaleY.GetNumerator()/2 );
+ else
+ aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
+ else
+ if( aScaleY.GetNumerator() >= 0 )
+ aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
+ else
+ aY += BigInt( aScaleY.GetNumerator()/2 );
+ aY /= BigInt( aScaleY.GetNumerator() );
+ aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
+ aSrcMapMode.SetOrigin( aOrigin );
+
+ aScaleX *= aSrcMapMode.GetScaleX();
+ aScaleY *= aSrcMapMode.GetScaleY();
+ aSrcMapMode.SetScaleX( aScaleX );
+ aSrcMapMode.SetScaleY( aScaleY );
+ }
+ else
+ aSrcMapMode=pA->GetMapMode();
+ }
+ }
+ break;
+
+ case META_FONT_ACTION:
+ {
+ const MetaFontAction* pA = (const MetaFontAction*) pMA;
+ aSrcFont = pA->GetFont();
+
+ if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_DONTKNOW )
+ aSrcFont.SetCharSet( GetExtendedTextEncoding( gsl_getSystemTextEncoding() ) );
+ if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_UNICODE )
+ aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
+ eSrcTextAlign = aSrcFont.GetAlign();
+ aSrcTextColor = aSrcFont.GetColor();
+ aSrcFont.SetAlign( ALIGN_BASELINE );
+ aSrcFont.SetColor( COL_WHITE );
+ }
+ break;
+
+ case META_PUSH_ACTION:
+ {
+ const MetaPushAction* pA = (const MetaPushAction*)pMA;
+
+ WMFWriterAttrStackMember* pAt = new WMFWriterAttrStackMember;
+ pAt->nFlags = pA->GetFlags();
+ pAt->aClipRegion = aSrcClipRegion;
+ pAt->aLineColor=aSrcLineColor;
+ pAt->aFillColor=aSrcFillColor;
+ pAt->eRasterOp=eSrcRasterOp;
+ pAt->aFont=aSrcFont;
+ pAt->eTextAlign=eSrcTextAlign;
+ pAt->aTextColor=aSrcTextColor;
+ pAt->aMapMode=aSrcMapMode;
+ pAt->aLineInfo=aDstLineInfo;
+ pAt->pSucc=pAttrStack;
+ pAttrStack=pAt;
+
+ SetAllAttr(); // update ( now all source attributes are equal to the destination attributes )
+ WMFRecord_SaveDC();
+
+ }
+ break;
+
+ case META_POP_ACTION:
+ {
+ WMFWriterAttrStackMember * pAt=pAttrStack;
+
+ if( pAt )
+ {
+ aDstLineInfo = pAt->aLineInfo;
+ aDstLineColor = pAt->aLineColor;
+ if ( pAt->nFlags & PUSH_LINECOLOR )
+ aSrcLineColor = pAt->aLineColor;
+ aDstFillColor = pAt->aFillColor;
+ if ( pAt->nFlags & PUSH_FILLCOLOR )
+ aSrcFillColor = pAt->aFillColor;
+ eDstROP2 = pAt->eRasterOp;
+ if ( pAt->nFlags & PUSH_RASTEROP )
+ eSrcRasterOp = pAt->eRasterOp;
+ aDstFont = pAt->aFont;
+ if ( pAt->nFlags & PUSH_FONT )
+ aSrcFont = pAt->aFont;
+ eDstTextAlign = pAt->eTextAlign;
+ if ( pAt->nFlags & ( PUSH_FONT | PUSH_TEXTALIGN ) )
+ eSrcTextAlign = pAt->eTextAlign;
+ aDstTextColor = pAt->aTextColor;
+ if ( pAt->nFlags & ( PUSH_FONT | PUSH_TEXTCOLOR ) )
+ aSrcTextColor = pAt->aTextColor;
+ if ( pAt->nFlags & PUSH_MAPMODE )
+ aSrcMapMode = pAt->aMapMode;
+ aDstClipRegion = pAt->aClipRegion;
+ if ( pAt->nFlags & PUSH_CLIPREGION )
+ aSrcClipRegion = pAt->aClipRegion;
+
+ WMFRecord_RestoreDC();
+ pAttrStack = pAt->pSucc;
+ delete pAt;
+ }
+ }
+ break;
+
+ case META_EPS_ACTION :
+ {
+ const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
+ const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
+
+ INT32 nCount = aGDIMetaFile.GetActionCount();
+ for ( INT32 i = 0; i < nCount; i++ )
+ {
+ const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
+ if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
+ {
+ const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
+ break;
+ }
+ }
+ }
+ break;
+
+ case META_RASTEROP_ACTION:
+ {
+ const MetaRasterOpAction* pA = (const MetaRasterOpAction*) pMA;
+ eSrcRasterOp=pA->GetRasterOp();
+ }
+ break;
+
+ case META_TRANSPARENT_ACTION:
+ {
+ aSrcLineInfo = LineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_PolyPolygon( ( (MetaTransparentAction*) pMA )->GetPolyPolygon() );
+ }
+ break;
+
+ case META_FLOATTRANSPARENT_ACTION:
+ {
+ const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
+
+ GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
+ Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
+ const Size aSrcSize( aTmpMtf.GetPrefSize() );
+ const Point aDestPt( pA->GetPoint() );
+ const Size aDestSize( pA->GetSize() );
+ const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
+ const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
+ long nMoveX, nMoveY;
+
+ aSrcLineInfo = LineInfo();
+ SetAllAttr();
+
+ if( fScaleX != 1.0 || fScaleY != 1.0 )
+ {
+ aTmpMtf.Scale( fScaleX, fScaleY );
+ aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+ }
+
+ nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
+
+ if( nMoveX || nMoveY )
+ aTmpMtf.Move( nMoveX, nMoveY );
+
+ WriteRecords( aTmpMtf );
+ }
+ break;
+
+ case( META_LAYOUTMODE_ACTION ):
+ {
+ sal_uInt32 nLayoutMode = ( (MetaLayoutModeAction*) pMA )->GetLayoutMode();
+ eSrcHorTextAlign = 0; // TA_LEFT
+ if (nLayoutMode & TEXT_LAYOUT_BIDI_RTL)
+ {
+ eSrcHorTextAlign = W_TA_RIGHT | W_TA_RTLREADING;
+ }
+ if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT)
+ eSrcHorTextAlign |= W_TA_RIGHT;
+ else if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT)
+ eSrcHorTextAlign &= ~W_TA_RIGHT;
+ break;
+ }
+
+ // Unsupported Actions
+ case META_MASK_ACTION:
+ case META_MASKSCALE_ACTION:
+ case META_MASKSCALEPART_ACTION:
+ {
+ DBG_ERROR( "Unsupported action: MetaMask...Action!" );
+ }
+ break;
+
+ case META_CLIPREGION_ACTION:
+ break;
+
+ case META_ISECTREGIONCLIPREGION_ACTION:
+ {
+ DBG_ERROR( "Unsupported action: MetaISectRegionClipRegionAction!" );
+ }
+ break;
+
+ case META_MOVECLIPREGION_ACTION:
+ {
+ DBG_ERROR( "Unsupported action: MetaMoveClipRegionAction!" );
+ }
+ break;
+ }
+
+ nWrittenActions++;
+ MayCallback();
+
+ if (pWMF->GetError())
+ bStatus=FALSE;
+
+ if(bStatus==FALSE)
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::WriteHeader( const GDIMetaFile &, BOOL bPlaceable )
+{
+ if( bPlaceable )
+ {
+ USHORT nCheckSum, nValue;
+ Size aSize( pVirDev->LogicToLogic(Size(1,1),MapMode(MAP_INCH), aTargetMapMode) );
+ USHORT nUnitsPerInch = (USHORT) ( ( aSize.Width() + aSize.Height() ) >> 1 );
+
+ nCheckSum=0;
+ nValue=0xcdd7; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x9ac6; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=(USHORT) aTargetSize.Width(); nCheckSum^=nValue; *pWMF << nValue;
+ nValue=(USHORT) aTargetSize.Height(); nCheckSum^=nValue; *pWMF << nValue;
+ nValue=nUnitsPerInch; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ *pWMF << nCheckSum;
+ }
+
+ nMetafileHeaderPos=pWMF->Tell();
+ *pWMF << (sal_uInt16)0x0001 // Typ: Datei
+ << (sal_uInt16)0x0009 // Headerlaenge in Worten
+ << (sal_uInt16)0x0300 // Version als BCD-Zahl
+ << (sal_uInt32) 0x00000000 // Dateilaenge (ohne 1. Header), wird spaeter durch UpdateHeader() berichtigt
+ << (sal_uInt16)MAXOBJECTHANDLES // Maximalezahl der gleichzeitigen Objekte
+ << (sal_uInt32) 0x00000000 // Maximale Record-laenge, wird spaeter durch UpdateHeader() berichtigt
+ << (sal_uInt16)0x0000; // Reserved
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::UpdateHeader()
+{
+ ULONG nPos;
+ sal_uInt32 nFileSize;
+
+ nPos=pWMF->Tell(); // Endposition = Gesammtgroesse der Datei
+ nFileSize=nPos-nMetafileHeaderPos; // Groesse des 1. Headers abziehen
+ if ((nFileSize&1)!=0) { // ggf. auf ganze Worte aufrunden
+ *pWMF << (BYTE)0;
+ nPos++;
+ nFileSize++;
+ }
+ nFileSize>>=1; // In Anzahl Worte umrechnen
+ pWMF->Seek(nMetafileHeaderPos+6); // Zum Dateigroessen-Eintrag im zweiten Header
+ *pWMF << nFileSize; // Dateigroesse berichtigen
+ pWMF->SeekRel(2); // Zum Max-Record-Laenge-Eintrag im zweiten Header
+ *pWMF << nMaxRecordSize; // und berichtigen
+ pWMF->Seek(nPos);
+}
+
+// ------------------------------------------------------------------------
+
+BOOL WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
+ FilterConfigItem* pFConfigItem, BOOL bPlaceable )
+{
+ WMFWriterAttrStackMember * pAt;
+
+ bEmbedEMF = TRUE;
+ bStatus=TRUE;
+ pConvert = 0;
+ pVirDev = new VirtualDevice;
+
+ pFilterConfigItem = pFConfigItem;
+ if ( pFilterConfigItem )
+ {
+ xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
+ if ( xStatusIndicator.is() )
+ {
+ rtl::OUString aMsg;
+ xStatusIndicator->start( aMsg, 100 );
+ }
+ }
+ nLastPercent=0;
+
+ pWMF=&rTargetStream;
+ pWMF->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
+
+ nMaxRecordSize=0;
+
+ aSrcMapMode=rMTF.GetPrefMapMode();
+
+ if( bPlaceable )
+ {
+ aTargetMapMode = aSrcMapMode;
+ aTargetSize = rMTF.GetPrefSize();
+ nTargetDivisor = CalcSaveTargetMapMode(aTargetMapMode, aTargetSize);
+ aTargetSize.Width() /= nTargetDivisor;
+ aTargetSize.Height() /= nTargetDivisor;
+ }
+ else
+ {
+ aTargetMapMode = MapMode( MAP_INCH );
+
+ const long nUnit = pVirDev->LogicToPixel( Size( 1, 1 ), aTargetMapMode ).Width();
+ const Fraction aFrac( 1, nUnit );
+
+ aTargetMapMode.SetScaleX( aFrac );
+ aTargetMapMode.SetScaleY( aFrac );
+ aTargetSize = pVirDev->LogicToLogic( rMTF.GetPrefSize(), aSrcMapMode, aTargetMapMode );
+ }
+
+ pVirDev->SetMapMode( aTargetMapMode );
+
+ pAttrStack=NULL;
+
+ for (USHORT i=0; i<MAXOBJECTHANDLES; i++)
+ bHandleAllocated[i]=FALSE;
+
+ nDstPenHandle=0xffff;
+ nDstFontHandle=0xffff;
+ nDstBrushHandle=0xffff;
+
+ nNumberOfActions=0;
+ nNumberOfBitmaps=0;
+ nWrittenActions=0;
+ nWrittenBitmaps=0;
+ nActBitmapPercent=0;
+
+ CountActionsAndBitmaps(rMTF);
+
+ WriteHeader(rMTF,bPlaceable);
+ if( bEmbedEMF )
+ WriteEmbeddedEMF( rMTF );
+ WMFRecord_SetWindowOrg(Point(0,0));
+ WMFRecord_SetWindowExt(rMTF.GetPrefSize());
+ WMFRecord_SetBkMode( TRUE );
+
+ eDstROP2 = eSrcRasterOp = ROP_OVERPAINT;
+ WMFRecord_SetROP2(eDstROP2);
+
+ aDstLineInfo = LineInfo();
+ aDstLineColor = aSrcLineColor = Color( COL_BLACK );
+ CreateSelectDeletePen( aDstLineColor, aDstLineInfo );
+
+ aDstFillColor = aSrcFillColor = Color( COL_WHITE );
+ CreateSelectDeleteBrush( aDstFillColor );
+
+ aDstClipRegion = aSrcClipRegion = Region();
+ bDstIsClipping = bSrcIsClipping = FALSE;
+
+ Font aFont;
+ aFont.SetCharSet( GetExtendedTextEncoding( gsl_getSystemTextEncoding() ) );
+ aFont.SetColor( Color( COL_WHITE ) );
+ aFont.SetAlign( ALIGN_BASELINE );
+ aDstFont = aSrcFont = aFont;
+ CreateSelectDeleteFont(aDstFont);
+
+ eDstTextAlign = eSrcTextAlign = ALIGN_BASELINE;
+ eDstHorTextAlign = eSrcHorTextAlign = W_TA_LEFT;
+ WMFRecord_SetTextAlign( eDstTextAlign, eDstHorTextAlign );
+
+ aDstTextColor = aSrcTextColor = Color( COL_WHITE );
+ WMFRecord_SetTextColor(aDstTextColor);
+
+ // Write records
+ WriteRecords(rMTF);
+
+ WMFRecord_EndOfFile();
+ UpdateHeader();
+
+ while(pAttrStack)
+ {
+ pAt=pAttrStack;
+ pAttrStack=pAt->pSucc;
+ delete pAt;
+ }
+
+ delete pVirDev;
+ delete pConvert;
+
+ if ( xStatusIndicator.is() )
+ xStatusIndicator->end();
+
+ return bStatus;
+}
+
+// ------------------------------------------------------------------------
+
+USHORT WMFWriter::CalcSaveTargetMapMode(MapMode& rMapMode,
+ const Size& rPrefSize)
+{
+ Fraction aDivFrac(2, 1);
+ USHORT nDivisor = 1;
+
+ Size aSize = pVirDev->LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
+
+ while( nDivisor <= 64 && (aSize.Width() > 32767 || aSize.Height() > 32767) )
+ {
+ Fraction aFrac = rMapMode.GetScaleX();
+
+ aFrac *= aDivFrac;
+ rMapMode.SetScaleX(aFrac);
+ aFrac = rMapMode.GetScaleY();
+ aFrac *= aDivFrac;
+ rMapMode.SetScaleY(aFrac);
+ nDivisor <<= 1;
+ aSize = pVirDev->LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
+ }
+
+ return nDivisor;
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::WriteEmbeddedEMF( const GDIMetaFile& rMTF )
+{
+ EMFWriter aEMFWriter;
+ SvMemoryStream aStream;
+
+ if( aEMFWriter.WriteEMF( rMTF, aStream ) )
+ {
+ sal_Size nTotalSize = aStream.Tell();
+ if( nTotalSize > SAL_MAX_UINT32 )
+ return;
+ aStream.Seek( 0 );
+ sal_uInt32 nRemainingSize = static_cast< sal_uInt32 >( nTotalSize );
+ sal_uInt32 nRecCounts = ( (nTotalSize - 1) / 0x2000 ) + 1;
+ sal_uInt16 nCheckSum = 0, nWord;
+
+ sal_uInt32 nPos = 0;
+
+ while( nPos + 1 < nTotalSize )
+ {
+ aStream >> nWord;
+ nCheckSum ^= nWord;
+ nPos += 2;
+ }
+
+ nCheckSum = static_cast< sal_uInt16 >( nCheckSum * -1 );
+
+ aStream.Seek( 0 );
+ while( nRemainingSize > 0 )
+ {
+ sal_uInt32 nCurSize;
+ if( nRemainingSize > 0x2000 )
+ {
+ nCurSize = 0x2000;
+ nRemainingSize -= 0x2000;
+ }
+ else
+ {
+ nCurSize = nRemainingSize;
+ nRemainingSize = 0;
+ }
+ WriteEMFRecord( aStream,
+ nCurSize,
+ nRemainingSize,
+ nTotalSize,
+ nRecCounts,
+ nCheckSum );
+ nCheckSum = 0;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize,
+ sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum )
+{
+ // according to http://msdn.microsoft.com/en-us/library/dd366152%28PROT.13%29.aspx
+ WriteRecordHeader( 0, W_META_ESCAPE );
+ *pWMF << (sal_uInt16)W_MFCOMMENT // same as META_ESCAPE_ENHANCED_METAFILE
+ << (sal_uInt16)( nCurSize + 34 ) // we will always have a 34 byte escape header:
+ << (sal_uInt32) 0x43464D57 // WMFC
+ << (sal_uInt32) 0x00000001 // Comment type
+ << (sal_uInt32) 0x00010000 // version
+ << nCheckSum // check sum
+ << (sal_uInt32) 0 // flags = 0
+ << nRecCounts // total number of records
+ << nCurSize // size of this record's data
+ << nRemainingSize // remaining size of data in following records, missing in MSDN documentation
+ << nTotalSize; // total size of EMF stream
+
+ pWMF->Write( static_cast< const sal_Char* >( rStream.GetData() ) + rStream.Tell(), nCurSize );
+ rStream.SeekRel( nCurSize );
+ UpdateRecordHeader();
+}
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.hxx b/svtools/source/filter.vcl/wmf/wmfwr.hxx
new file mode 100644
index 000000000000..9fe698b22c2e
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/wmfwr.hxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WMFWR_HXX
+#define _WMFWR_HXX
+
+#include <tools/bigint.hxx>
+#include <tools/debug.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/virdev.hxx>
+#include <svtools/fltcall.hxx>
+
+// -----------------------------------------------------------------------------
+
+#define MAXOBJECTHANDLES 16
+
+// -----------------------------------------------------------------------------
+
+struct WMFWriterAttrStackMember
+{
+ struct WMFWriterAttrStackMember * pSucc;
+ Color aLineColor;
+ Color aFillColor;
+ Color aTextColor;
+ LineInfo aLineInfo;
+ TextAlign eTextAlign;
+ RasterOp eRasterOp;
+ Font aFont;
+ MapMode aMapMode;
+ Region aClipRegion;
+ sal_uInt16 nFlags;
+};
+
+// -------------
+// - WMFWriter -
+// -------------
+
+class StarSymbolToMSMultiFont;
+class LineInfo;
+namespace basegfx { class B2DPolygon; }
+
+class WMFWriter
+{
+private:
+
+ BOOL bStatus;
+
+ ULONG nLastPercent; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
+ FilterConfigItem* pFilterConfigItem;
+
+ com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
+
+ SvStream* pWMF;
+ VirtualDevice* pVirDev;
+ StarSymbolToMSMultiFont *pConvert;
+ MapMode aTargetMapMode;
+ Size aTargetSize;
+ USHORT nTargetDivisor;
+
+ ULONG nMetafileHeaderPos;
+ sal_uInt32 nMaxRecordSize; // in Worten
+ ULONG nActRecordPos;
+
+ // Aktuelle Attribute im Quell-Metafile:
+ Color aSrcLineColor;
+ Color aSrcFillColor;
+ Color aSrcTextColor;
+ LineInfo aSrcLineInfo;
+ RasterOp eSrcRasterOp;
+ FontAlign eSrcTextAlign;
+ Font aSrcFont;
+ MapMode aSrcMapMode;
+ BOOL bSrcIsClipping;
+ Region aSrcClipRegion;
+ WMFWriterAttrStackMember * pAttrStack;
+
+ UINT32 eSrcHorTextAlign;
+
+ // Aktuelle Attribute im Ziel-Metafile:
+ Color aDstLineColor;
+ Color aDstFillColor;
+ Color aDstTextColor;
+ LineInfo aDstLineInfo;
+ RasterOp eDstROP2;
+ FontAlign eDstTextAlign;
+ Font aDstFont;
+
+ UINT32 eDstHorTextAlign;
+
+ BOOL bDstIsClipping; // ???: derzeit unberuecksichtigt
+ Region aDstClipRegion; // ???: derzeit unberuecksichtigt
+ BOOL bHandleAllocated[MAXOBJECTHANDLES]; // Welche Handles vergeben sind
+ USHORT nDstPenHandle,nDstFontHandle,nDstBrushHandle; // Welche Handles die jeweiligen
+ // Selected-Objects besitzen
+ // 0xffff = keines:
+
+ // Damit nicht bei jeder Operation alle Attribute verglichen werden muessen:
+
+ ULONG nNumberOfActions; // Anzahl der Actions im GDIMetafile
+ ULONG nNumberOfBitmaps; // Anzahl der Bitmaps
+ ULONG nWrittenActions; // Anzahl der bereits verarbeiteten Actions beim Schreiben der Orders
+ ULONG nWrittenBitmaps; // Anzahl der bereits geschriebenen Bitmaps
+ ULONG nActBitmapPercent; // Wieviel Prozent die naechste Bitmap schon geschrieben ist.
+
+ BOOL bEmbedEMF; // optionally embedd EMF data into WMF
+
+ void MayCallback();
+ // Berechnet anhand der obigen 5 Parameter eine Prozentzahl
+ // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
+ // moechte.
+
+ void CountActionsAndBitmaps(const GDIMetaFile & rMTF);
+ // Zaehlt die Bitmaps und Actions (nNumberOfActions und nNumberOfBitmaps muessen
+ // zu Anfang auf 0 gesetzt werden, weil diese Methode rekursiv ist)
+
+ void WritePointXY(const Point & rPoint);
+ void WritePointYX(const Point & rPoint);
+ sal_Int32 ScaleWidth( sal_Int32 nDX );
+ void WriteSize(const Size & rSize);
+ void WriteHeightWidth(const Size & rSize);
+ void WriteRectangle(const Rectangle & rRect);
+ void WriteColor(const Color & rColor);
+
+ void WriteRecordHeader(sal_uInt32 nSizeWords, sal_uInt16 nType);
+ // nSizeWords ist die Groesse des gesammten Records in Anzahl Worte.
+ // Wenn nSizeWords unbekannt ist, dann 0 einsetzen (siehe UpdateRecordHeader()).
+
+ void UpdateRecordHeader();
+ // berichtig die Groesse des Records nach dem Schreiben der Parameter, wenn
+ // nSizeWords bei Aufruf von WriteRecordHeader(..) unbekannt war.
+ // fuegt ggf. noch ein BYTE 0 ein damit Anzahl Bytes immer gerade.
+
+ void WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
+ void WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
+ void WMFRecord_CreateBrushIndirect(const Color& rColor);
+ void WMFRecord_CreateFontIndirect(const Font & rFont);
+ void WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo );
+ void WMFRecord_DeleteObject(USHORT nObjectHandle);
+ void WMFRecord_Ellipse(const Rectangle & rRect);
+ void WMFRecord_Escape( sal_uInt32 nEsc, sal_uInt32 nLen, const sal_Int8* pData );
+ sal_Bool WMFRecord_Escape_Unicode( const Point& rPoint, const String& rStr, const sal_Int32 * pDXAry );
+ void WMFRecord_ExtTextOut(const Point & rPoint, const String & rString, const sal_Int32 * pDXAry);
+
+ void TrueExtTextOut(const Point & rPoint, const String & rString,
+ const ByteString & rByteString, const sal_Int32 * pDXAry);
+ void TrueTextOut(const Point & rPoint, const ByteString& rString);
+ void WMFRecord_LineTo(const Point & rPoint);
+ void WMFRecord_MoveTo(const Point & rPoint);
+ void WMFRecord_Pie(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
+ void WMFRecord_Polygon(const Polygon & rPoly);
+ void WMFRecord_PolyLine(const Polygon & rPoly);
+ void WMFRecord_PolyPolygon(const PolyPolygon & rPolyPoly);
+ void WMFRecord_Rectangle(const Rectangle & rRect);
+ void WMFRecord_RestoreDC();
+ void WMFRecord_RoundRect(const Rectangle & rRect, long nHorzRound, long nVertRound);
+ void WMFRecord_SaveDC();
+ void WMFRecord_SelectObject(USHORT nObjectHandle);
+ void WMFRecord_SetBkColor(const Color & rColor);
+ void WMFRecord_SetBkMode(BOOL bTransparent);
+ void WMFRecord_SetStretchBltMode();
+ void WMFRecord_SetPixel(const Point & rPoint, const Color & rColor);
+ void WMFRecord_SetROP2(RasterOp eROP);
+ void WMFRecord_SetTextAlign(FontAlign eFontAlign, UINT32 eHorTextAlign);
+ void WMFRecord_SetTextColor(const Color & rColor);
+ void WMFRecord_SetWindowExt(const Size & rSize);
+ void WMFRecord_SetWindowOrg(const Point & rPoint);
+ void WMFRecord_StretchDIB(const Point & rPoint, const Size & rSize, const Bitmap & rBitmap, sal_uInt32 nROP = 0UL );
+ void WMFRecord_TextOut(const Point & rPoint, const String & rString);
+ void WMFRecord_EndOfFile();
+ void WMFRecord_IntersectClipRect( const Rectangle& rRect);
+
+ USHORT AllocHandle();
+ void FreeHandle(USHORT nObjectHandle);
+ void CreateSelectDeletePen( const Color& rColor, const LineInfo& rLineInfo );
+ void CreateSelectDeleteFont(const Font & rFont);
+ void CreateSelectDeleteBrush(const Color& rColor);
+
+ void SetLineAndFillAttr();
+ void SetAllAttr();
+
+ void HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
+ void WriteRecords(const GDIMetaFile & rMTF);
+
+ void WriteHeader(const GDIMetaFile & rMTF, BOOL bPlaceable);
+ void UpdateHeader();
+
+ void WriteEmbeddedEMF( const GDIMetaFile& rMTF );
+ void WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize,
+ sal_uInt32 nRemainingSize,
+ sal_uInt32 nTotalSize,
+ sal_uInt32 nRecCounts,
+ sal_uInt16 nCheckSum );
+
+ USHORT CalcSaveTargetMapMode(MapMode& rMapMode, const Size& rPrefSize);
+
+public:
+
+ WMFWriter() {}
+
+ BOOL WriteWMF(const GDIMetaFile & rMTF, SvStream & rTargetStream, FilterConfigItem* pFilterConfigItem, BOOL bPlaceable=TRUE);
+};
+
+#endif
diff --git a/svtools/source/graphic/descriptor.cxx b/svtools/source/graphic/descriptor.cxx
new file mode 100644
index 000000000000..5db73e6cc2f3
--- /dev/null
+++ b/svtools/source/graphic/descriptor.cxx
@@ -0,0 +1,498 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "descriptor.hxx"
+
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <svtools/filter.hxx>
+#include <svl/itemprop.hxx>
+
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/graphic/GraphicType.hpp>
+
+#include "vcl/graph.hxx"
+#include "vcl/svapp.hxx"
+
+#define UNOGRAPHIC_GRAPHICTYPE 1
+#define UNOGRAPHIC_MIMETYPE 2
+#define UNOGRAPHIC_SIZEPIXEL 3
+#define UNOGRAPHIC_SIZE100THMM 4
+#define UNOGRAPHIC_BITSPERPIXEL 5
+#define UNOGRAPHIC_TRANSPARENT 6
+#define UNOGRAPHIC_ALPHA 7
+#define UNOGRAPHIC_ANIMATED 8
+
+using namespace ::com::sun::star;
+
+namespace unographic {
+
+// ---------------------
+// - GraphicDescriptor -
+// ---------------------
+
+GraphicDescriptor::GraphicDescriptor() :
+ ::comphelper::PropertySetHelper( createPropertySetInfo(), SAL_NO_ACQUIRE ),
+ mpGraphic( NULL ),
+ meType( GRAPHIC_NONE ),
+ mnBitsPerPixel ( 0 ),
+ mbTransparent ( false ),
+ mbAlpha( false ),
+ mbAnimated( false )
+{
+}
+
+// ------------------------------------------------------------------------------
+
+GraphicDescriptor::~GraphicDescriptor()
+ throw()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicDescriptor::init( const ::Graphic& rGraphic )
+ throw()
+{
+ mpGraphic = &rGraphic;
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicDescriptor::init( const ::rtl::OUString& rURL )
+ throw()
+{
+ SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rURL, STREAM_READ );
+
+ if( pIStm )
+ {
+ implCreate( *pIStm, &rURL );
+ delete pIStm;
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicDescriptor::init( const uno::Reference< io::XInputStream >& rxIStm, const ::rtl::OUString& rURL )
+ throw()
+{
+ SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rxIStm );
+
+ if( pIStm )
+ {
+ implCreate( *pIStm, &rURL );
+ delete pIStm;
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+bool GraphicDescriptor::isValid() const
+{
+ return( mpGraphic ? ( mpGraphic->GetType() != GRAPHIC_NONE ) : ( meType != GRAPHIC_NONE ) );
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicDescriptor::implCreate( SvStream& rIStm, const ::rtl::OUString* pURL )
+{
+ String aURL;
+ if( pURL )
+ aURL = *pURL;
+ ::GraphicDescriptor aDescriptor( rIStm, &aURL );
+
+ mpGraphic = NULL;
+ maMimeType = ::rtl::OUString();
+ meType = GRAPHIC_NONE;
+ mnBitsPerPixel = 0;
+ mbTransparent = false;
+
+ if( aDescriptor.Detect( true ) && aDescriptor.GetFileFormat() != GFF_NOT )
+ {
+ const char* pMimeType = NULL;
+ sal_uInt8 cType = graphic::GraphicType::EMPTY;
+
+ switch( aDescriptor.GetFileFormat() )
+ {
+ case( GFF_BMP ): pMimeType = MIMETYPE_BMP; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_GIF ): pMimeType = MIMETYPE_GIF; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_JPG ): pMimeType = MIMETYPE_JPG; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PCD ): pMimeType = MIMETYPE_PCD; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PCX ): pMimeType = MIMETYPE_PCX; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PNG ): pMimeType = MIMETYPE_PNG; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_TIF ): pMimeType = MIMETYPE_TIF; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_XBM ): pMimeType = MIMETYPE_XBM; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_XPM ): pMimeType = MIMETYPE_XPM; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PBM ): pMimeType = MIMETYPE_PBM; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PGM ): pMimeType = MIMETYPE_PGM; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PPM ): pMimeType = MIMETYPE_PPM; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_RAS ): pMimeType = MIMETYPE_RAS; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_TGA ): pMimeType = MIMETYPE_TGA; cType = graphic::GraphicType::PIXEL; break;
+ case( GFF_PSD ): pMimeType = MIMETYPE_PSD; cType = graphic::GraphicType::PIXEL; break;
+
+ case( GFF_EPS ): pMimeType = MIMETYPE_EPS; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_DXF ): pMimeType = MIMETYPE_DXF; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_MET ): pMimeType = MIMETYPE_MET; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_PCT ): pMimeType = MIMETYPE_PCT; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_SGF ): pMimeType = MIMETYPE_SGF; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_SVM ): pMimeType = MIMETYPE_SVM; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_WMF ): pMimeType = MIMETYPE_WMF; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_SGV ): pMimeType = MIMETYPE_SGV; cType = graphic::GraphicType::VECTOR; break;
+ case( GFF_EMF ): pMimeType = MIMETYPE_EMF; cType = graphic::GraphicType::VECTOR; break;
+
+ default:
+ break;
+ }
+
+ if( graphic::GraphicType::EMPTY != cType )
+ {
+ meType = ( ( graphic::GraphicType::PIXEL == cType ) ? GRAPHIC_BITMAP : GRAPHIC_GDIMETAFILE );
+ maMimeType = String( pMimeType, RTL_TEXTENCODING_ASCII_US );
+ maSizePixel = aDescriptor.GetSizePixel();
+ maSize100thMM = aDescriptor.GetSize_100TH_MM();
+ mnBitsPerPixel = aDescriptor.GetBitsPerPixel();
+ mbTransparent = ( graphic::GraphicType::VECTOR == cType );
+ mbAlpha = mbAnimated = false;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString GraphicDescriptor::getImplementationName_Static()
+ throw()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicDescriptor" ) );
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > GraphicDescriptor::getSupportedServiceNames_Static()
+ throw( )
+{
+ uno::Sequence< ::rtl::OUString > aSeq( 1 );
+
+ aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicDescriptor" ) );
+
+ return aSeq;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Any SAL_CALL GraphicDescriptor::queryAggregation( const uno::Type & rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aAny;
+
+ if( rType == ::getCppuType((const uno::Reference< lang::XServiceInfo >*)0) )
+ aAny <<= uno::Reference< lang::XServiceInfo >(this);
+ else if( rType == ::getCppuType((const uno::Reference< lang::XTypeProvider >*)0) )
+ aAny <<= uno::Reference< lang::XTypeProvider >(this);
+ else if( rType == ::getCppuType((const uno::Reference< beans::XPropertySet >*)0) )
+ aAny <<= uno::Reference< beans::XPropertySet >(this);
+ else if( rType == ::getCppuType((const uno::Reference< beans::XPropertyState >*)0) )
+ aAny <<= uno::Reference< beans::XPropertyState >(this);
+ else if( rType == ::getCppuType((const uno::Reference< beans::XMultiPropertySet >*)0) )
+ aAny <<= uno::Reference< beans::XMultiPropertySet >(this);
+ else
+ aAny <<= OWeakAggObject::queryAggregation( rType );
+
+ return aAny;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Any SAL_CALL GraphicDescriptor::queryInterface( const uno::Type & rType )
+ throw( uno::RuntimeException )
+{
+ return OWeakAggObject::queryInterface( rType );
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL GraphicDescriptor::acquire()
+ throw()
+{
+ OWeakAggObject::acquire();
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL GraphicDescriptor::release()
+ throw()
+{
+ OWeakAggObject::release();
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL GraphicDescriptor::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL GraphicDescriptor::supportsService( const rtl::OUString& ServiceName )
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
+ const ::rtl::OUString* pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL GraphicDescriptor::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< uno::Type > SAL_CALL GraphicDescriptor::getTypes()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< uno::Type > aTypes( 6 );
+ uno::Type* pTypes = aTypes.getArray();
+
+ *pTypes++ = ::getCppuType((const uno::Reference< uno::XAggregation>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< beans::XPropertySet>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< beans::XPropertyState>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< beans::XMultiPropertySet>*)0);
+
+ return aTypes;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< sal_Int8 > SAL_CALL GraphicDescriptor::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ 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;
+}
+
+// ------------------------------------------------------------------------------
+
+::comphelper::PropertySetInfo* GraphicDescriptor::createPropertySetInfo()
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ ::comphelper::PropertySetInfo* pRet = new ::comphelper::PropertySetInfo();
+
+ static ::comphelper::PropertyMapEntry aEntries[] =
+ {
+ { MAP_CHAR_LEN( "GraphicType" ), UNOGRAPHIC_GRAPHICTYPE, &::getCppuType( (const sal_Int8*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "MimeType" ), UNOGRAPHIC_MIMETYPE, &::getCppuType( (const ::rtl::OUString*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "SizePixel" ), UNOGRAPHIC_SIZEPIXEL, &::getCppuType( (const awt::Size*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "Size100thMM" ), UNOGRAPHIC_SIZE100THMM, &::getCppuType( (const awt::Size*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "BitsPerPixel" ), UNOGRAPHIC_BITSPERPIXEL, &::getCppuType( (const sal_uInt8*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "Transparent" ), UNOGRAPHIC_TRANSPARENT, &::getCppuType( (const sal_Bool*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "Alpha" ), UNOGRAPHIC_ALPHA, &::getCppuType( (const sal_Bool*)(0)), beans::PropertyAttribute::READONLY, 0 },
+ { MAP_CHAR_LEN( "Animated" ), UNOGRAPHIC_ANIMATED, &::getCppuType( (const sal_Bool*)(0)), beans::PropertyAttribute::READONLY, 0 },
+
+ { 0,0,0,0,0,0 }
+ };
+
+ pRet->acquire();
+ pRet->add( aEntries );
+
+ return pRet;
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicDescriptor::_setPropertyValues( const comphelper::PropertyMapEntry** /*ppEntries*/, const uno::Any* /*pValues*/ )
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException )
+{
+ // we only have readonly attributes
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicDescriptor::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, uno::Any* pValues )
+ throw( beans::UnknownPropertyException, lang::WrappedTargetException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ while( *ppEntries )
+ {
+ switch( (*ppEntries)->mnHandle )
+ {
+ case( UNOGRAPHIC_GRAPHICTYPE ):
+ {
+ const GraphicType eType( mpGraphic ? mpGraphic->GetType() : meType );
+
+ *pValues <<= ( ( eType == GRAPHIC_BITMAP ? graphic::GraphicType::PIXEL :
+ ( eType == GRAPHIC_GDIMETAFILE ? graphic::GraphicType::VECTOR :
+ graphic::GraphicType::EMPTY ) ) );
+ }
+ break;
+
+ case( UNOGRAPHIC_MIMETYPE ):
+ {
+ ::rtl::OUString aMimeType;
+
+ if( mpGraphic )
+ {
+ if( mpGraphic->IsLink() )
+ {
+ const char* pMimeType;
+
+ switch( const_cast< Graphic* >( mpGraphic )->GetLink().GetType() )
+ {
+ case( GFX_LINK_TYPE_NATIVE_GIF ): pMimeType = MIMETYPE_GIF; break;
+ case( GFX_LINK_TYPE_NATIVE_JPG ): pMimeType = MIMETYPE_JPG; break;
+ case( GFX_LINK_TYPE_NATIVE_PNG ): pMimeType = MIMETYPE_PNG; break;
+ case( GFX_LINK_TYPE_NATIVE_WMF ): pMimeType = MIMETYPE_WMF; break;
+ case( GFX_LINK_TYPE_NATIVE_MET ): pMimeType = MIMETYPE_MET; break;
+ case( GFX_LINK_TYPE_NATIVE_PCT ): pMimeType = MIMETYPE_PCT ; break;
+
+ default:
+ pMimeType = NULL;
+ break;
+ }
+
+ if( pMimeType )
+ aMimeType = ::rtl::OUString::createFromAscii( pMimeType );
+ }
+
+ if( !aMimeType.getLength() && ( mpGraphic->GetType() != GRAPHIC_NONE ) )
+ aMimeType = ::rtl::OUString::createFromAscii( MIMETYPE_VCLGRAPHIC );
+ }
+ else
+ aMimeType = maMimeType;
+
+ *pValues <<= aMimeType;
+ }
+ break;
+
+ case( UNOGRAPHIC_SIZEPIXEL ):
+ {
+ awt::Size aAWTSize( 0, 0 );
+
+ if( mpGraphic )
+ {
+ if( mpGraphic->GetType() == GRAPHIC_BITMAP )
+ {
+ const Size aSizePix( mpGraphic->GetBitmapEx().GetSizePixel() );
+ aAWTSize = awt::Size( aSizePix.Width(), aSizePix.Height() );
+ }
+ }
+ else
+ aAWTSize = awt::Size( maSizePixel.Width(), maSizePixel.Height() );
+
+ *pValues <<= aAWTSize;
+ }
+ break;
+
+ case( UNOGRAPHIC_SIZE100THMM ):
+ {
+ awt::Size aAWTSize( 0, 0 );
+
+ if( mpGraphic )
+ {
+ if( mpGraphic->GetPrefMapMode().GetMapUnit() != MAP_PIXEL )
+ {
+ const Size aSizeLog( OutputDevice::LogicToLogic( mpGraphic->GetPrefSize(), mpGraphic->GetPrefMapMode(), MAP_100TH_MM ) );
+ aAWTSize = awt::Size( aSizeLog.Width(), aSizeLog.Height() );
+ }
+ }
+ else
+ aAWTSize = awt::Size( maSize100thMM.Width(), maSize100thMM.Height() );
+
+ *pValues <<= aAWTSize;
+ }
+ break;
+
+ case( UNOGRAPHIC_BITSPERPIXEL ):
+ {
+ USHORT nBitsPerPixel = 0;
+
+ if( mpGraphic )
+ {
+ if( mpGraphic->GetType() == GRAPHIC_BITMAP )
+ nBitsPerPixel = mpGraphic->GetBitmapEx().GetBitmap().GetBitCount();
+ }
+ else
+ nBitsPerPixel = mnBitsPerPixel;
+
+ *pValues <<= sal::static_int_cast< sal_Int8 >(nBitsPerPixel);
+ }
+ break;
+
+ case( UNOGRAPHIC_TRANSPARENT ):
+ {
+ *pValues <<= static_cast< sal_Bool >( mpGraphic ? mpGraphic->IsTransparent() : mbTransparent );
+ }
+ break;
+
+ case( UNOGRAPHIC_ALPHA ):
+ {
+ *pValues <<= static_cast< sal_Bool >( mpGraphic ? mpGraphic->IsAlpha() : mbAlpha );
+ }
+ break;
+
+ case( UNOGRAPHIC_ANIMATED ):
+ {
+ *pValues <<= static_cast< sal_Bool >( mpGraphic ? mpGraphic->IsAnimated() : mbAnimated );
+ }
+ break;
+ }
+
+ ++ppEntries;
+ ++pValues;
+ }
+}
+
+}
diff --git a/svtools/source/graphic/descriptor.hxx b/svtools/source/graphic/descriptor.hxx
new file mode 100644
index 000000000000..bed7c64c0411
--- /dev/null
+++ b/svtools/source/graphic/descriptor.hxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _GOODIES_DESCRIPTOR_HXX
+#define _GOODIES_DESCRIPTOR_HXX
+
+#include <comphelper/propertysethelper.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#include <comphelper/propertysetinfo.hxx>
+#include <vcl/graph.hxx>
+
+#define MIMETYPE_BMP "image/x-MS-bmp"
+#define MIMETYPE_GIF "image/gif"
+#define MIMETYPE_JPG "image/jpeg"
+#define MIMETYPE_PCD "image/x-photo-cd"
+#define MIMETYPE_PCX "image/x-pcx"
+#define MIMETYPE_PNG "image/png"
+#define MIMETYPE_TIF "image/tiff"
+#define MIMETYPE_XBM "image/x-xbitmap"
+#define MIMETYPE_XPM "image/x-xpixmap"
+#define MIMETYPE_PBM "image/x-portable-bitmap"
+#define MIMETYPE_PGM "image/x-portable-graymap"
+#define MIMETYPE_PPM "image/x-portable-pixmap"
+#define MIMETYPE_RAS "image/x-cmu-raster"
+#define MIMETYPE_TGA "image/x-targa"
+#define MIMETYPE_PSD "image/vnd.adobe.photoshop"
+#define MIMETYPE_EPS "image/x-eps"
+#define MIMETYPE_DXF "image/vnd.dxf"
+#define MIMETYPE_MET "image/x-met"
+#define MIMETYPE_PCT "image/x-pict"
+#define MIMETYPE_SGF "image/x-sgf"
+#define MIMETYPE_SVM "image/x-svm"
+#define MIMETYPE_WMF "image/x-wmf"
+#define MIMETYPE_SGV "image/x-sgv"
+#define MIMETYPE_EMF "image/x-emf"
+#define MIMETYPE_SVG "image/svg+xml"
+#define MIMETYPE_VCLGRAPHIC "image/x-vclgraphic"
+
+using namespace com::sun::star;
+
+namespace comphelper { class PropertySetInfo; }
+namespace com { namespace sun { namespace star { namespace io { class XInputStream; } } } }
+
+class Graphic;
+
+namespace unographic {
+
+// -------------------
+// - GraphicProvider -
+// -------------------
+
+class GraphicDescriptor : public ::cppu::OWeakAggObject,
+ public ::com::sun::star::lang::XServiceInfo,
+ public ::com::sun::star::lang::XTypeProvider,
+ public ::comphelper::PropertySetHelper
+{
+public:
+
+ GraphicDescriptor();
+ ~GraphicDescriptor() throw();
+
+ void init( const ::Graphic& rGraphic ) throw();
+ void init( const ::rtl::OUString& rURL ) throw();
+ void init( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxIStm, const ::rtl::OUString& rURL ) throw();
+
+ bool isValid() const;
+
+ static ::rtl::OUString getImplementationName_Static() throw();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static() throw();
+
+protected:
+
+ static ::comphelper::PropertySetInfo* createPropertySetInfo();
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ 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
+ 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 );
+
+ // 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);
+
+ // PropertySetHelper
+ virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const ::com::sun::star::uno::Any* pValues ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException );
+ virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::uno::Any* pValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException );
+
+private:
+
+ const ::Graphic* mpGraphic;
+ GraphicType meType;
+ ::rtl::OUString maMimeType;
+ Size maSizePixel;
+ Size maSize100thMM;
+ USHORT mnBitsPerPixel;
+ bool mbTransparent;
+ bool mbAlpha;
+ bool mbAnimated;
+
+ GraphicDescriptor( const GraphicDescriptor& rDescriptor );
+
+ GraphicDescriptor& operator=( const GraphicDescriptor& );
+
+ void implCreate( SvStream& rIStm, const ::rtl::OUString* pPath );
+};
+
+}
+
+#endif
diff --git a/svtools/source/graphic/graphic.cxx b/svtools/source/graphic/graphic.cxx
new file mode 100644
index 000000000000..52c03c611241
--- /dev/null
+++ b/svtools/source/graphic/graphic.cxx
@@ -0,0 +1,300 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/graphic/GraphicType.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+#include <vcl/graph.hxx>
+#include "graphic.hxx"
+
+using namespace com::sun::star;
+
+namespace unographic {
+
+// -------------------
+// - GraphicProvider -
+// -------------------
+
+Graphic::Graphic() :
+ mpGraphic( NULL )
+{
+}
+
+// ------------------------------------------------------------------------------
+
+Graphic::~Graphic()
+ throw()
+{
+ delete mpGraphic;
+}
+
+// ------------------------------------------------------------------------------
+
+void Graphic::init( const ::Graphic& rGraphic )
+ throw()
+{
+ delete mpGraphic;
+ mpGraphic = new ::Graphic( rGraphic );
+ ::unographic::GraphicDescriptor::init( *mpGraphic );
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Any SAL_CALL Graphic::queryAggregation( const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aAny;
+ if( rType == ::getCppuType((const uno::Reference< graphic::XGraphic >*)0) )
+ aAny <<= uno::Reference< graphic::XGraphic >( this );
+ else if( rType == ::getCppuType((const uno::Reference< awt::XBitmap >*)0) )
+ aAny <<= uno::Reference< awt::XBitmap >( this );
+ else if( rType == ::getCppuType((const uno::Reference< lang::XUnoTunnel >*)0) )
+ aAny <<= uno::Reference< lang::XUnoTunnel >(this);
+ else
+ aAny <<= ::unographic::GraphicDescriptor::queryAggregation( rType );
+
+ return aAny ;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Any SAL_CALL Graphic::queryInterface( const uno::Type & rType )
+ throw( uno::RuntimeException )
+{
+ ::com::sun::star::uno::Any aReturn = ::unographic::GraphicDescriptor::queryInterface( rType );
+ if ( !aReturn.hasValue() )
+ aReturn = ::cppu::queryInterface ( rType, static_cast< graphic::XGraphicTransformer*>( this ) );
+ return aReturn;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Graphic::acquire()
+ throw()
+{
+ ::unographic::GraphicDescriptor::acquire();
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Graphic::release() throw()
+{
+ ::unographic::GraphicDescriptor::release();
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< sal_Int8 > SAL_CALL Graphic::getImplementationId_Static()
+ throw(uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ 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 Graphic::getImplementationName_Static()
+ throw()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.Graphic" ) );
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > Graphic::getSupportedServiceNames_Static()
+ throw()
+{
+ uno::Sequence< ::rtl::OUString > aSeq( 1 );
+
+ aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.Graphic" ) );
+
+ return aSeq;
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL Graphic::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Graphic::supportsService( const ::rtl::OUString& rServiceName )
+ throw( uno::RuntimeException )
+{
+ if( ::unographic::GraphicDescriptor::supportsService( rServiceName ) )
+ return true;
+ else
+ {
+ uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
+ const ::rtl::OUString* pArray = aSNL.getConstArray();
+
+ for( int i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == rServiceName )
+ return true;
+
+ return false;
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > SAL_CALL Graphic::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aRet( ::unographic::GraphicDescriptor::getSupportedServiceNames() );
+ uno::Sequence< ::rtl::OUString > aNew( getSupportedServiceNames_Static() );
+ sal_Int32 nOldCount = aRet.getLength();
+
+ aRet.realloc( nOldCount + aNew.getLength() );
+
+ for( sal_Int32 i = 0; i < aNew.getLength(); ++i )
+ aRet[ nOldCount++ ] = aNew[ i ];
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< uno::Type > SAL_CALL Graphic::getTypes()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< uno::Type > aRet( ::unographic::GraphicDescriptor::getTypes() );
+ sal_Int32 nOldCount = aRet.getLength();
+
+ aRet.realloc( nOldCount + 2 );
+ aRet[ nOldCount ] = ::getCppuType((const uno::Reference< graphic::XGraphic>*)0);
+ aRet[ nOldCount+1 ] = ::getCppuType((const uno::Reference< awt::XBitmap>*)0);
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< sal_Int8 > SAL_CALL Graphic::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ return getImplementationId_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+::sal_Int8 SAL_CALL Graphic::getType()
+ throw (uno::RuntimeException)
+{
+ ::sal_Int8 cRet = graphic::GraphicType::EMPTY;
+
+ if( mpGraphic && ( mpGraphic->GetType() != GRAPHIC_NONE ) )
+ cRet = ( ( mpGraphic->GetType() == GRAPHIC_BITMAP ) ? graphic::GraphicType::PIXEL : graphic::GraphicType::VECTOR );
+
+ return cRet;
+}
+
+//----------------------------------------------------------------------
+// XBitmap
+//----------------------------------------------------------------------
+
+awt::Size SAL_CALL Graphic::getSize( ) throw (uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ ::Size aVclSize;
+ if( mpGraphic && ( mpGraphic->GetType() != GRAPHIC_NONE ) )
+ aVclSize = mpGraphic->GetSizePixel();
+
+ return awt::Size( aVclSize.Width(), aVclSize.Height() );
+}
+
+//----------------------------------------------------------------------
+
+uno::Sequence< ::sal_Int8 > SAL_CALL Graphic::getDIB( ) throw (uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( mpGraphic && ( mpGraphic->GetType() != GRAPHIC_NONE ) )
+ {
+ SvMemoryStream aMem;
+ aMem << mpGraphic->GetBitmapEx().GetBitmap();
+ return ::com::sun::star::uno::Sequence<sal_Int8>( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+ }
+ else
+ {
+ return uno::Sequence<sal_Int8>();
+ }
+}
+
+//----------------------------------------------------------------------
+
+uno::Sequence< ::sal_Int8 > SAL_CALL Graphic::getMaskDIB( ) throw (uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( mpGraphic && ( mpGraphic->GetType() != GRAPHIC_NONE ) )
+ {
+ SvMemoryStream aMem;
+ aMem << mpGraphic->GetBitmapEx().GetMask();
+ return ::com::sun::star::uno::Sequence<sal_Int8>( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+ }
+ else
+ {
+ return uno::Sequence<sal_Int8>();
+ }
+}
+
+//----------------------------------------------------------------------
+const ::Graphic* Graphic::getImplementation( const uno::Reference< uno::XInterface >& rxIFace )
+ throw()
+{
+ uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY );
+ return( xTunnel.is() ? reinterpret_cast< ::Graphic* >( xTunnel->getSomething( getImplementationId_Static() ) ) : NULL );
+}
+
+//----------------------------------------------------------------------
+sal_Int64 SAL_CALL Graphic::getSomething( const uno::Sequence< sal_Int8 >& rId )
+ throw( uno::RuntimeException )
+{
+ return( ( rId.getLength() == 16 && 0 == rtl_compareMemory( getImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) ?
+ reinterpret_cast< sal_Int64 >( mpGraphic ) :
+ 0 );
+}
+
+}
diff --git a/svtools/source/graphic/graphic.hxx b/svtools/source/graphic/graphic.hxx
new file mode 100644
index 000000000000..1a6594a3e543
--- /dev/null
+++ b/svtools/source/graphic/graphic.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 _GOODIES_GRAPHIC_HXX
+#define _GOODIES_GRAPHIC_HXX
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+
+#include "descriptor.hxx"
+#include "transformer.hxx"
+
+using namespace com::sun::star;
+
+class Graphic;
+
+namespace unographic {
+
+// -------------------
+// - GraphicProvider -
+// -------------------
+
+class Graphic : public ::com::sun::star::graphic::XGraphic,
+ public ::com::sun::star::awt::XBitmap,
+ public ::com::sun::star::lang::XUnoTunnel,
+ public ::unographic::GraphicDescriptor,
+ public ::unographic::GraphicTransformer
+{
+public:
+
+ Graphic();
+ ~Graphic() throw();
+
+ using unographic::GraphicDescriptor::init;
+ void init( const ::Graphic& rGraphic ) throw();
+
+ static const ::Graphic* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw();
+ static ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId_Static( ) throw(::com::sun::star::uno::RuntimeException);
+ static ::rtl::OUString getImplementationName_Static() throw();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static() throw();
+
+protected:
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ 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
+ 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 );
+
+ // 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);
+
+ // XGraphic
+ virtual ::sal_Int8 SAL_CALL getType( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XBitmap
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getDIB( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getMaskDIB( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException);
+
+private:
+
+ ::Graphic* mpGraphic;
+};
+
+}
+
+#endif
diff --git a/svtools/source/graphic/graphicunofactory.cxx b/svtools/source/graphic/graphicunofactory.cxx
new file mode 100644
index 000000000000..f29b34b66743
--- /dev/null
+++ b/svtools/source/graphic/graphicunofactory.cxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <comphelper/servicedecl.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/graphic/XGraphicObject.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <svtools/grfmgr.hxx>
+
+using namespace com::sun::star;
+
+namespace unographic {
+
+typedef ::cppu::WeakImplHelper1< graphic::XGraphicObject > GObjectAccess_BASE;
+ // Simple uno wrapper around the GraphicObject class to allow basic
+ // access. ( and solves a horrible cyclic link problem between
+ // goodies/toolkit/extensions )
+class GObjectImpl : public GObjectAccess_BASE
+{
+ ::osl::Mutex m_aMutex;
+ std::auto_ptr< GraphicObject > mpGObject;
+public:
+ GObjectImpl( uno::Sequence< uno::Any > const & args, uno::Reference< uno::XComponentContext > const & xComponentContext ) throw (uno::RuntimeException);
+
+ // XGraphicObject
+ virtual uno::Reference< graphic::XGraphic > SAL_CALL getGraphic() throw (uno::RuntimeException);
+ virtual void SAL_CALL setGraphic( const uno::Reference< graphic::XGraphic >& _graphic ) throw (uno::RuntimeException);
+ ::rtl::OUString SAL_CALL getUniqueID() throw (uno::RuntimeException);
+};
+
+GObjectImpl::GObjectImpl( uno::Sequence< uno::Any > const & args, uno::Reference< uno::XComponentContext > const & /*xComponentContext*/ ) throw (uno::RuntimeException)
+{
+ if ( args.getLength() == 1 )
+ {
+ rtl::OUString sId;
+ if ( !( args[ 0 ] >>= sId ) || sId.getLength() == 0 )
+ throw lang::IllegalArgumentException();
+ ByteString bsId( sId.getStr(), RTL_TEXTENCODING_UTF8 );
+ mpGObject.reset( new GraphicObject( bsId ) );
+ }
+ else
+ mpGObject.reset( new GraphicObject() );
+}
+
+uno::Reference< graphic::XGraphic > SAL_CALL GObjectImpl::getGraphic() throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !mpGObject.get() )
+ throw uno::RuntimeException();
+ return mpGObject->GetGraphic().GetXGraphic();
+}
+
+void SAL_CALL GObjectImpl::setGraphic( const uno::Reference< graphic::XGraphic >& _graphic ) throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !mpGObject.get() )
+ throw uno::RuntimeException();
+ Graphic aGraphic( _graphic );
+ mpGObject->SetGraphic( aGraphic );
+}
+
+::rtl::OUString SAL_CALL GObjectImpl::getUniqueID() throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ rtl::OUString sId;
+ if ( mpGObject.get() )
+ sId = String( mpGObject->GetUniqueID().GetBuffer(), RTL_TEXTENCODING_ASCII_US );
+ return sId;
+}
+
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<GObjectImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl( serviceBI, "com.sun.star.graphic.GraphicObject", "com.sun.star.graphic.GraphicObject" );
+
+}
diff --git a/svtools/source/graphic/grfattr.cxx b/svtools/source/graphic/grfattr.cxx
new file mode 100644
index 000000000000..757be42a104c
--- /dev/null
+++ b/svtools/source/graphic/grfattr.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_svtools.hxx"
+
+#include <tools/vcompat.hxx>
+#include <svtools/grfmgr.hxx>
+
+// ---------------
+// - GraphicAttr -
+// ---------------
+
+GraphicAttr::GraphicAttr() :
+ mfGamma ( 1.0 ),
+ mnMirrFlags ( 0 ),
+ mnLeftCrop ( 0 ),
+ mnTopCrop ( 0 ),
+ mnRightCrop ( 0 ),
+ mnBottomCrop ( 0 ),
+ mnRotate10 ( 0 ),
+ mnContPercent ( 0 ),
+ mnLumPercent ( 0 ),
+ mnRPercent ( 0 ),
+ mnGPercent ( 0 ),
+ mnBPercent ( 0 ),
+ mbInvert ( FALSE ),
+ mcTransparency ( 0 ),
+ meDrawMode ( GRAPHICDRAWMODE_STANDARD )
+{
+}
+
+// ------------------------------------------------------------------------
+
+GraphicAttr::~GraphicAttr()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicAttr::operator==( const GraphicAttr& rAttr ) const
+{
+ return( ( mfGamma == rAttr.mfGamma ) &&
+ ( mnMirrFlags == rAttr.mnMirrFlags ) &&
+ ( mnLeftCrop == rAttr.mnLeftCrop ) &&
+ ( mnTopCrop == rAttr.mnTopCrop ) &&
+ ( mnRightCrop == rAttr.mnRightCrop ) &&
+ ( mnBottomCrop == rAttr.mnBottomCrop ) &&
+ ( mnRotate10 == rAttr.mnRotate10 ) &&
+ ( mnContPercent == rAttr.mnContPercent ) &&
+ ( mnLumPercent == rAttr.mnLumPercent ) &&
+ ( mnRPercent == rAttr.mnRPercent ) &&
+ ( mnGPercent == rAttr.mnGPercent ) &&
+ ( mnBPercent == rAttr.mnBPercent ) &&
+ ( mbInvert == rAttr.mbInvert ) &&
+ ( mcTransparency == rAttr.mcTransparency ) &&
+ ( meDrawMode == rAttr.meDrawMode ) );
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, GraphicAttr& rAttr )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ sal_uInt32 nTmp32;
+ UINT16 nTmp16;
+
+ rIStm >> nTmp32 >> nTmp32 >> rAttr.mfGamma >> rAttr.mnMirrFlags >> rAttr.mnRotate10;
+ rIStm >> rAttr.mnContPercent >> rAttr.mnLumPercent >> rAttr.mnRPercent >> rAttr.mnGPercent >> rAttr.mnBPercent;
+ rIStm >> rAttr.mbInvert >> rAttr.mcTransparency >> nTmp16;
+ rAttr.meDrawMode = (GraphicDrawMode) nTmp16;
+
+ if( aCompat.GetVersion() >= 2 )
+ {
+ rIStm >> rAttr.mnLeftCrop >> rAttr.mnTopCrop >> rAttr.mnRightCrop >> rAttr.mnBottomCrop;
+ }
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const GraphicAttr& rAttr )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 2 );
+ const sal_uInt32 nTmp32 = 0;
+
+ rOStm << nTmp32 << nTmp32 << rAttr.mfGamma << rAttr.mnMirrFlags << rAttr.mnRotate10;
+ rOStm << rAttr.mnContPercent << rAttr.mnLumPercent << rAttr.mnRPercent << rAttr.mnGPercent << rAttr.mnBPercent;
+ rOStm << rAttr.mbInvert << rAttr.mcTransparency << (UINT16) rAttr.meDrawMode;
+ rOStm << rAttr.mnLeftCrop << rAttr.mnTopCrop << rAttr.mnRightCrop << rAttr.mnBottomCrop;
+
+ return rOStm;
+}
diff --git a/svtools/source/graphic/grfcache.cxx b/svtools/source/graphic/grfcache.cxx
new file mode 100644
index 000000000000..41240c95d113
--- /dev/null
+++ b/svtools/source/graphic/grfcache.cxx
@@ -0,0 +1,1062 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <vos/timer.hxx>
+#include <tools/debug.hxx>
+#include <vcl/outdev.hxx>
+#include <tools/poly.hxx>
+#include "grfcache.hxx"
+
+#include <memory>
+
+// -----------
+// - Defines -
+// -----------
+
+#define RELEASE_TIMEOUT 10000
+#define MAX_BMP_EXTENT 4096
+
+// -----------
+// - statics -
+// -----------
+
+static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+// -------------
+// - GraphicID -
+// -------------
+
+class GraphicID
+{
+private:
+
+ sal_uInt32 mnID1;
+ sal_uInt32 mnID2;
+ sal_uInt32 mnID3;
+ sal_uInt32 mnID4;
+
+ GraphicID();
+
+public:
+
+
+ GraphicID( const GraphicObject& rObj );
+ ~GraphicID() {}
+
+ BOOL operator==( const GraphicID& rID ) const
+ {
+ return( rID.mnID1 == mnID1 && rID.mnID2 == mnID2 &&
+ rID.mnID3 == mnID3 && rID.mnID4 == mnID4 );
+ }
+
+ ByteString GetIDString() const;
+ BOOL IsEmpty() const { return( 0 == mnID4 ); }
+};
+
+// -----------------------------------------------------------------------------
+
+GraphicID::GraphicID( const GraphicObject& rObj )
+{
+ const Graphic& rGraphic = rObj.GetGraphic();
+
+ mnID1 = ( (ULONG) rGraphic.GetType() ) << 28;
+
+ switch( rGraphic.GetType() )
+ {
+ case( GRAPHIC_BITMAP ):
+ {
+ if( rGraphic.IsAnimated() )
+ {
+ const Animation aAnimation( rGraphic.GetAnimation() );
+
+ mnID1 |= ( aAnimation.Count() & 0x0fffffff );
+ mnID2 = aAnimation.GetDisplaySizePixel().Width();
+ mnID3 = aAnimation.GetDisplaySizePixel().Height();
+ mnID4 = rGraphic.GetChecksum();
+ }
+ else
+ {
+ const BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ mnID1 |= ( ( ( (ULONG) aBmpEx.GetTransparentType() << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
+ mnID2 = aBmpEx.GetSizePixel().Width();
+ mnID3 = aBmpEx.GetSizePixel().Height();
+ mnID4 = rGraphic.GetChecksum();
+ }
+ }
+ break;
+
+ case( GRAPHIC_GDIMETAFILE ):
+ {
+ const GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
+
+ mnID1 |= ( aMtf.GetActionCount() & 0x0fffffff );
+ mnID2 = aMtf.GetPrefSize().Width();
+ mnID3 = aMtf.GetPrefSize().Height();
+ mnID4 = rGraphic.GetChecksum();
+ }
+ break;
+
+ default:
+ mnID2 = mnID3 = mnID4 = 0;
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicID::GetIDString() const
+{
+ ByteString aHexStr;
+ sal_Char* pStr = aHexStr.AllocBuffer( 32 );
+ sal_Int32 nShift;
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID1 >> (sal_uInt32) nShift ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID2 >> (sal_uInt32) nShift ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID3 >> (sal_uInt32) nShift ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID4 >> (sal_uInt32) nShift ) & 0xf ];
+
+ return aHexStr;
+}
+
+// ---------------------
+// - GraphicCacheEntry -
+// ---------------------
+
+class GraphicCacheEntry
+{
+private:
+
+ List maGraphicObjectList;
+ GraphicID maID;
+ GfxLink maGfxLink;
+ BitmapEx* mpBmpEx;
+ GDIMetaFile* mpMtf;
+ Animation* mpAnimation;
+ BOOL mbSwappedAll;
+
+ BOOL ImplInit( const GraphicObject& rObj );
+ BOOL ImplMatches( const GraphicObject& rObj ) const { return( GraphicID( rObj ) == maID ); }
+ void ImplFillSubstitute( Graphic& rSubstitute );
+
+public:
+
+ GraphicCacheEntry( const GraphicObject& rObj );
+ ~GraphicCacheEntry();
+
+ const GraphicID& GetID() const { return maID; }
+
+ void AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute );
+ BOOL ReleaseGraphicObjectReference( const GraphicObject& rObj );
+ ULONG GetGraphicObjectReferenceCount() { return maGraphicObjectList.Count(); }
+ BOOL HasGraphicObjectReference( const GraphicObject& rObj );
+
+ void TryToSwapIn();
+ void GraphicObjectWasSwappedOut( const GraphicObject& rObj );
+ BOOL FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute );
+ void GraphicObjectWasSwappedIn( const GraphicObject& rObj );
+};
+
+// -----------------------------------------------------------------------------
+
+GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) :
+ maID ( rObj ),
+ mpBmpEx ( NULL ),
+ mpMtf ( NULL ),
+ mpAnimation ( NULL ),
+ mbSwappedAll ( !ImplInit( rObj ) )
+{
+ maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicCacheEntry::~GraphicCacheEntry()
+{
+ DBG_ASSERT( !maGraphicObjectList.Count(), "GraphicCacheEntry::~GraphicCacheEntry(): Not all GraphicObjects are removed from this entry" );
+
+ delete mpBmpEx;
+ delete mpMtf;
+ delete mpAnimation;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::ImplInit( const GraphicObject& rObj )
+{
+ BOOL bRet;
+
+ if( !rObj.IsSwappedOut() )
+ {
+ const Graphic& rGraphic = rObj.GetGraphic();
+
+ if( mpBmpEx )
+ delete mpBmpEx, mpBmpEx = NULL;
+
+ if( mpMtf )
+ delete mpMtf, mpMtf = NULL;
+
+ if( mpAnimation )
+ delete mpAnimation, mpAnimation = NULL;
+
+ switch( rGraphic.GetType() )
+ {
+ case( GRAPHIC_BITMAP ):
+ {
+ if( rGraphic.IsAnimated() )
+ mpAnimation = new Animation( rGraphic.GetAnimation() );
+ else
+ mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() );
+ }
+ break;
+
+ case( GRAPHIC_GDIMETAFILE ):
+ {
+ mpMtf = new GDIMetaFile( rGraphic.GetGDIMetaFile() );
+ }
+ break;
+
+ default:
+ DBG_ASSERT( GetID().IsEmpty(), "GraphicCacheEntry::ImplInit: Could not initialize graphic! (=>KA)" );
+ break;
+ }
+
+ if( rGraphic.IsLink() )
+ maGfxLink = ( (Graphic&) rGraphic ).GetLink();
+ else
+ maGfxLink = GfxLink();
+
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
+{
+ // create substitute for graphic;
+ const Size aPrefSize( rSubstitute.GetPrefSize() );
+ const MapMode aPrefMapMode( rSubstitute.GetPrefMapMode() );
+ const Link aAnimationNotifyHdl( rSubstitute.GetAnimationNotifyHdl() );
+ const String aDocFileName( rSubstitute.GetDocFileName() );
+ const ULONG nDocFilePos = rSubstitute.GetDocFilePos();
+ const GraphicType eOldType = rSubstitute.GetType();
+ const BOOL bDefaultType = ( rSubstitute.GetType() == GRAPHIC_DEFAULT );
+
+ if( rSubstitute.IsLink() && ( GFX_LINK_TYPE_NONE == maGfxLink.GetType() ) )
+ maGfxLink = rSubstitute.GetLink();
+
+ if( mpBmpEx )
+ rSubstitute = *mpBmpEx;
+ else if( mpAnimation )
+ rSubstitute = *mpAnimation;
+ else if( mpMtf )
+ rSubstitute = *mpMtf;
+ else
+ rSubstitute.Clear();
+
+ if( eOldType != GRAPHIC_NONE )
+ {
+ rSubstitute.SetPrefSize( aPrefSize );
+ rSubstitute.SetPrefMapMode( aPrefMapMode );
+ rSubstitute.SetAnimationNotifyHdl( aAnimationNotifyHdl );
+ rSubstitute.SetDocFileName( aDocFileName, nDocFilePos );
+ }
+
+ if( GFX_LINK_TYPE_NONE != maGfxLink.GetType() )
+ rSubstitute.SetLink( maGfxLink );
+
+ if( bDefaultType )
+ rSubstitute.SetDefaultType();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ if( mbSwappedAll )
+ mbSwappedAll = !ImplInit( rObj );
+
+ ImplFillSubstitute( rSubstitute );
+ maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::ReleaseGraphicObjectReference( const GraphicObject& rObj )
+{
+ BOOL bRet = FALSE;
+
+ for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() )
+ {
+ if( &rObj == (GraphicObject*) pObj )
+ {
+ maGraphicObjectList.Remove( pObj );
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::HasGraphicObjectReference( const GraphicObject& rObj )
+{
+ BOOL bRet = FALSE;
+
+ for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() )
+ if( &rObj == (GraphicObject*) pObj )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::TryToSwapIn()
+{
+ if( mbSwappedAll && maGraphicObjectList.Count() )
+ ( (GraphicObject*) maGraphicObjectList.First() )->FireSwapInRequest();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::GraphicObjectWasSwappedOut( const GraphicObject& /*rObj*/ )
+{
+ mbSwappedAll = TRUE;
+
+ for( void* pObj = maGraphicObjectList.First(); mbSwappedAll && pObj; pObj = maGraphicObjectList.Next() )
+ if( !( (GraphicObject*) pObj )->IsSwappedOut() )
+ mbSwappedAll = FALSE;
+
+ if( mbSwappedAll )
+ {
+ delete mpBmpEx, mpBmpEx = NULL;
+ delete mpMtf, mpMtf = NULL;
+ delete mpAnimation, mpAnimation = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ BOOL bRet;
+
+ if( !mbSwappedAll && rObj.IsSwappedOut() )
+ {
+ ImplFillSubstitute( rSubstitute );
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
+{
+ if( mbSwappedAll )
+ mbSwappedAll = !ImplInit( rObj );
+}
+
+// ----------------------------
+// - GraphicDisplayCacheEntry -
+// ----------------------------
+
+class GraphicDisplayCacheEntry
+{
+private:
+
+ ::vos::TTimeValue maReleaseTime;
+ const GraphicCacheEntry* mpRefCacheEntry;
+ GDIMetaFile* mpMtf;
+ BitmapEx* mpBmpEx;
+ GraphicAttr maAttr;
+ Size maOutSizePix;
+ ULONG mnCacheSize;
+ ULONG mnOutDevDrawMode;
+ USHORT mnOutDevBitCount;
+
+public:
+
+ static ULONG GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr );
+
+public:
+
+ GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
+ OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const BitmapEx& rBmpEx ) :
+ mpRefCacheEntry( pRefCacheEntry ),
+ mpMtf( NULL ), mpBmpEx( new BitmapEx( rBmpEx ) ),
+ maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
+ mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
+ mnOutDevDrawMode( pOut->GetDrawMode() ),
+ mnOutDevBitCount( pOut->GetBitCount() )
+ {
+ }
+
+ GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
+ OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const GDIMetaFile& rMtf ) :
+ mpRefCacheEntry( pRefCacheEntry ),
+ mpMtf( new GDIMetaFile( rMtf ) ), mpBmpEx( NULL ),
+ maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
+ mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
+ mnOutDevDrawMode( pOut->GetDrawMode() ),
+ mnOutDevBitCount( pOut->GetBitCount() )
+ {
+ }
+
+
+ ~GraphicDisplayCacheEntry();
+
+ const GraphicAttr& GetAttr() const { return maAttr; }
+ const Size& GetOutputSizePixel() const { return maOutSizePix; }
+ ULONG GetCacheSize() const { return mnCacheSize; }
+ const GraphicCacheEntry* GetReferencedCacheEntry() const { return mpRefCacheEntry; }
+ ULONG GetOutDevDrawMode() const { return mnOutDevDrawMode; }
+ USHORT GetOutDevBitCount() const { return mnOutDevBitCount; }
+
+ void SetReleaseTime( const ::vos::TTimeValue& rReleaseTime ) { maReleaseTime = rReleaseTime; }
+ const ::vos::TTimeValue& GetReleaseTime() const { return maReleaseTime; }
+
+ BOOL Matches( OutputDevice* pOut, const Point& /*rPtPixel*/, const Size& rSzPixel,
+ const GraphicCacheEntry* pCacheEntry, const GraphicAttr& rAttr ) const
+ {
+ // #i46805# Additional match
+ // criteria: outdev draw mode and
+ // bit count. One cannot reuse
+ // this cache object, if it's
+ // e.g. generated for
+ // DRAWMODE_GRAYBITMAP.
+ return( ( pCacheEntry == mpRefCacheEntry ) &&
+ ( maAttr == rAttr ) &&
+ ( ( maOutSizePix == rSzPixel ) || ( !maOutSizePix.Width() && !maOutSizePix.Height() ) ) &&
+ ( pOut->GetBitCount() == mnOutDevBitCount ) &&
+ ( pOut->GetDrawMode() == mnOutDevDrawMode ) );
+ }
+
+ void Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const;
+};
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& /*rPt*/, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr )
+{
+ const Graphic& rGraphic = rObj.GetGraphic();
+ const GraphicType eType = rGraphic.GetType();
+ ULONG nNeededSize;
+
+ if( GRAPHIC_BITMAP == eType )
+ {
+ const Size aOutSizePix( pOut->LogicToPixel( rSz ) );
+ const long nBitCount = pOut->GetBitCount();
+
+ if( ( aOutSizePix.Width() > MAX_BMP_EXTENT ) ||
+ ( aOutSizePix.Height() > MAX_BMP_EXTENT ) )
+ {
+ nNeededSize = ULONG_MAX;
+ }
+ else if( nBitCount )
+ {
+ nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;
+
+ if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) )
+ nNeededSize += nNeededSize / nBitCount;
+ }
+ else
+ {
+ DBG_ERROR( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
+ nNeededSize = 256000;
+ }
+ }
+ else if( GRAPHIC_GDIMETAFILE == eType )
+ nNeededSize = rGraphic.GetSizeBytes();
+ else
+ nNeededSize = 0;
+
+ return nNeededSize;
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicDisplayCacheEntry::~GraphicDisplayCacheEntry()
+{
+ if( mpMtf )
+ delete mpMtf;
+
+ if( mpBmpEx )
+ delete mpBmpEx;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const
+{
+ if( mpMtf )
+ GraphicManager::ImplDraw( pOut, rPt, rSz, *mpMtf, maAttr );
+ else if( mpBmpEx )
+ {
+ if( maAttr.IsRotated() )
+ {
+ Polygon aPoly( Rectangle( rPt, rSz ) );
+
+ aPoly.Rotate( rPt, maAttr.GetRotation() % 3600 );
+ const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
+ pOut->DrawBitmapEx( aRotBoundRect.TopLeft(), aRotBoundRect.GetSize(), *mpBmpEx );
+ }
+ else
+ pOut->DrawBitmapEx( rPt, rSz, *mpBmpEx );
+ }
+}
+
+// -----------------------
+// - GraphicCache -
+// -----------------------
+
+GraphicCache::GraphicCache( GraphicManager& rMgr, ULONG nDisplayCacheSize, ULONG nMaxObjDisplayCacheSize ) :
+ mrMgr ( rMgr ),
+ mnReleaseTimeoutSeconds ( 0UL ),
+ mnMaxDisplaySize ( nDisplayCacheSize ),
+ mnMaxObjDisplaySize ( nMaxObjDisplayCacheSize ),
+ mnUsedDisplaySize ( 0UL )
+{
+ maReleaseTimer.SetTimeoutHdl( LINK( this, GraphicCache, ReleaseTimeoutHdl ) );
+ maReleaseTimer.SetTimeout( RELEASE_TIMEOUT );
+ maReleaseTimer.Start();
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicCache::~GraphicCache()
+{
+ DBG_ASSERT( !maGraphicCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in cache" );
+ DBG_ASSERT( !maDisplayCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in display cache" );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::AddGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute,
+ const ByteString* pID, const GraphicObject* pCopyObj )
+{
+ BOOL bInserted = FALSE;
+
+ if( !rObj.IsSwappedOut() &&
+ ( pID || ( pCopyObj && ( pCopyObj->GetType() != GRAPHIC_NONE ) ) || ( rObj.GetType() != GRAPHIC_NONE ) ) )
+ {
+ if( pCopyObj )
+ {
+ GraphicCacheEntry* pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() );
+
+ while( !bInserted && pEntry )
+ {
+ if( pEntry->HasGraphicObjectReference( *pCopyObj ) )
+ {
+ pEntry->AddGraphicObjectReference( rObj, rSubstitute );
+ bInserted = TRUE;
+ }
+ else
+ {
+ pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() );
+ }
+ }
+ }
+
+ if( !bInserted )
+ {
+ GraphicCacheEntry* pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() );
+ ::std::auto_ptr< GraphicID > apID;
+
+ if( !pID )
+ {
+ apID.reset( new GraphicID( rObj ) );
+ }
+
+ while( !bInserted && pEntry )
+ {
+ const GraphicID& rEntryID = pEntry->GetID();
+
+ if( pID )
+ {
+ if( rEntryID.GetIDString() == *pID )
+ {
+ pEntry->TryToSwapIn();
+
+ // since pEntry->TryToSwapIn can modify our current list, we have to
+ // iterate from beginning to add a reference to the appropriate
+ // CacheEntry object; after this, quickly jump out of the outer iteration
+ for( pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() );
+ !bInserted && pEntry;
+ pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() ) )
+ {
+ const GraphicID& rID = pEntry->GetID();
+
+ if( rID.GetIDString() == *pID )
+ {
+ pEntry->AddGraphicObjectReference( rObj, rSubstitute );
+ bInserted = TRUE;
+ }
+ }
+
+ if( !bInserted )
+ {
+ maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND );
+ bInserted = TRUE;
+ }
+ }
+ }
+ else
+ {
+ if( rEntryID == *apID )
+ {
+ pEntry->AddGraphicObjectReference( rObj, rSubstitute );
+ bInserted = TRUE;
+ }
+ }
+
+ if( !bInserted )
+ pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() );
+ }
+ }
+ }
+
+ if( !bInserted )
+ maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::ReleaseGraphicObject( const GraphicObject& rObj )
+{
+ // Release cached object
+ GraphicCacheEntry* pEntry = (GraphicCacheEntry*) maGraphicCache.First();
+ BOOL bRemoved = FALSE;
+
+ while( !bRemoved && pEntry )
+ {
+ bRemoved = pEntry->ReleaseGraphicObjectReference( rObj );
+
+ if( bRemoved )
+ {
+ if( 0 == pEntry->GetGraphicObjectReferenceCount() )
+ {
+ // if graphic cache entry has no more references,
+ // the corresponding display cache object can be removed
+ GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+
+ while( pDisplayEntry )
+ {
+ if( pDisplayEntry->GetReferencedCacheEntry() == pEntry )
+ {
+ mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
+ maDisplayCache.Remove( pDisplayEntry );
+ delete pDisplayEntry;
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
+ }
+ else
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+
+ // delete graphic cache entry
+ maGraphicCache.Remove( (void*) pEntry );
+ delete pEntry;
+ }
+ }
+ else
+ pEntry = (GraphicCacheEntry*) maGraphicCache.Next();
+ }
+
+ DBG_ASSERT( bRemoved, "GraphicCache::ReleaseGraphicObject(...): GraphicObject not found in cache" );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::GraphicObjectWasSwappedOut( const GraphicObject& rObj )
+{
+ // notify cache that rObj is swapped out (and can thus be pruned
+ // from the cache)
+ GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
+
+ if( pEntry )
+ pEntry->GraphicObjectWasSwappedOut( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
+
+ if( !pEntry )
+ return FALSE;
+
+ return pEntry->FillSwappedGraphicObject( rObj, rSubstitute );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
+{
+ GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
+
+ if( pEntry )
+ {
+ if( pEntry->GetID().IsEmpty() )
+ {
+ ReleaseGraphicObject( rObj );
+ AddGraphicObject( rObj, (Graphic&) rObj.GetGraphic(), NULL, NULL );
+ }
+ else
+ pEntry->GraphicObjectWasSwappedIn( rObj );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::SetMaxDisplayCacheSize( ULONG nNewCacheSize )
+{
+ mnMaxDisplaySize = nNewCacheSize;
+
+ if( GetMaxDisplayCacheSize() < GetUsedDisplayCacheSize() )
+ ImplFreeDisplayCacheSpace( GetUsedDisplayCacheSize() - GetMaxDisplayCacheSize() );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::SetMaxObjDisplayCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached )
+{
+ const BOOL bDestroy = ( bDestroyGreaterCached && ( nNewMaxObjSize < mnMaxObjDisplaySize ) );
+
+ mnMaxObjDisplaySize = Min( nNewMaxObjSize, mnMaxDisplaySize );
+
+ if( bDestroy )
+ {
+ GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+
+ while( pCacheObj )
+ {
+ if( pCacheObj->GetCacheSize() > mnMaxObjDisplaySize )
+ {
+ mnUsedDisplaySize -= pCacheObj->GetCacheSize();
+ maDisplayCache.Remove( pCacheObj );
+ delete pCacheObj;
+ pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
+ }
+ else
+ pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::SetCacheTimeout( ULONG nTimeoutSeconds )
+{
+ if( mnReleaseTimeoutSeconds != nTimeoutSeconds )
+ {
+ GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+ ::vos::TTimeValue aReleaseTime;
+
+ if( ( mnReleaseTimeoutSeconds = nTimeoutSeconds ) != 0 )
+ {
+ osl_getSystemTime( &aReleaseTime );
+ aReleaseTime.addTime( ::vos::TTimeValue( nTimeoutSeconds, 0 ) );
+ }
+
+ while( pDisplayEntry )
+ {
+ pDisplayEntry->SetReleaseTime( aReleaseTime );
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::ClearDisplayCache()
+{
+ for( void* pObj = maDisplayCache.First(); pObj; pObj = maDisplayCache.Next() )
+ delete (GraphicDisplayCacheEntry*) pObj;
+
+ maDisplayCache.Clear();
+ mnUsedDisplaySize = 0UL;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const
+{
+ return( GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) <=
+ GetMaxObjDisplayCacheSize() );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const
+{
+ const Point aPtPixel( pOut->LogicToPixel( rPt ) );
+ const Size aSzPixel( pOut->LogicToPixel( rSz ) );
+ const GraphicCacheEntry* pCacheEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
+ //GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) ( (GraphicCache*) this )->maDisplayCache.First(); // -Wall removed ....
+ BOOL bFound = FALSE;
+
+ if( pCacheEntry )
+ {
+ for( long i = 0, nCount = maDisplayCache.Count(); !bFound && ( i < nCount ); i++ )
+ if( ( (GraphicDisplayCacheEntry*) maDisplayCache.GetObject( i ) )->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
+ bFound = TRUE;
+ }
+
+ return bFound;
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicCache::GetUniqueID( const GraphicObject& rObj ) const
+{
+ ByteString aRet;
+ GraphicCacheEntry* pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
+
+ // ensure that the entry is correctly initialized (it has to be read at least once)
+ if( pEntry && pEntry->GetID().IsEmpty() )
+ pEntry->TryToSwapIn();
+
+ // do another call to ImplGetCacheEntry in case of modified entry list
+ pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
+
+ if( pEntry )
+ aRet = pEntry->GetID().GetIDString();
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const BitmapEx& rBmpEx )
+{
+ const ULONG nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
+ BOOL bRet = FALSE;
+
+ if( nNeededSize <= GetMaxObjDisplayCacheSize() )
+ {
+ if( nNeededSize > GetFreeDisplayCacheSize() )
+ ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
+
+ GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
+ pOut, rPt, rSz, rObj, rAttr, rBmpEx );
+
+ if( GetCacheTimeout() )
+ {
+ ::vos::TTimeValue aReleaseTime;
+
+ osl_getSystemTime( &aReleaseTime );
+ aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) );
+ pNewEntry->SetReleaseTime( aReleaseTime );
+ }
+
+ maDisplayCache.Insert( pNewEntry, LIST_APPEND );
+ mnUsedDisplaySize += pNewEntry->GetCacheSize();
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const GDIMetaFile& rMtf )
+{
+ const ULONG nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
+ BOOL bRet = FALSE;
+
+ if( nNeededSize <= GetMaxObjDisplayCacheSize() )
+ {
+ if( nNeededSize > GetFreeDisplayCacheSize() )
+ ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
+
+ GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
+ pOut, rPt, rSz, rObj, rAttr, rMtf );
+
+ if( GetCacheTimeout() )
+ {
+ ::vos::TTimeValue aReleaseTime;
+
+ osl_getSystemTime( &aReleaseTime );
+ aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) );
+ pNewEntry->SetReleaseTime( aReleaseTime );
+ }
+
+ maDisplayCache.Insert( pNewEntry, LIST_APPEND );
+ mnUsedDisplaySize += pNewEntry->GetCacheSize();
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr )
+{
+ const Point aPtPixel( pOut->LogicToPixel( rPt ) );
+ const Size aSzPixel( pOut->LogicToPixel( rSz ) );
+ const GraphicCacheEntry* pCacheEntry = ImplGetCacheEntry( rObj );
+ GraphicDisplayCacheEntry* pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+ BOOL bRet = FALSE;
+
+ while( !bRet && pDisplayCacheEntry )
+ {
+ if( pDisplayCacheEntry->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
+ {
+ ::vos::TTimeValue aReleaseTime;
+
+ // put found object at last used position
+ maDisplayCache.Insert( maDisplayCache.Remove( pDisplayCacheEntry ), LIST_APPEND );
+
+ if( GetCacheTimeout() )
+ {
+ osl_getSystemTime( &aReleaseTime );
+ aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) );
+ }
+
+ pDisplayCacheEntry->SetReleaseTime( aReleaseTime );
+ bRet = TRUE;
+ }
+ else
+ pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+
+ if( bRet )
+ pDisplayCacheEntry->Draw( pOut, rPt, rSz );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::ImplFreeDisplayCacheSpace( ULONG nSizeToFree )
+{
+ ULONG nFreedSize = 0UL;
+
+ if( nSizeToFree )
+ {
+ void* pObj = maDisplayCache.First();
+
+ if( nSizeToFree > mnUsedDisplaySize )
+ nSizeToFree = mnUsedDisplaySize;
+
+ while( pObj )
+ {
+ GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) pObj;
+
+ nFreedSize += pCacheObj->GetCacheSize();
+ mnUsedDisplaySize -= pCacheObj->GetCacheSize();
+ maDisplayCache.Remove( pObj );
+ delete pCacheObj;
+
+ if( nFreedSize >= nSizeToFree )
+ break;
+ else
+ pObj = maDisplayCache.GetCurObject();
+ }
+ }
+
+ return( nFreedSize >= nSizeToFree );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicCacheEntry* GraphicCache::ImplGetCacheEntry( const GraphicObject& rObj )
+{
+ GraphicCacheEntry* pRet = NULL;
+
+ for( void* pObj = maGraphicCache.First(); !pRet && pObj; pObj = maGraphicCache.Next() )
+ if( ( (GraphicCacheEntry*) pObj )->HasGraphicObjectReference( rObj ) )
+ pRet = (GraphicCacheEntry*) pObj;
+
+ return pRet;
+}
+
+// -----------------------------------------------------------------------------
+
+IMPL_LINK( GraphicCache, ReleaseTimeoutHdl, Timer*, pTimer )
+{
+ pTimer->Stop();
+
+ ::vos::TTimeValue aCurTime;
+ GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+
+ osl_getSystemTime( &aCurTime );
+
+ while( pDisplayEntry )
+ {
+ const ::vos::TTimeValue& rReleaseTime = pDisplayEntry->GetReleaseTime();
+
+ if( !rReleaseTime.isEmpty() && ( rReleaseTime < aCurTime ) )
+ {
+ mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
+ maDisplayCache.Remove( pDisplayEntry );
+ delete pDisplayEntry;
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
+ }
+ else
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+
+ pTimer->Start();
+
+ return 0;
+}
diff --git a/svtools/source/graphic/grfcache.hxx b/svtools/source/graphic/grfcache.hxx
new file mode 100644
index 000000000000..55309a00827d
--- /dev/null
+++ b/svtools/source/graphic/grfcache.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 _GRFCACHE_HXX
+#define _GRFCACHE_HXX
+
+#include <tools/list.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/timer.hxx>
+#include <svtools/grfmgr.hxx>
+
+// -----------------------
+// - GraphicManagerCache -
+// -----------------------
+
+class GraphicCacheEntry;
+
+class GraphicCache
+{
+private:
+
+ GraphicManager& mrMgr;
+ Timer maReleaseTimer;
+ List maGraphicCache;
+ List maDisplayCache;
+ ULONG mnReleaseTimeoutSeconds;
+ ULONG mnMaxDisplaySize;
+ ULONG mnMaxObjDisplaySize;
+ ULONG mnUsedDisplaySize;
+
+ BOOL ImplFreeDisplayCacheSpace( ULONG nSizeToFree );
+ GraphicCacheEntry* ImplGetCacheEntry( const GraphicObject& rObj );
+
+
+ DECL_LINK( ReleaseTimeoutHdl, Timer* pTimer );
+
+public:
+
+ GraphicCache( GraphicManager& rMgr,
+ ULONG nDisplayCacheSize = 10000000UL,
+ ULONG nMaxObjDisplayCacheSize = 2400000UL );
+ ~GraphicCache();
+
+public:
+
+ void AddGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute,
+ const ByteString* pID, const GraphicObject* pCopyObj );
+ void ReleaseGraphicObject( const GraphicObject& rObj );
+
+ void GraphicObjectWasSwappedOut( const GraphicObject& rObj );
+ BOOL FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute );
+ void GraphicObjectWasSwappedIn( const GraphicObject& rObj );
+
+ ByteString GetUniqueID( const GraphicObject& rObj ) const;
+
+public:
+
+ void SetMaxDisplayCacheSize( ULONG nNewCacheSize );
+ ULONG GetMaxDisplayCacheSize() const { return mnMaxDisplaySize; };
+
+ void SetMaxObjDisplayCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached = FALSE );
+ ULONG GetMaxObjDisplayCacheSize() const { return mnMaxObjDisplaySize; }
+
+ ULONG GetUsedDisplayCacheSize() const { return mnUsedDisplaySize; }
+ ULONG GetFreeDisplayCacheSize() const { return( mnMaxDisplaySize - mnUsedDisplaySize ); }
+
+ void SetCacheTimeout( ULONG nTimeoutSeconds );
+ ULONG GetCacheTimeout() const { return mnReleaseTimeoutSeconds; }
+
+ void ClearDisplayCache();
+ BOOL IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const;
+ BOOL IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const;
+ BOOL CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const BitmapEx& rBmpEx );
+ BOOL CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const GDIMetaFile& rMtf );
+ BOOL DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr );
+};
+
+#endif // _GRFCACHE_HXX
diff --git a/svtools/source/graphic/grfmgr.cxx b/svtools/source/graphic/grfmgr.cxx
new file mode 100644
index 000000000000..221354cc6665
--- /dev/null
+++ b/svtools/source/graphic/grfmgr.cxx
@@ -0,0 +1,1382 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+
+#include <algorithm>
+
+#include <tools/vcompat.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/salbtype.hxx>
+#include <unotools/cacheoptions.hxx>
+#include <svtools/grfmgr.hxx>
+
+// --> OD 2010-01-04 #i105243#
+#include <vcl/pdfextoutdevdata.hxx>
+// <--
+
+// -----------
+// - Defines -
+// -----------
+
+#define WATERMARK_LUM_OFFSET 50
+#define WATERMARK_CON_OFFSET -70
+
+// -----------
+// - statics -
+// -----------
+
+GraphicManager* GraphicObject::mpGlobalMgr = NULL;
+
+// ---------------------
+// - GrfDirectCacheObj -
+// ---------------------
+
+struct GrfSimpleCacheObj
+{
+ Graphic maGraphic;
+ GraphicAttr maAttr;
+
+ GrfSimpleCacheObj( const Graphic& rGraphic, const GraphicAttr& rAttr ) :
+ maGraphic( rGraphic ), maAttr( rAttr ) {}
+};
+
+// -----------------
+// - GraphicObject -
+// -----------------
+
+TYPEINIT1_AUTOFACTORY( GraphicObject, SvDataCopyStream );
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const GraphicManager* pMgr ) :
+ mpLink ( NULL ),
+ mpUserData ( NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr ) :
+ maGraphic ( rGraphic ),
+ mpLink ( NULL ),
+ mpUserData ( NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const Graphic& rGraphic, const String& rLink, const GraphicManager* pMgr ) :
+ maGraphic ( rGraphic ),
+ mpLink ( rLink.Len() ? ( new String( rLink ) ) : NULL ),
+ mpUserData ( NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const GraphicObject& rGraphicObj, const GraphicManager* pMgr ) :
+ SvDataCopyStream(),
+ maGraphic ( rGraphicObj.GetGraphic() ),
+ maAttr ( rGraphicObj.maAttr ),
+ mpLink ( rGraphicObj.mpLink ? ( new String( *rGraphicObj.mpLink ) ) : NULL ),
+ mpUserData ( rGraphicObj.mpUserData ? ( new String( *rGraphicObj.mpUserData ) ) : NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr, NULL, &rGraphicObj );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const ByteString& rUniqueID, const GraphicManager* pMgr ) :
+ mpLink ( NULL ),
+ mpUserData ( NULL )
+{
+ ImplConstruct();
+
+ // assign default properties
+ ImplAssignGraphicData();
+
+ ImplSetGraphicManager( pMgr, &rUniqueID );
+
+ // update properties
+ ImplAssignGraphicData();
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::~GraphicObject()
+{
+ if( mpMgr )
+ {
+ mpMgr->ImplUnregisterObj( *this );
+
+ if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
+ delete mpGlobalMgr, mpGlobalMgr = NULL;
+ }
+
+ delete mpSwapOutTimer;
+ delete mpSwapStreamHdl;
+ delete mpLink;
+ delete mpUserData;
+ delete mpSimpleCache;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplConstruct()
+{
+ mpMgr = NULL;
+ mpSwapStreamHdl = NULL;
+ mpSwapOutTimer = NULL;
+ mpSimpleCache = NULL;
+ mnAnimationLoopCount = 0;
+ mbAutoSwapped = FALSE;
+ mbIsInSwapIn = FALSE;
+ mbIsInSwapOut = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplAssignGraphicData()
+{
+ maPrefSize = maGraphic.GetPrefSize();
+ maPrefMapMode = maGraphic.GetPrefMapMode();
+ mnSizeBytes = maGraphic.GetSizeBytes();
+ meType = maGraphic.GetType();
+ mbTransparent = maGraphic.IsTransparent();
+ mbAlpha = maGraphic.IsAlpha();
+ mbAnimated = maGraphic.IsAnimated();
+ mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
+
+ if( maGraphic.GetType() == GRAPHIC_GDIMETAFILE )
+ {
+ const GDIMetaFile& rMtf = GetGraphic().GetGDIMetaFile();
+ mbEPS = ( rMtf.GetActionCount() >= 1 ) && ( META_EPS_ACTION == rMtf.GetAction( 0 )->GetType() );
+ }
+ else
+ mbEPS = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplSetGraphicManager( const GraphicManager* pMgr, const ByteString* pID, const GraphicObject* pCopyObj )
+{
+ if( !mpMgr || ( pMgr != mpMgr ) )
+ {
+ if( !pMgr && mpMgr && ( mpMgr == mpGlobalMgr ) )
+ return;
+ else
+ {
+ if( mpMgr )
+ {
+ mpMgr->ImplUnregisterObj( *this );
+
+ if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
+ delete mpGlobalMgr, mpGlobalMgr = NULL;
+ }
+
+ if( !pMgr )
+ {
+ if( !mpGlobalMgr )
+ {
+ SvtCacheOptions aCacheOptions;
+
+ mpGlobalMgr = new GraphicManager( aCacheOptions.GetGraphicManagerTotalCacheSize(),
+ aCacheOptions.GetGraphicManagerObjectCacheSize() );
+ mpGlobalMgr->SetCacheTimeout( aCacheOptions.GetGraphicManagerObjectReleaseTime() );
+ }
+
+ mpMgr = mpGlobalMgr;
+ }
+ else
+ mpMgr = (GraphicManager*) pMgr;
+
+ mpMgr->ImplRegisterObj( *this, maGraphic, pID, pCopyObj );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplAutoSwapIn()
+{
+ if( IsSwappedOut() )
+ {
+ if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
+ mbAutoSwapped = FALSE;
+ else
+ {
+ mbIsInSwapIn = TRUE;
+
+ if( maGraphic.SwapIn() )
+ mbAutoSwapped = FALSE;
+ else
+ {
+ SvStream* pStream = GetSwapStream();
+
+ if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
+ {
+ if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
+ {
+ if( HasLink() )
+ {
+ String aURLStr;
+
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( GetLink(), aURLStr ) )
+ {
+ SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_READ );
+
+ if( pIStm )
+ {
+ (*pIStm) >> maGraphic;
+ mbAutoSwapped = ( maGraphic.GetType() != GRAPHIC_NONE );
+ delete pIStm;
+ }
+ }
+ }
+ }
+ else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
+ mbAutoSwapped = !maGraphic.SwapIn();
+ else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
+ mbAutoSwapped = maGraphic.IsSwapOut();
+ else
+ {
+ mbAutoSwapped = !maGraphic.SwapIn( pStream );
+ delete pStream;
+ }
+ }
+ else
+ {
+ DBG_ASSERT( ( GRAPHIC_NONE == meType ) || ( GRAPHIC_DEFAULT == meType ),
+ "GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" );
+ }
+ }
+
+ mbIsInSwapIn = FALSE;
+
+ if( !mbAutoSwapped && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedIn( *this );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+BOOL GraphicObject::ImplGetCropParams( OutputDevice* pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
+ PolyPolygon& rClipPolyPoly, BOOL& bRectClipRegion ) const
+{
+ BOOL bRet = FALSE;
+
+ if( GetType() != GRAPHIC_NONE )
+ {
+ Polygon aClipPoly( Rectangle( rPt, rSz ) );
+ const USHORT nRot10 = pAttr->GetRotation() % 3600;
+ const Point aOldOrigin( rPt );
+ // --> OD 2005-09-30 #i54875# - It's not needed to get the graphic again.
+// const Graphic& rGraphic = GetGraphic();
+ // <--
+ const MapMode aMap100( MAP_100TH_MM );
+ Size aSize100;
+ long nTotalWidth, nTotalHeight;
+ long nNewLeft, nNewTop, nNewRight, nNewBottom;
+ double fScale;
+
+ if( nRot10 )
+ {
+ aClipPoly.Rotate( rPt, nRot10 );
+ bRectClipRegion = FALSE;
+ }
+ else
+ bRectClipRegion = TRUE;
+
+ rClipPolyPoly = aClipPoly;
+
+ // --> OD 2005-09-30 #i54875# - directly access member <maGraphic> to
+ // get <PrefSize> and <PrefMapMode>.
+// if( rGraphic.GetPrefMapMode() == MAP_PIXEL )
+// aSize100 = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), aMap100 );
+// else
+// aSize100 = pOut->LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), aMap100 );
+ if( maGraphic.GetPrefMapMode() == MAP_PIXEL )
+ aSize100 = Application::GetDefaultDevice()->PixelToLogic( maGraphic.GetPrefSize(), aMap100 );
+ else
+ {
+ MapMode m(maGraphic.GetPrefMapMode());
+ aSize100 = pOut->LogicToLogic( maGraphic.GetPrefSize(), &m, &aMap100 );
+ }
+ // <--
+
+ nTotalWidth = aSize100.Width() - pAttr->GetLeftCrop() - pAttr->GetRightCrop();
+ nTotalHeight = aSize100.Height() - pAttr->GetTopCrop() - pAttr->GetBottomCrop();
+
+ if( aSize100.Width() > 0 && aSize100.Height() > 0 && nTotalWidth > 0 && nTotalHeight > 0 )
+ {
+ fScale = (double) aSize100.Width() / nTotalWidth;
+ nNewLeft = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_HORZ ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * fScale );
+ nNewRight = nNewLeft + FRound( aSize100.Width() * fScale ) - 1;
+
+ fScale = (double) rSz.Width() / aSize100.Width();
+ rPt.X() += FRound( nNewLeft * fScale );
+ rSz.Width() = FRound( ( nNewRight - nNewLeft + 1 ) * fScale );
+
+ fScale = (double) aSize100.Height() / nTotalHeight;
+ nNewTop = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_VERT ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * fScale );
+ nNewBottom = nNewTop + FRound( aSize100.Height() * fScale ) - 1;
+
+ fScale = (double) rSz.Height() / aSize100.Height();
+ rPt.Y() += FRound( nNewTop * fScale );
+ rSz.Height() = FRound( ( nNewBottom - nNewTop + 1 ) * fScale );
+
+ if( nRot10 )
+ {
+ Polygon aOriginPoly( 1 );
+
+ aOriginPoly[ 0 ] = rPt;
+ aOriginPoly.Rotate( aOldOrigin, nRot10 );
+ rPt = aOriginPoly[ 0 ];
+ }
+
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
+{
+ if( &rGraphicObj != this )
+ {
+ mpMgr->ImplUnregisterObj( *this );
+
+ delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
+ delete mpSimpleCache, mpSimpleCache = NULL;
+ delete mpLink;
+ delete mpUserData;
+
+ maGraphic = rGraphicObj.GetGraphic();
+ maAttr = rGraphicObj.maAttr;
+ mpLink = rGraphicObj.mpLink ? new String( *rGraphicObj.mpLink ) : NULL;
+ mpUserData = rGraphicObj.mpUserData ? new String( *rGraphicObj.mpUserData ) : NULL;
+ ImplAssignGraphicData();
+ mbAutoSwapped = FALSE;
+ mpMgr = rGraphicObj.mpMgr;
+
+ mpMgr->ImplRegisterObj( *this, maGraphic, NULL, &rGraphicObj );
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::operator==( const GraphicObject& rGraphicObj ) const
+{
+ return( ( rGraphicObj.maGraphic == maGraphic ) &&
+ ( rGraphicObj.maAttr == maAttr ) &&
+ ( rGraphicObj.GetLink() == GetLink() ) );
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicObject::Load( SvStream& rIStm )
+{
+ rIStm >> *this;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicObject::Save( SvStream& rOStm )
+{
+ rOStm << *this;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicObject::Assign( const SvDataCopyStream& rCopyStream )
+{
+ *this = (const GraphicObject& ) rCopyStream;
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicObject::GetUniqueID() const
+{
+ if ( !IsInSwapIn() && IsEPS() )
+ const_cast<GraphicObject*>(this)->FireSwapInRequest();
+
+ ByteString aRet;
+
+ if( mpMgr )
+ aRet = mpMgr->ImplGetUniqueID( *this );
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicObject::GetChecksum() const
+{
+ return( ( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() ) ? maGraphic.GetChecksum() : 0 );
+}
+
+// -----------------------------------------------------------------------------
+
+SvStream* GraphicObject::GetSwapStream() const
+{
+ return( HasSwapStreamHdl() ? (SvStream*) mpSwapStreamHdl->Call( (void*) this ) : GRFMGR_AUTOSWAPSTREAM_NONE );
+}
+
+// -----------------------------------------------------------------------------
+
+// !!! to be removed
+ULONG GraphicObject::GetReleaseFromCache() const
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetAttr( const GraphicAttr& rAttr )
+{
+ maAttr = rAttr;
+
+ if( mpSimpleCache && ( mpSimpleCache->maAttr != rAttr ) )
+ delete mpSimpleCache, mpSimpleCache = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetLink()
+{
+ if( mpLink )
+ delete mpLink, mpLink = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetLink( const String& rLink )
+{
+ delete mpLink, mpLink = new String( rLink );
+}
+
+// -----------------------------------------------------------------------------
+
+String GraphicObject::GetLink() const
+{
+ if( mpLink )
+ return *mpLink;
+ else
+ return String();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetUserData()
+{
+ if( mpUserData )
+ delete mpUserData, mpUserData = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetUserData( const String& rUserData )
+{
+ delete mpUserData, mpUserData = new String( rUserData );
+}
+
+// -----------------------------------------------------------------------------
+
+String GraphicObject::GetUserData() const
+{
+ if( mpUserData )
+ return *mpUserData;
+ else
+ return String();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetSwapStreamHdl()
+{
+ if( mpSwapStreamHdl )
+ {
+ delete mpSwapOutTimer, mpSwapOutTimer = NULL;
+ delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetSwapStreamHdl( const Link& rHdl, const ULONG nSwapOutTimeout )
+{
+ delete mpSwapStreamHdl, mpSwapStreamHdl = new Link( rHdl );
+
+ if( nSwapOutTimeout )
+ {
+ if( !mpSwapOutTimer )
+ {
+ mpSwapOutTimer = new Timer;
+ mpSwapOutTimer->SetTimeoutHdl( LINK( this, GraphicObject, ImplAutoSwapOutHdl ) );
+ }
+
+ mpSwapOutTimer->SetTimeout( nSwapOutTimeout );
+ mpSwapOutTimer->Start();
+ }
+ else
+ delete mpSwapOutTimer, mpSwapOutTimer = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+Link GraphicObject::GetSwapStreamHdl() const
+{
+ if( mpSwapStreamHdl )
+ return *mpSwapStreamHdl;
+ else
+ return Link();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::FireSwapInRequest()
+{
+ ImplAutoSwapIn();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::FireSwapOutRequest()
+{
+ ImplAutoSwapOutHdl( NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::GraphicManagerDestroyed()
+{
+ // we're alive, but our manager doesn't live anymore ==> connect to default manager
+ mpMgr = NULL;
+ ImplSetGraphicManager( NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetGraphicManager( const GraphicManager& rMgr )
+{
+ ImplSetGraphicManager( &rMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicAttr* pAttr, ULONG nFlags ) const
+{
+ BOOL bRet;
+
+ if( nFlags & GRFMGR_DRAW_CACHED )
+ {
+ // --> OD 2005-10-11 #i54875# - Consider cropped graphics.
+ // Note: The graphic manager caches a cropped graphic with its
+ // uncropped position and size.
+// bRet = mpMgr->IsInCache( pOut, rPt, rSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
+ Point aPt( rPt );
+ Size aSz( rSz );
+ if ( pAttr->IsCropped() )
+ {
+ PolyPolygon aClipPolyPoly;
+ BOOL bRectClip;
+ ImplGetCropParams( pOut, aPt, aSz, pAttr, aClipPolyPoly, bRectClip );
+ }
+ bRet = mpMgr->IsInCache( pOut, aPt, aSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ReleaseFromCache()
+{
+
+ mpMgr->ReleaseFromCache( *this );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetAnimationNotifyHdl( const Link& rLink )
+{
+ maGraphic.SetAnimationNotifyHdl( rLink );
+}
+
+// -----------------------------------------------------------------------------
+
+List* GraphicObject::GetAnimationInfoList() const
+{
+ return maGraphic.GetAnimationInfoList();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicAttr* pAttr, ULONG nFlags )
+{
+ GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
+ Point aPt( rPt );
+ Size aSz( rSz );
+ const sal_uInt32 nOldDrawMode = pOut->GetDrawMode();
+ BOOL bCropped = aAttr.IsCropped();
+ BOOL bCached = FALSE;
+ BOOL bRet;
+
+ // #i29534# Provide output rects for PDF writer
+ Rectangle aCropRect;
+
+ if( !( GRFMGR_DRAW_USE_DRAWMODE_SETTINGS & nFlags ) )
+ pOut->SetDrawMode( nOldDrawMode & ( ~( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ) ) );
+
+ // mirrored horizontically
+ if( aSz.Width() < 0L )
+ {
+ aPt.X() += aSz.Width() + 1;
+ aSz.Width() = -aSz.Width();
+ aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_HORZ );
+ }
+
+ // mirrored vertically
+ if( aSz.Height() < 0L )
+ {
+ aPt.Y() += aSz.Height() + 1;
+ aSz.Height() = -aSz.Height();
+ aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_VERT );
+ }
+
+ if( bCropped )
+ {
+ PolyPolygon aClipPolyPoly;
+ BOOL bRectClip;
+ const BOOL bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );
+
+ pOut->Push( PUSH_CLIPREGION );
+
+ if( bCrop )
+ {
+ if( bRectClip )
+ {
+ // #i29534# Store crop rect for later forwarding to
+ // PDF writer
+ aCropRect = aClipPolyPoly.GetBoundRect();
+ pOut->IntersectClipRegion( aCropRect );
+ }
+ else
+ {
+ pOut->IntersectClipRegion( aClipPolyPoly );
+ }
+ }
+ }
+
+ bRet = mpMgr->DrawObj( pOut, aPt, aSz, *this, aAttr, nFlags, bCached );
+
+ if( bCropped )
+ pOut->Pop();
+
+ pOut->SetDrawMode( nOldDrawMode );
+
+ // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins
+ // (code above needs to call GetGraphic twice)
+ if( bCached )
+ {
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Start();
+ else
+ FireSwapOutRequest();
+ }
+
+ return bRet;
+}
+
+// --> OD 2010-01-04 #i105243#
+BOOL GraphicObject::DrawWithPDFHandling( OutputDevice& rOutDev,
+ const Point& rPt, const Size& rSz,
+ const GraphicAttr* pGrfAttr,
+ const ULONG nFlags )
+{
+ const GraphicAttr aGrfAttr( pGrfAttr ? *pGrfAttr : GetAttr() );
+
+ // Notify PDF writer about linked graphic (if any)
+ bool bWritingPdfLinkedGraphic( false );
+ Point aPt( rPt );
+ Size aSz( rSz );
+ Rectangle aCropRect;
+ vcl::PDFExtOutDevData* pPDFExtOutDevData =
+ dynamic_cast<vcl::PDFExtOutDevData*>(rOutDev.GetExtOutDevData());
+ if( pPDFExtOutDevData )
+ {
+ // only delegate image handling to PDF, if no special treatment is necessary
+ if( GetGraphic().IsLink() &&
+ rSz.Width() > 0L &&
+ rSz.Height() > 0L &&
+ !aGrfAttr.IsSpecialDrawMode() &&
+ !aGrfAttr.IsMirrored() &&
+ !aGrfAttr.IsRotated() &&
+ !aGrfAttr.IsAdjusted() )
+ {
+ bWritingPdfLinkedGraphic = true;
+
+ if( aGrfAttr.IsCropped() )
+ {
+ PolyPolygon aClipPolyPoly;
+ BOOL bRectClip;
+ const BOOL bCrop = ImplGetCropParams( &rOutDev,
+ aPt, aSz,
+ &aGrfAttr,
+ aClipPolyPoly,
+ bRectClip );
+ if ( bCrop && bRectClip )
+ {
+ aCropRect = aClipPolyPoly.GetBoundRect();
+ }
+ }
+
+ pPDFExtOutDevData->BeginGroup();
+ }
+ }
+
+ BOOL bRet = Draw( &rOutDev, rPt, rSz, &aGrfAttr, nFlags );
+
+ // Notify PDF writer about linked graphic (if any)
+ if( bWritingPdfLinkedGraphic )
+ {
+ pPDFExtOutDevData->EndGroup( const_cast< Graphic& >(GetGraphic()),
+ aGrfAttr.GetTransparency(),
+ Rectangle( aPt, aSz ),
+ aCropRect );
+ }
+
+ return bRet;
+}
+// <--
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::DrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSize,
+ const Size& rOffset, const GraphicAttr* pAttr, ULONG nFlags, int nTileCacheSize1D )
+{
+ if( pOut == NULL || rSize.Width() == 0 || rSize.Height() == 0 )
+ return FALSE;
+
+ const MapMode aOutMapMode( pOut->GetMapMode() );
+ const MapMode aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
+ // #106258# Clamp size to 1 for zero values. This is okay, since
+ // logical size of zero is handled above already
+ const Size aOutTileSize( ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Width() ),
+ ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Height() ) );
+
+ //#i69780 clip final tile size to a sane max size
+ while (((sal_Int64)rSize.Width() * nTileCacheSize1D) > SAL_MAX_UINT16)
+ nTileCacheSize1D /= 2;
+ while (((sal_Int64)rSize.Height() * nTileCacheSize1D) > SAL_MAX_UINT16)
+ nTileCacheSize1D /= 2;
+
+ return ImplDrawTiled( pOut, rArea, aOutTileSize, rOffset, pAttr, nFlags, nTileCacheSize1D );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ long nExtraData, const GraphicAttr* pAttr, ULONG /*nFlags*/,
+ OutputDevice* pFirstFrameOutDev )
+{
+ BOOL bRet = FALSE;
+
+ GetGraphic();
+
+ if( !IsSwappedOut() )
+ {
+ const GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
+
+ if( mbAnimated )
+ {
+ Point aPt( rPt );
+ Size aSz( rSz );
+ BOOL bCropped = aAttr.IsCropped();
+
+ if( bCropped )
+ {
+ PolyPolygon aClipPolyPoly;
+ BOOL bRectClip;
+ const BOOL bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );
+
+ pOut->Push( PUSH_CLIPREGION );
+
+ if( bCrop )
+ {
+ if( bRectClip )
+ pOut->IntersectClipRegion( aClipPolyPoly.GetBoundRect() );
+ else
+ pOut->IntersectClipRegion( aClipPolyPoly );
+ }
+ }
+
+ if( !mpSimpleCache || ( mpSimpleCache->maAttr != aAttr ) || pFirstFrameOutDev )
+ {
+ if( mpSimpleCache )
+ delete mpSimpleCache;
+
+ mpSimpleCache = new GrfSimpleCacheObj( GetTransformedGraphic( &aAttr ), aAttr );
+ mpSimpleCache->maGraphic.SetAnimationNotifyHdl( GetAnimationNotifyHdl() );
+ }
+
+ mpSimpleCache->maGraphic.StartAnimation( pOut, aPt, aSz, nExtraData, pFirstFrameOutDev );
+
+ if( bCropped )
+ pOut->Pop();
+
+ bRet = TRUE;
+ }
+ else
+ bRet = Draw( pOut, rPt, rSz, &aAttr, GRFMGR_DRAW_STANDARD );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::StopAnimation( OutputDevice* pOut, long nExtraData )
+{
+ if( mpSimpleCache )
+ mpSimpleCache->maGraphic.StopAnimation( pOut, nExtraData );
+}
+
+// -----------------------------------------------------------------------------
+
+const Graphic& GraphicObject::GetGraphic() const
+{
+ if( mbAutoSwapped )
+ ( (GraphicObject*) this )->ImplAutoSwapIn();
+
+ return maGraphic;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj )
+{
+ mpMgr->ImplUnregisterObj( *this );
+
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Stop();
+
+ maGraphic = rGraphic;
+ mbAutoSwapped = FALSE;
+ ImplAssignGraphicData();
+ delete mpLink, mpLink = NULL;
+ delete mpSimpleCache, mpSimpleCache = NULL;
+
+ mpMgr->ImplRegisterObj( *this, maGraphic, 0, pCopyObj);
+
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Start();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetGraphic( const Graphic& rGraphic, const String& rLink )
+{
+ SetGraphic( rGraphic );
+ mpLink = new String( rLink );
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMode& rDestMap, const GraphicAttr& rAttr ) const
+{
+ // #104550# Extracted from svx/source/svdraw/svdograf.cxx
+ Graphic aTransGraphic( maGraphic );
+ const GraphicType eType = GetType();
+ const Size aSrcSize( aTransGraphic.GetPrefSize() );
+
+ // #104115# Convert the crop margins to graphic object mapmode
+ const MapMode aMapGraph( aTransGraphic.GetPrefMapMode() );
+ const MapMode aMap100( MAP_100TH_MM );
+
+ Size aCropLeftTop;
+ Size aCropRightBottom;
+
+ if( GRAPHIC_GDIMETAFILE == eType )
+ {
+ GDIMetaFile aMtf( aTransGraphic.GetGDIMetaFile() );
+
+ if( aMapGraph == MAP_PIXEL )
+ {
+ aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(),
+ rAttr.GetTopCrop() ),
+ aMap100 );
+ aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(),
+ rAttr.GetBottomCrop() ),
+ aMap100 );
+ }
+ else
+ {
+ aCropLeftTop = OutputDevice::LogicToLogic( Size( rAttr.GetLeftCrop(),
+ rAttr.GetTopCrop() ),
+ aMap100,
+ aMapGraph );
+ aCropRightBottom = OutputDevice::LogicToLogic( Size( rAttr.GetRightCrop(),
+ rAttr.GetBottomCrop() ),
+ aMap100,
+ aMapGraph );
+ }
+
+ // #104115# If the metafile is cropped, give it a special
+ // treatment: clip against the remaining area, scale up such
+ // that this area later fills the desired size, and move the
+ // origin to the upper left edge of that area.
+ if( rAttr.IsCropped() )
+ {
+ const MapMode aMtfMapMode( aMtf.GetPrefMapMode() );
+
+ Rectangle aClipRect( aMtfMapMode.GetOrigin().X() + aCropLeftTop.Width(),
+ aMtfMapMode.GetOrigin().Y() + aCropLeftTop.Height(),
+ aMtfMapMode.GetOrigin().X() + aSrcSize.Width() - aCropRightBottom.Width(),
+ aMtfMapMode.GetOrigin().Y() + aSrcSize.Height() - aCropRightBottom.Height() );
+
+ // #104115# To correctly crop rotated metafiles, clip by view rectangle
+ aMtf.AddAction( new MetaISectRectClipRegionAction( aClipRect ), 0 );
+
+ // #104115# To crop the metafile, scale larger than the output rectangle
+ aMtf.Scale( (double)rDestSize.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()),
+ (double)rDestSize.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) );
+
+ // #104115# Adapt the pref size by hand (scale changes it
+ // proportionally, but we want it to be smaller than the
+ // former size, to crop the excess out)
+ aMtf.SetPrefSize( Size( (long)((double)rDestSize.Width() * (1.0 + (aCropLeftTop.Width() + aCropRightBottom.Width()) / aSrcSize.Width()) + .5),
+ (long)((double)rDestSize.Height() * (1.0 + (aCropLeftTop.Height() + aCropRightBottom.Height()) / aSrcSize.Height()) + .5) ) );
+
+ // #104115# Adapt the origin of the new mapmode, such that it
+ // is shifted to the place where the cropped output starts
+ Point aNewOrigin( (long)((double)aMtfMapMode.GetOrigin().X() + rDestSize.Width() * aCropLeftTop.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()) + .5),
+ (long)((double)aMtfMapMode.GetOrigin().Y() + rDestSize.Height() * aCropLeftTop.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) + .5) );
+ MapMode aNewMap( rDestMap );
+ aNewMap.SetOrigin( OutputDevice::LogicToLogic(aNewOrigin, aMtfMapMode, rDestMap) );
+ aMtf.SetPrefMapMode( aNewMap );
+ }
+ else
+ {
+ aMtf.Scale( Fraction( rDestSize.Width(), aSrcSize.Width() ), Fraction( rDestSize.Height(), aSrcSize.Height() ) );
+ aMtf.SetPrefMapMode( rDestMap );
+ }
+
+ aTransGraphic = aMtf;
+ }
+ else if( GRAPHIC_BITMAP == eType )
+ {
+ BitmapEx aBitmapEx( aTransGraphic.GetBitmapEx() );
+
+ // convert crops to pixel
+ aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(),
+ rAttr.GetTopCrop() ),
+ aMap100 );
+ aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(),
+ rAttr.GetBottomCrop() ),
+ aMap100 );
+
+ // convert from prefmapmode to pixel
+ const Size aSrcSizePixel( Application::GetDefaultDevice()->LogicToPixel( aSrcSize,
+ aMapGraph ) );
+
+ // setup crop rectangle in pixel
+ Rectangle aCropRect( aCropLeftTop.Width(), aCropLeftTop.Height(),
+ aSrcSizePixel.Width() - aCropRightBottom.Width(),
+ aSrcSizePixel.Height() - aCropRightBottom.Height() );
+
+ // #105641# Also crop animations
+ if( aTransGraphic.IsAnimated() )
+ {
+ USHORT nFrame;
+ Animation aAnim( aTransGraphic.GetAnimation() );
+
+ for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
+ {
+ AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );
+
+ if( !aCropRect.IsInside( Rectangle(aAnimBmp.aPosPix, aAnimBmp.aSizePix) ) )
+ {
+ // setup actual cropping (relative to frame position)
+ Rectangle aCropRectRel( aCropRect );
+ aCropRectRel.Move( -aAnimBmp.aPosPix.X(),
+ -aAnimBmp.aPosPix.Y() );
+
+ // cropping affects this frame, apply it then
+ // do _not_ apply enlargement, this is done below
+ ImplTransformBitmap( aAnimBmp.aBmpEx, rAttr, Size(), Size(),
+ aCropRectRel, rDestSize, FALSE );
+
+ aAnim.Replace( aAnimBmp, nFrame );
+ }
+ // else: bitmap completely within crop area,
+ // i.e. nothing is cropped away
+ }
+
+ // now, apply enlargement (if any) through global animation size
+ if( aCropLeftTop.Width() < 0 ||
+ aCropLeftTop.Height() < 0 ||
+ aCropRightBottom.Width() < 0 ||
+ aCropRightBottom.Height() < 0 )
+ {
+ Size aNewSize( aAnim.GetDisplaySizePixel() );
+ aNewSize.Width() += aCropRightBottom.Width() < 0 ? -aCropRightBottom.Width() : 0;
+ aNewSize.Width() += aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0;
+ aNewSize.Height() += aCropRightBottom.Height() < 0 ? -aCropRightBottom.Height() : 0;
+ aNewSize.Height() += aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0;
+ aAnim.SetDisplaySizePixel( aNewSize );
+ }
+
+ // if topleft has changed, we must move all frames to the
+ // right and bottom, resp.
+ if( aCropLeftTop.Width() < 0 ||
+ aCropLeftTop.Height() < 0 )
+ {
+ Point aPosOffset( aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0,
+ aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0 );
+
+ for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
+ {
+ AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );
+
+ aAnimBmp.aPosPix += aPosOffset;
+
+ aAnim.Replace( aAnimBmp, nFrame );
+ }
+ }
+
+ aTransGraphic = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( aTransGraphic.GetBitmapEx() );
+
+ ImplTransformBitmap( aBmpEx, rAttr, aCropLeftTop, aCropRightBottom,
+ aCropRect, rDestSize, TRUE );
+
+ aTransGraphic = aBmpEx;
+ }
+
+ aTransGraphic.SetPrefSize( rDestSize );
+ aTransGraphic.SetPrefMapMode( rDestMap );
+ }
+
+ GraphicObject aGrfObj( aTransGraphic );
+ aTransGraphic = aGrfObj.GetTransformedGraphic( &rAttr );
+
+ return aTransGraphic;
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const // TODO: Change to Impl
+{
+ GetGraphic();
+
+ Graphic aGraphic;
+ GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
+
+ if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() )
+ {
+ if( aAttr.IsSpecialDrawMode() || aAttr.IsAdjusted() || aAttr.IsMirrored() || aAttr.IsRotated() || aAttr.IsTransparent() )
+ {
+ if( GetType() == GRAPHIC_BITMAP )
+ {
+ if( IsAnimated() )
+ {
+ Animation aAnimation( maGraphic.GetAnimation() );
+ GraphicManager::ImplAdjust( aAnimation, aAttr, ADJUSTMENT_ALL );
+ aAnimation.SetLoopCount( mnAnimationLoopCount );
+ aGraphic = aAnimation;
+ }
+ else
+ {
+ BitmapEx aBmpEx( maGraphic.GetBitmapEx() );
+ GraphicManager::ImplAdjust( aBmpEx, aAttr, ADJUSTMENT_ALL );
+ aGraphic = aBmpEx;
+ }
+ }
+ else
+ {
+ GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() );
+ GraphicManager::ImplAdjust( aMtf, aAttr, ADJUSTMENT_ALL );
+ aGraphic = aMtf;
+ }
+ }
+ else
+ {
+ if( ( GetType() == GRAPHIC_BITMAP ) && IsAnimated() )
+ {
+ Animation aAnimation( maGraphic.GetAnimation() );
+ aAnimation.SetLoopCount( mnAnimationLoopCount );
+ aGraphic = aAnimation;
+ }
+ else
+ aGraphic = maGraphic;
+ }
+ }
+
+ return aGraphic;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ResetAnimationLoopCount()
+{
+ if( IsAnimated() && !IsSwappedOut() )
+ {
+ maGraphic.ResetAnimationLoopCount();
+
+ if( mpSimpleCache )
+ mpSimpleCache->maGraphic.ResetAnimationLoopCount();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapOut()
+{
+ BOOL bRet = ( !mbAutoSwapped ? maGraphic.SwapOut() : FALSE );
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedOut( *this );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapOut( SvStream* pOStm )
+{
+ BOOL bRet = ( !mbAutoSwapped ? maGraphic.SwapOut( pOStm ) : FALSE );
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedOut( *this );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapIn()
+{
+ BOOL bRet;
+
+ if( mbAutoSwapped )
+ {
+ ImplAutoSwapIn();
+ bRet = TRUE;
+ }
+ else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
+ bRet = TRUE;
+ else
+ {
+ bRet = maGraphic.SwapIn();
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedIn( *this );
+ }
+
+ if( bRet )
+ ImplAssignGraphicData();
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapIn( SvStream* pIStm )
+{
+ BOOL bRet;
+
+ if( mbAutoSwapped )
+ {
+ ImplAutoSwapIn();
+ bRet = TRUE;
+ }
+ else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
+ bRet = TRUE;
+ else
+ {
+ bRet = maGraphic.SwapIn( pIStm );
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedIn( *this );
+ }
+
+ if( bRet )
+ ImplAssignGraphicData();
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetSwapState()
+{
+ if( !IsSwappedOut() )
+ {
+ mbAutoSwapped = TRUE;
+
+ if( mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedOut( *this );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+IMPL_LINK( GraphicObject, ImplAutoSwapOutHdl, void*, EMPTYARG )
+{
+ if( !IsSwappedOut() )
+ {
+ mbIsInSwapOut = TRUE;
+
+ SvStream* pStream = GetSwapStream();
+
+ if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
+ {
+ if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
+ mbAutoSwapped = SwapOut( NULL );
+ else
+ {
+ if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
+ mbAutoSwapped = SwapOut();
+ else
+ {
+ mbAutoSwapped = SwapOut( pStream );
+ delete pStream;
+ }
+ }
+ }
+
+ mbIsInSwapOut = FALSE;
+ }
+
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Start();
+
+ return 0L;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ Graphic aGraphic;
+ GraphicAttr aAttr;
+ ByteString aLink;
+ BOOL bLink;
+
+ rIStm >> aGraphic >> aAttr >> bLink;
+
+ rGraphicObj.SetGraphic( aGraphic );
+ rGraphicObj.SetAttr( aAttr );
+
+ if( bLink )
+ {
+ rIStm >> aLink;
+ rGraphicObj.SetLink( UniString( aLink, RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ rGraphicObj.SetLink();
+
+ rGraphicObj.SetSwapStreamHdl();
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
+ const BOOL bLink = rGraphicObj.HasLink();
+
+ rOStm << rGraphicObj.GetGraphic() << rGraphicObj.GetAttr() << bLink;
+
+ if( bLink )
+ rOStm << ByteString( rGraphicObj.GetLink(), RTL_TEXTENCODING_UTF8 );
+
+ return rOStm;
+}
+
+#define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
+
+GraphicObject GraphicObject::CreateGraphicObjectFromURL( const ::rtl::OUString &rURL )
+{
+ const String aURL( rURL ), aPrefix( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX) );
+ if( aURL.Search( aPrefix ) == 0 )
+ {
+ // graphic manager url
+ ByteString aUniqueID( String(rURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 )), RTL_TEXTENCODING_UTF8 );
+ return GraphicObject( aUniqueID );
+ }
+ else
+ {
+ Graphic aGraphic;
+ if ( aURL.Len() )
+ {
+ SvStream* pStream = utl::UcbStreamHelper::CreateStream( aURL, STREAM_READ );
+ if( pStream )
+ GraphicConverter::Import( *pStream, aGraphic );
+ }
+
+ return GraphicObject( aGraphic );
+ }
+}
+
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
new file mode 100644
index 000000000000..7e1255aabc56
--- /dev/null
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -0,0 +1,2382 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <vos/macros.hxx>
+#include <vcl/bmpacc.hxx>
+#include <tools/poly.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/window.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/animate.hxx>
+#include <vcl/alpha.hxx>
+#include <vcl/virdev.hxx>
+#include "grfcache.hxx"
+#include <svtools/grfmgr.hxx>
+
+// -----------
+// - defines -
+// -----------
+
+#define MAX_PRINTER_EXT 1024
+#define MAP( cVal0, cVal1, nFrac ) ((BYTE)((((long)(cVal0)<<20L)+nFrac*((long)(cVal1)-(cVal0)))>>20L))
+#define WATERMARK_LUM_OFFSET 50
+#define WATERMARK_CON_OFFSET -70
+
+// -----------
+// - helpers -
+// -----------
+
+namespace {
+
+void muckWithBitmap( const Point& rDestPoint,
+ const Size& rDestSize,
+ const Size& rRefSize,
+ bool& o_rbNonBitmapActionEncountered )
+{
+ const Point aEmptyPoint;
+
+ if( aEmptyPoint != rDestPoint ||
+ rDestSize != rRefSize )
+ {
+ // non-fullscale, or offsetted bmp -> fallback to mtf
+ // rendering
+ o_rbNonBitmapActionEncountered = true;
+ }
+}
+
+BitmapEx muckWithBitmap( const BitmapEx& rBmpEx,
+ const Point& rSrcPoint,
+ const Size& rSrcSize,
+ const Point& rDestPoint,
+ const Size& rDestSize,
+ const Size& rRefSize,
+ bool& o_rbNonBitmapActionEncountered )
+{
+ BitmapEx aBmpEx;
+
+ muckWithBitmap(rDestPoint,
+ rDestSize,
+ rRefSize,
+ o_rbNonBitmapActionEncountered);
+
+ if( o_rbNonBitmapActionEncountered )
+ return aBmpEx;
+
+ aBmpEx = rBmpEx;
+
+ if( (rSrcPoint.X() != 0 && rSrcPoint.Y() != 0) ||
+ rSrcSize != rBmpEx.GetSizePixel() )
+ {
+ // crop bitmap to given source rectangle (no
+ // need to copy and convert the whole bitmap)
+ const Rectangle aCropRect( rSrcPoint,
+ rSrcSize );
+ aBmpEx.Crop( aCropRect );
+ }
+
+ return aBmpEx;
+}
+
+} // namespace {
+
+
+// ------------------
+// - GraphicManager -
+// ------------------
+
+GraphicManager::GraphicManager( ULONG nCacheSize, ULONG nMaxObjCacheSize ) :
+ mpCache( new GraphicCache( *this, nCacheSize, nMaxObjCacheSize ) )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicManager::~GraphicManager()
+{
+ for( void* pObj = maObjList.First(); pObj; pObj = maObjList.Next() )
+ ( (GraphicObject*) pObj )->GraphicManagerDestroyed();
+
+ delete mpCache;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::SetMaxCacheSize( ULONG nNewCacheSize )
+{
+ mpCache->SetMaxDisplayCacheSize( nNewCacheSize );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetMaxCacheSize() const
+{
+ return mpCache->GetMaxDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::SetMaxObjCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached )
+{
+ mpCache->SetMaxObjDisplayCacheSize( nNewMaxObjSize, bDestroyGreaterCached );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetMaxObjCacheSize() const
+{
+ return mpCache->GetMaxObjDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetUsedCacheSize() const
+{
+ return mpCache->GetUsedDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetFreeCacheSize() const
+{
+ return mpCache->GetFreeDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::SetCacheTimeout( ULONG nTimeoutSeconds )
+{
+ mpCache->SetCacheTimeout( nTimeoutSeconds );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetCacheTimeout() const
+{
+ return mpCache->GetCacheTimeout();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ClearCache()
+{
+ mpCache->ClearDisplayCache();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ReleaseFromCache( const GraphicObject& /*rObj*/ )
+{
+ // !!!
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::IsInCache( OutputDevice* pOut, const Point& rPt,
+ const Size& rSz, const GraphicObject& rObj,
+ const GraphicAttr& rAttr ) const
+{
+ return mpCache->IsInDisplayCache( pOut, rPt, rSz, rObj, rAttr );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::DrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ GraphicObject& rObj, const GraphicAttr& rAttr,
+ const ULONG nFlags, BOOL& rCached )
+{
+ Point aPt( rPt );
+ Size aSz( rSz );
+ BOOL bRet = FALSE;
+
+ rCached = FALSE;
+
+ if( ( rObj.GetType() == GRAPHIC_BITMAP ) || ( rObj.GetType() == GRAPHIC_GDIMETAFILE ) )
+ {
+ // create output and fill cache
+ const Size aOutSize( pOut->GetOutputSizePixel() );
+
+ if( rObj.IsAnimated() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ||
+ ( !( nFlags & GRFMGR_DRAW_NO_SUBSTITUTE ) &&
+ ( ( nFlags & GRFMGR_DRAW_SUBSTITUTE ) ||
+ !( nFlags & GRFMGR_DRAW_CACHED ) ||
+ ( pOut->GetConnectMetaFile() && !pOut->IsOutputEnabled() ) ) ) )
+ {
+ // simple output of transformed graphic
+ const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
+
+ if( aGraphic.IsSupportedGraphic() )
+ {
+ const USHORT nRot10 = rAttr.GetRotation() % 3600;
+
+ if( nRot10 )
+ {
+ Polygon aPoly( Rectangle( aPt, aSz ) );
+
+ aPoly.Rotate( aPt, nRot10 );
+ const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
+ aPt = aRotBoundRect.TopLeft();
+ aSz = aRotBoundRect.GetSize();
+ }
+
+ aGraphic.Draw( pOut, aPt, aSz );
+ }
+
+ bRet = TRUE;
+ }
+
+ if( !bRet )
+ {
+ // cached/direct drawing
+ if( !mpCache->DrawDisplayCacheObj( pOut, aPt, aSz, rObj, rAttr ) )
+ bRet = ImplDraw( pOut, aPt, aSz, rObj, rAttr, nFlags, rCached );
+ else
+ bRet = rCached = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplRegisterObj( const GraphicObject& rObj, Graphic& rSubstitute,
+ const ByteString* pID, const GraphicObject* pCopyObj )
+{
+ maObjList.Insert( (void*) &rObj, LIST_APPEND );
+ mpCache->AddGraphicObject( rObj, rSubstitute, pID, pCopyObj );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplUnregisterObj( const GraphicObject& rObj )
+{
+ mpCache->ReleaseGraphicObject( rObj );
+ maObjList.Remove( (void*) &rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj )
+{
+ mpCache->GraphicObjectWasSwappedOut( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicManager::ImplGetUniqueID( const GraphicObject& rObj ) const
+{
+ return mpCache->GetUniqueID( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplFillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ return( mpCache->FillSwappedGraphicObject( rObj, rSubstitute ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj )
+{
+ mpCache->GraphicObjectWasSwappedIn( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
+ const Size& rSz, GraphicObject& rObj,
+ const GraphicAttr& rAttr,
+ const ULONG nFlags, BOOL& rCached )
+{
+ const Graphic& rGraphic = rObj.GetGraphic();
+ BOOL bRet = FALSE;
+
+ if( rGraphic.IsSupportedGraphic() && !rGraphic.IsSwapOut() )
+ {
+ if( GRAPHIC_BITMAP == rGraphic.GetType() )
+ {
+ const BitmapEx aSrcBmpEx( rGraphic.GetBitmapEx() );
+
+ // #i46805# No point in caching a bitmap that is rendered
+ // via RectFill on the OutDev
+ if( !(pOut->GetDrawMode() & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP )) &&
+ mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
+ {
+ BitmapEx aDstBmpEx;
+
+ if( ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags, &aDstBmpEx ) )
+ {
+ rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
+ bRet = TRUE;
+ }
+ }
+
+ if( !bRet )
+ bRet = ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags );
+ }
+ else
+ {
+ const GDIMetaFile& rSrcMtf = rGraphic.GetGDIMetaFile();
+
+ if( mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
+ {
+ GDIMetaFile aDstMtf;
+ BitmapEx aContainedBmpEx;
+
+ if( ImplCreateOutput( pOut, rPt, rSz, rSrcMtf, rAttr, nFlags, aDstMtf, aContainedBmpEx ) )
+ {
+ if( !!aContainedBmpEx )
+ {
+ // #117889# Use bitmap output method, if
+ // metafile basically contains only a single
+ // bitmap
+ BitmapEx aDstBmpEx;
+
+ if( ImplCreateOutput( pOut, rPt, rSz, aContainedBmpEx, rAttr, nFlags, &aDstBmpEx ) )
+ {
+ rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
+ bRet = TRUE;
+ }
+ }
+ else
+ {
+ rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstMtf );
+ bRet = TRUE;
+ }
+ }
+ }
+
+ if( !bRet )
+ {
+ const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
+
+ if( aGraphic.IsSupportedGraphic() )
+ {
+ aGraphic.Draw( pOut, rPt, rSz );
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateOutput( OutputDevice* pOut,
+ const Point& rPt, const Size& rSz,
+ const BitmapEx& rBmpEx, const GraphicAttr& rAttr,
+ const ULONG nFlags, BitmapEx* pBmpEx )
+{
+ USHORT nRot10 = rAttr.GetRotation() % 3600;
+ Point aOutPtPix;
+ Size aOutSzPix;
+ Size aUnrotatedSzPix( pOut->LogicToPixel( rSz ) );
+ BOOL bRet = FALSE;
+
+ if( nRot10 )
+ {
+ Polygon aPoly( Rectangle( rPt, rSz ) );
+
+ aPoly.Rotate( rPt, nRot10 );
+ const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
+ aOutPtPix = pOut->LogicToPixel( aRotBoundRect.TopLeft() );
+ aOutSzPix = pOut->LogicToPixel( aRotBoundRect.GetSize() );
+ }
+ else
+ {
+ aOutPtPix = pOut->LogicToPixel( rPt );
+ aOutSzPix = aUnrotatedSzPix;
+ }
+
+ if( aUnrotatedSzPix.Width() && aUnrotatedSzPix.Height() )
+ {
+ BitmapEx aBmpEx( rBmpEx );
+ BitmapEx aOutBmpEx;
+ Point aOutPt;
+ Size aOutSz;
+ const Size& rBmpSzPix = rBmpEx.GetSizePixel();
+ const long nW = rBmpSzPix.Width();
+ const long nH = rBmpSzPix.Height();
+ const long nNewW = aUnrotatedSzPix.Width();
+ const long nNewH = aUnrotatedSzPix.Height();
+ double fTmp;
+ long* pMapIX = new long[ nNewW ];
+ long* pMapFX = new long[ nNewW ];
+ long* pMapIY = new long[ nNewH ];
+ long* pMapFY = new long[ nNewH ];
+ long nStartX = -1, nStartY = -1, nEndX = -1, nEndY = -1;
+ long nX, nY, nTmp, nTmpX, nTmpY;
+ BOOL bHMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
+ BOOL bVMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+
+ if( nFlags & GRFMGR_DRAW_BILINEAR )
+ {
+ const double fRevScaleX = ( nNewW > 1L ) ? ( (double) ( nW - 1L ) / ( nNewW - 1L ) ) : 0.0;
+ const double fRevScaleY = ( nNewH > 1L ) ? ( (double) ( nH - 1L ) / ( nNewH - 1L ) ) : 0.0;
+
+ // create horizontal mapping table
+ for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
+ {
+ fTmp = nX * fRevScaleX;
+
+ if( bHMirr )
+ fTmp = nTmpX - fTmp;
+
+ pMapFX[ nX ] = (long) ( ( fTmp - ( pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
+ }
+
+ // create vertical mapping table
+ for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
+ {
+ fTmp = nY * fRevScaleY;
+
+ if( bVMirr )
+ fTmp = nTmpY - fTmp;
+
+ pMapFY[ nY ] = (long) ( ( fTmp - ( pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
+ }
+ }
+ else
+ {
+ // #98290# Use a different mapping for non-interpolating mode, to avoid missing rows/columns
+ const double fRevScaleX = ( nNewW > 1L ) ? ( (double) nW / nNewW ) : 0.0;
+ const double fRevScaleY = ( nNewH > 1L ) ? ( (double) nH / nNewH ) : 0.0;
+
+ // create horizontal mapping table
+ for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
+ {
+ fTmp = nX * fRevScaleX;
+
+ if( bHMirr )
+ fTmp = nTmpX - fTmp;
+
+ // #98290# Do not use round to zero, otherwise last column will be missing
+ pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp );
+ pMapFX[ nX ] = fTmp >= nTmp+1 ? 1048576 : 0;
+ }
+
+ // create vertical mapping table
+ for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
+ {
+ fTmp = nY * fRevScaleY;
+
+ if( bVMirr )
+ fTmp = nTmpY - fTmp;
+
+ // #98290# Do not use round to zero, otherwise last row will be missing
+ pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp );
+ pMapFY[ nY ] = fTmp >= nTmp+1 ? 1048576 : 0;
+ }
+ }
+
+ // calculate output sizes
+ if( !pBmpEx )
+ {
+ Point aPt;
+ Rectangle aOutRect( aPt, pOut->GetOutputSizePixel() );
+ Rectangle aBmpRect( aOutPtPix, aOutSzPix );
+
+ if( pOut->GetOutDevType() == OUTDEV_WINDOW )
+ {
+ const Region aPaintRgn( ( (Window*) pOut )->GetPaintRegion() );
+ if( !aPaintRgn.IsNull() )
+ aOutRect.Intersection( pOut->LogicToPixel( aPaintRgn.GetBoundRect() ) );
+ }
+
+ aOutRect.Intersection( aBmpRect );
+
+ if( !aOutRect.IsEmpty() )
+ {
+ aOutPt = pOut->PixelToLogic( aOutRect.TopLeft() );
+ aOutSz = pOut->PixelToLogic( aOutRect.GetSize() );
+ nStartX = aOutRect.Left() - aBmpRect.Left();
+ nStartY = aOutRect.Top() - aBmpRect.Top();
+ nEndX = aOutRect.Right() - aBmpRect.Left();
+ nEndY = aOutRect.Bottom() - aBmpRect.Top();
+ }
+ else
+ nStartX = -1L; // invalid
+ }
+ else
+ {
+ aOutPt = pOut->PixelToLogic( aOutPtPix );
+ aOutSz = pOut->PixelToLogic( aOutSzPix );
+ nStartX = nStartY = 0;
+ nEndX = aOutSzPix.Width() - 1L;
+ nEndY = aOutSzPix.Height() - 1L;
+ }
+
+ // do transformation
+ if( nStartX >= 0L )
+ {
+ const BOOL bSimple = ( 1 == nW || 1 == nH );
+
+ if( nRot10 )
+ {
+ if( bSimple )
+ {
+ bRet = ( aOutBmpEx = aBmpEx ).Scale( aUnrotatedSzPix );
+
+ if( bRet )
+ aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
+ }
+ else
+ {
+ bRet = ImplCreateRotatedScaled( aBmpEx,
+ nRot10, aOutSzPix, aUnrotatedSzPix,
+ pMapIX, pMapFX, pMapIY, pMapFY, nStartX, nEndX, nStartY, nEndY,
+ aOutBmpEx );
+ }
+ }
+ else
+ {
+ // #105229# Don't scale if output size equals bitmap size
+ // #107226# Copy through only if we're not mirroring
+ if( !bHMirr && !bVMirr && aOutSzPix == rBmpSzPix )
+ {
+ // #107226# Use original dimensions when just copying through
+ aOutPt = pOut->PixelToLogic( aOutPtPix );
+ aOutSz = pOut->PixelToLogic( aOutSzPix );
+ aOutBmpEx = aBmpEx;
+ bRet = TRUE;
+ }
+ else
+ {
+ if( bSimple )
+ bRet = ( aOutBmpEx = aBmpEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
+ else
+ {
+ bRet = ImplCreateScaled( aBmpEx,
+ pMapIX, pMapFX, pMapIY, pMapFY,
+ nStartX, nEndX, nStartY, nEndY,
+ aOutBmpEx );
+ }
+ }
+ }
+
+ if( bRet )
+ {
+ // attribute adjustment if neccessary
+ if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsTransparent() )
+ ImplAdjust( aOutBmpEx, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+
+ // OutDev adjustment if neccessary
+ if( pOut->GetOutDevType() != OUTDEV_PRINTER && pOut->GetBitCount() <= 8 && aOutBmpEx.GetBitCount() >= 8 )
+ aOutBmpEx.Dither( BMP_DITHER_MATRIX );
+ }
+ }
+
+ // delete lookup tables
+ delete[] pMapIX;
+ delete[] pMapFX;
+ delete[] pMapIY;
+ delete[] pMapFY;
+
+ // create output
+ if( bRet )
+ {
+ if( !pBmpEx )
+ pOut->DrawBitmapEx( aOutPt, aOutSz, aOutBmpEx );
+ else
+ {
+ if( !rAttr.IsTransparent() && !aOutBmpEx.IsAlpha() )
+ aOutBmpEx = BitmapEx( aOutBmpEx.GetBitmap().CreateDisplayBitmap( pOut ), aOutBmpEx.GetMask() );
+
+ pOut->DrawBitmapEx( aOutPt, aOutSz, *pBmpEx = aOutBmpEx );
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateOutput( OutputDevice* pOut,
+ const Point& rPt, const Size& rSz,
+ const GDIMetaFile& rMtf, const GraphicAttr& rAttr,
+ const ULONG /*nFlags*/, GDIMetaFile& rOutMtf, BitmapEx& rOutBmpEx )
+{
+ const Size aNewSize( rMtf.GetPrefSize() );
+
+ rOutMtf = rMtf;
+
+ // #117889# count bitmap actions, and flag actions that paint, but
+ // are no bitmaps.
+ sal_Int32 nNumBitmaps(0);
+ bool bNonBitmapActionEncountered(false);
+ if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
+ {
+ const double fGrfWH = (double) aNewSize.Width() / aNewSize.Height();
+ const double fOutWH = (double) rSz.Width() / rSz.Height();
+
+ const double fScaleX = fOutWH / fGrfWH;
+ const double fScaleY = 1.0;
+
+ const MapMode& rPrefMapMode( rMtf.GetPrefMapMode() );
+ const Size& rSizePix( pOut->LogicToPixel( aNewSize,
+ rPrefMapMode ) );
+
+ // taking care of font width default if scaling metafile.
+ // #117889# use existing metafile scan, to determine whether
+ // the metafile basically displays a single bitmap. Note that
+ // the solution, as implemented here, is quite suboptimal (the
+ // cases where a mtf consisting basically of a single bitmap,
+ // that fail to pass the test below, are probably frequent). A
+ // better solution would involve FSAA, but that's currently
+ // expensive, and might trigger bugs on display drivers, if
+ // VDevs get bigger than the actual screen.
+ sal_uInt32 nCurPos;
+ MetaAction* pAct;
+ for( nCurPos = 0, pAct = (MetaAction*)rOutMtf.FirstAction(); pAct;
+ pAct = (MetaAction*)rOutMtf.NextAction(), nCurPos++ )
+ {
+ MetaAction* pModAct = NULL;
+ switch( pAct->GetType() )
+ {
+ case META_FONT_ACTION:
+ {
+ MetaFontAction* pA = (MetaFontAction*)pAct;
+ Font aFont( pA->GetFont() );
+ if ( !aFont.GetWidth() )
+ {
+ FontMetric aFontMetric( pOut->GetFontMetric( aFont ) );
+ aFont.SetWidth( aFontMetric.GetWidth() );
+ pModAct = new MetaFontAction( aFont );
+ }
+ }
+ // FALLTHROUGH intended
+ case META_NULL_ACTION:
+ // FALLTHROUGH intended
+
+ // OutDev state changes (which don't affect bitmap
+ // output)
+ case META_LINECOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_FILLCOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTCOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTFILLCOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTALIGN_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTLINECOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTLINE_ACTION:
+ // FALLTHROUGH intended
+ case META_PUSH_ACTION:
+ // FALLTHROUGH intended
+ case META_POP_ACTION:
+ // FALLTHROUGH intended
+ case META_LAYOUTMODE_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTLANGUAGE_ACTION:
+ // FALLTHROUGH intended
+ case META_COMMENT_ACTION:
+ break;
+
+ // bitmap output methods
+ case META_BMP_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpAction* pAction = (MetaBmpAction*)pAct;
+
+ rOutBmpEx = BitmapEx( pAction->GetBitmap() );
+ muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pAction->GetBitmap().GetSizePixel(),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ ++nNumBitmaps;
+ }
+ break;
+
+ case META_BMPSCALE_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpScaleAction* pAction = (MetaBmpScaleAction*)pAct;
+
+ rOutBmpEx = BitmapEx( pAction->GetBitmap() );
+ muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ ++nNumBitmaps;
+ }
+ break;
+
+ case META_BMPSCALEPART_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpScalePartAction* pAction = (MetaBmpScalePartAction*)pAct;
+
+ rOutBmpEx = muckWithBitmap( BitmapEx( pAction->GetBitmap() ),
+ pAction->GetSrcPoint(),
+ pAction->GetSrcSize(),
+ pOut->LogicToPixel( pAction->GetDestPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetDestSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ ++nNumBitmaps;
+ }
+ break;
+
+ case META_BMPEX_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpExAction* pAction = (MetaBmpExAction*)pAct;
+
+ rOutBmpEx = pAction->GetBitmapEx();
+ muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pAction->GetBitmapEx().GetSizePixel(),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ ++nNumBitmaps;
+ }
+ break;
+
+ case META_BMPEXSCALE_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpExScaleAction* pAction = (MetaBmpExScaleAction*)pAct;
+
+ rOutBmpEx = pAction->GetBitmapEx();
+ muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ ++nNumBitmaps;
+ }
+ break;
+
+ case META_BMPEXSCALEPART_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpExScalePartAction* pAction = (MetaBmpExScalePartAction*)pAct;
+
+ rOutBmpEx = muckWithBitmap( pAction->GetBitmapEx(),
+ pAction->GetSrcPoint(),
+ pAction->GetSrcSize(),
+ pOut->LogicToPixel( pAction->GetDestPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetDestSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ ++nNumBitmaps;
+ }
+ break;
+
+ // these actions actually output something (that's
+ // different from a bitmap)
+ case META_RASTEROP_ACTION:
+ if( ((MetaRasterOpAction*)pAct)->GetRasterOp() == ROP_OVERPAINT )
+ break;
+ // FALLTHROUGH intended
+ case META_PIXEL_ACTION:
+ // FALLTHROUGH intended
+ case META_POINT_ACTION:
+ // FALLTHROUGH intended
+ case META_LINE_ACTION:
+ // FALLTHROUGH intended
+ case META_RECT_ACTION:
+ // FALLTHROUGH intended
+ case META_ROUNDRECT_ACTION:
+ // FALLTHROUGH intended
+ case META_ELLIPSE_ACTION:
+ // FALLTHROUGH intended
+ case META_ARC_ACTION:
+ // FALLTHROUGH intended
+ case META_PIE_ACTION:
+ // FALLTHROUGH intended
+ case META_CHORD_ACTION:
+ // FALLTHROUGH intended
+ case META_POLYLINE_ACTION:
+ // FALLTHROUGH intended
+ case META_POLYGON_ACTION:
+ // FALLTHROUGH intended
+ case META_POLYPOLYGON_ACTION:
+ // FALLTHROUGH intended
+
+ case META_TEXT_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTARRAY_ACTION:
+ // FALLTHROUGH intended
+ case META_STRETCHTEXT_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTRECT_ACTION:
+ // FALLTHROUGH intended
+
+ case META_MASK_ACTION:
+ // FALLTHROUGH intended
+ case META_MASKSCALE_ACTION:
+ // FALLTHROUGH intended
+ case META_MASKSCALEPART_ACTION:
+ // FALLTHROUGH intended
+
+ case META_GRADIENT_ACTION:
+ // FALLTHROUGH intended
+ case META_HATCH_ACTION:
+ // FALLTHROUGH intended
+ case META_WALLPAPER_ACTION:
+ // FALLTHROUGH intended
+
+ case META_TRANSPARENT_ACTION:
+ // FALLTHROUGH intended
+ case META_EPS_ACTION:
+ // FALLTHROUGH intended
+ case META_FLOATTRANSPARENT_ACTION:
+ // FALLTHROUGH intended
+ case META_GRADIENTEX_ACTION:
+ // FALLTHROUGH intended
+
+ // OutDev state changes that _do_ affect bitmap
+ // output
+ case META_CLIPREGION_ACTION:
+ // FALLTHROUGH intended
+ case META_ISECTRECTCLIPREGION_ACTION:
+ // FALLTHROUGH intended
+ case META_ISECTREGIONCLIPREGION_ACTION:
+ // FALLTHROUGH intended
+ case META_MOVECLIPREGION_ACTION:
+ // FALLTHROUGH intended
+
+ case META_MAPMODE_ACTION:
+ // FALLTHROUGH intended
+ case META_REFPOINT_ACTION:
+ // FALLTHROUGH intended
+ default:
+ bNonBitmapActionEncountered = true;
+ break;
+ }
+ if ( pModAct )
+ {
+ rOutMtf.ReplaceAction( pModAct, nCurPos );
+ pAct->Delete();
+ }
+ else
+ {
+ if( pAct->GetRefCount() > 1 )
+ {
+ rOutMtf.ReplaceAction( pModAct = pAct->Clone(), nCurPos );
+ pAct->Delete();
+ }
+ else
+ pModAct = pAct;
+ }
+ pModAct->Scale( fScaleX, fScaleY );
+ }
+ rOutMtf.SetPrefSize( Size( FRound( aNewSize.Width() * fScaleX ),
+ FRound( aNewSize.Height() * fScaleY ) ) );
+ }
+
+ if( nNumBitmaps != 1 || bNonBitmapActionEncountered )
+ {
+ if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsMirrored() || rAttr.IsRotated() || rAttr.IsTransparent() )
+ ImplAdjust( rOutMtf, rAttr, ADJUSTMENT_ALL );
+
+ ImplDraw( pOut, rPt, rSz, rOutMtf, rAttr );
+ rOutBmpEx = BitmapEx();
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateScaled( const BitmapEx& rBmpEx,
+ long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY,
+ long nStartX, long nEndX, long nStartY, long nEndY,
+ BitmapEx& rOutBmpEx )
+{
+ Bitmap aBmp( rBmpEx.GetBitmap() );
+ Bitmap aOutBmp;
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ BitmapWriteAccess* pWAcc;
+ BitmapColor aCol0, aCol1, aColRes;
+ const long nDstW = nEndX - nStartX + 1L;
+ const long nDstH = nEndY - nStartY + 1L;
+ long nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY;
+ long nXDst, nYDst;
+ BYTE cR0, cG0, cB0, cR1, cG1, cB1;
+ BOOL bRet = FALSE;
+
+ DBG_ASSERT( aBmp.GetSizePixel() == rBmpEx.GetSizePixel(),
+ "GraphicManager::ImplCreateScaled(): bmp size inconsistent" );
+
+ if( pAcc )
+ {
+ aOutBmp = Bitmap( Size( nDstW, nDstH ), 24 );
+ pWAcc = aOutBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ if( pAcc->HasPalette() )
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ Scanline pLine0, pLine1;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ const BitmapColor& rCol0 = pAcc->GetPaletteColor( pLine0[ nTmpX ] );
+ const BitmapColor& rCol2 = pAcc->GetPaletteColor( pLine1[ nTmpX ] );
+ const BitmapColor& rCol1 = pAcc->GetPaletteColor( pLine0[ ++nTmpX ] );
+ const BitmapColor& rCol3 = pAcc->GetPaletteColor( pLine1[ nTmpX ] );
+
+ cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
+ cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );
+
+ cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
+ cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
+ cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ else
+ {
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ], nTmpFY = pMapFY[ nY ];
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ aCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, nTmpX ) );
+ aCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, ++nTmpX ) );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( ++nTmpY, nTmpX ) );
+ aCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY--, --nTmpX ) );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ }
+ else
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ Scanline pLine0, pLine1, pTmp0, pTmp1;
+ long nOff;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nOff = 3L * ( nTmpX = pMapIX[ nX ] );
+ nTmpFX = pMapFX[ nX ];
+
+ pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
+ cB0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cR0 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
+ cB1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cR1 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
+ {
+ Scanline pLine0, pLine1, pTmp0, pTmp1;
+ long nOff;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nOff = 3L * ( nTmpX = pMapIX[ nX ] );
+ nTmpFX = pMapFX[ nX ];
+
+ pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
+ cR0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cB0 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
+ cR1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cB1 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ else
+ {
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ aCol0 = pAcc->GetPixel( nTmpY, nTmpX );
+ aCol1 = pAcc->GetPixel( nTmpY, ++nTmpX );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pAcc->GetPixel( ++nTmpY, nTmpX );
+ aCol0 = pAcc->GetPixel( nTmpY--, --nTmpX );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ }
+
+ aOutBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ }
+
+ if( bRet && rBmpEx.IsTransparent() )
+ {
+ bRet = FALSE;
+
+ if( rBmpEx.IsAlpha() )
+ {
+ DBG_ASSERT( rBmpEx.GetAlpha().GetSizePixel() == rBmpEx.GetSizePixel(),
+ "GraphicManager::ImplCreateScaled(): alpha mask size inconsistent" );
+
+ AlphaMask aAlpha( rBmpEx.GetAlpha() );
+ AlphaMask aOutAlpha;
+
+ pAcc = aAlpha.AcquireReadAccess();
+
+ if( pAcc )
+ {
+ aOutAlpha = AlphaMask( Size( nDstW, nDstH ) );
+ pWAcc = aOutAlpha.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
+ pWAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ Scanline pLine0, pLine1, pLineW;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+ pLineW = pWAcc->GetScanline( nYDst );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++, nXDst++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ const long nAlpha0 = pLine0[ nTmpX ];
+ const long nAlpha2 = pLine1[ nTmpX ];
+ const long nAlpha1 = pLine0[ ++nTmpX ];
+ const long nAlpha3 = pLine1[ nTmpX ];
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ *pLineW++ = MAP( n0, n1, nTmpFY );
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aAlphaValue( 0 );
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ], nTmpFY = pMapFY[ nY ];
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ long nAlpha0 = pAcc->GetPixel( nTmpY, nTmpX ).GetIndex();
+ long nAlpha1 = pAcc->GetPixel( nTmpY, ++nTmpX ).GetIndex();
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+
+ nAlpha1 = pAcc->GetPixel( ++nTmpY, nTmpX ).GetIndex();
+ nAlpha0 = pAcc->GetPixel( nTmpY--, --nTmpX ).GetIndex();
+ const long n1 = MAP( nAlpha0, nAlpha1, nTmpFX );
+
+ aAlphaValue.SetIndex( MAP( n0, n1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aAlphaValue );
+ }
+ }
+ }
+
+ aOutAlpha.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aAlpha.ReleaseAccess( pAcc );
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
+ }
+ }
+ else
+ {
+ DBG_ASSERT( rBmpEx.GetMask().GetSizePixel() == rBmpEx.GetSizePixel(),
+ "GraphicManager::ImplCreateScaled(): mask size inconsistent" );
+
+ Bitmap aMsk( rBmpEx.GetMask() );
+ Bitmap aOutMsk;
+
+ pAcc = aMsk.AcquireReadAccess();
+
+ if( pAcc )
+ {
+ // #i40115# Use the same palette for destination
+ // bitmap. Otherwise, we'd have to color-map even the
+ // case below, when both masks are one bit deep.
+ if( pAcc->HasPalette() )
+ aOutMsk = Bitmap( Size( nDstW, nDstH ),
+ 1,
+ &pAcc->GetPalette() );
+ else
+ aOutMsk = Bitmap( Size( nDstW, nDstH ), 1 );
+
+ pWAcc = aOutMsk.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ long* pMapLX = new long[ nDstW ];
+ long* pMapLY = new long[ nDstH ];
+
+ // create new horizontal mapping table
+ for( nX = 0UL, nTmpX = nStartX; nX < nDstW; nTmpX++ )
+ pMapLX[ nX++ ] = FRound( (double) pMapIX[ nTmpX ] + pMapFX[ nTmpX ] / 1048576. );
+
+ // create new vertical mapping table
+ for( nY = 0UL, nTmpY = nStartY; nY < nDstH; nTmpY++ )
+ pMapLY[ nY++ ] = FRound( (double) pMapIY[ nTmpY ] + pMapFY[ nTmpY ] / 1048576. );
+
+ // do normal scaling
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ pWAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL )
+ {
+ // optimized
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ Scanline pSrc = pAcc->GetScanline( pMapLY[ nY ] );
+ Scanline pDst = pWAcc->GetScanline( nY );
+
+ for( nX = 0L; nX < nDstW; nX++ )
+ {
+ const long nSrcX = pMapLX[ nX ];
+
+ if( pSrc[ nSrcX >> 3 ] & ( 1 << ( 7 - ( nSrcX & 7 ) ) ) )
+ pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
+ else
+ pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
+ }
+ }
+ }
+ else
+ {
+ const BitmapColor aB( pAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWB( pWAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWW( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ if( pAcc->HasPalette() )
+ {
+ for( nY = 0L; nY < nDstH; nY++ )
+ {
+ for( nX = 0L; nX < nDstW; nX++ )
+ {
+ if( pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( pMapLY[ nY ], pMapLX[ nX ] ) ) == aB )
+ pWAcc->SetPixel( nY, nX, aWB );
+ else
+ pWAcc->SetPixel( nY, nX, aWW );
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nDstH; nY++ )
+ {
+ for( nX = 0L; nX < nDstW; nX++ )
+ {
+ if( pAcc->GetPixel( pMapLY[ nY ], pMapLX[ nX ] ) == aB )
+ pWAcc->SetPixel( nY, nX, aWB );
+ else
+ pWAcc->SetPixel( nY, nX, aWW );
+ }
+ }
+ }
+ }
+
+ delete[] pMapLX;
+ delete[] pMapLY;
+ aOutMsk.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aMsk.ReleaseAccess( pAcc );
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
+ }
+ }
+
+ if( !bRet )
+ rOutBmpEx = aOutBmp;
+ }
+ else
+ rOutBmpEx = aOutBmp;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateRotatedScaled( const BitmapEx& rBmpEx,
+ USHORT nRot10, const Size& /*rOutSzPix*/, const Size& rUnrotatedSzPix,
+ long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY,
+ long nStartX, long nEndX, long nStartY, long nEndY,
+ BitmapEx& rOutBmpEx )
+{
+ Point aPt;
+ Bitmap aBmp( rBmpEx.GetBitmap() );
+ Bitmap aOutBmp;
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ BitmapWriteAccess* pWAcc;
+ Polygon aPoly( Rectangle( aPt, rUnrotatedSzPix ) ); aPoly.Rotate( Point(), nRot10 );
+ Rectangle aNewBound( aPoly.GetBoundRect() );
+ const double fCosAngle = cos( nRot10 * F_PI1800 ), fSinAngle = sin( nRot10 * F_PI1800 );
+ double fTmp;
+ const long nDstW = nEndX - nStartX + 1L;
+ const long nDstH = nEndY - nStartY + 1L;
+ const long nUnRotW = rUnrotatedSzPix.Width();
+ const long nUnRotH = rUnrotatedSzPix.Height();
+ long* pCosX = new long[ nDstW ];
+ long* pSinX = new long[ nDstW ];
+ long* pCosY = new long[ nDstH ];
+ long* pSinY = new long[ nDstH ];
+ long nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY, nUnRotX, nUnRotY, nSinY, nCosY;
+ BYTE cR0, cG0, cB0, cR1, cG1, cB1;
+ BOOL bRet = FALSE;
+
+ // create horizontal mapping table
+ for( nX = 0L, nTmpX = aNewBound.Left() + nStartX; nX < nDstW; nX++ )
+ {
+ pCosX[ nX ] = FRound( fCosAngle * ( fTmp = nTmpX++ << 8 ) );
+ pSinX[ nX ] = FRound( fSinAngle * fTmp );
+ }
+
+ // create vertical mapping table
+ for( nY = 0L, nTmpY = aNewBound.Top() + nStartY; nY < nDstH; nY++ )
+ {
+ pCosY[ nY ] = FRound( fCosAngle * ( fTmp = nTmpY++ << 8 ) );
+ pSinY[ nY ] = FRound( fSinAngle * fTmp );
+ }
+
+ if( pAcc )
+ {
+ aOutBmp = Bitmap( Size( nDstW, nDstH ), 24 );
+ pWAcc = aOutBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ BitmapColor aColRes;
+
+ if( pAcc->HasPalette() )
+ {
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ const BitmapColor& rCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, nTmpX ) );
+ const BitmapColor& rCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, ++nTmpX ) );
+ cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
+ cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );
+
+ const BitmapColor& rCol3 = pAcc->GetPaletteColor( pAcc->GetPixel( ++nTmpY, nTmpX ) );
+ const BitmapColor& rCol2 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, --nTmpX ) );
+ cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
+ cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
+ cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nY, nX, aColRes );
+ }
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol0, aCol1;
+
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ aCol0 = pAcc->GetPixel( nTmpY, nTmpX );
+ aCol1 = pAcc->GetPixel( nTmpY, ++nTmpX );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pAcc->GetPixel( ++nTmpY, nTmpX );
+ aCol0 = pAcc->GetPixel( nTmpY, --nTmpX );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nY, nX, aColRes );
+ }
+ }
+ }
+ }
+
+ aOutBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ }
+
+ // mask processing
+ if( bRet && ( rBmpEx.IsTransparent() || ( nRot10 != 900 && nRot10 != 1800 && nRot10 != 2700 ) ) )
+ {
+ bRet = FALSE;
+
+ if( rBmpEx.IsAlpha() )
+ {
+ AlphaMask aAlpha( rBmpEx.GetAlpha() );
+ AlphaMask aOutAlpha;
+
+ pAcc = aAlpha.AcquireReadAccess();
+
+ if( pAcc )
+ {
+ aOutAlpha = AlphaMask( Size( nDstW, nDstH ) );
+ pWAcc = aOutAlpha.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
+ pWAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ Scanline pLine0, pLine1, pLineW;
+
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
+ pLineW = pWAcc->GetScanline( nY );
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ], nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ pLine0 = pAcc->GetScanline( nTmpY++ );
+ pLine1 = pAcc->GetScanline( nTmpY );
+
+ const long nAlpha0 = pLine0[ nTmpX ];
+ const long nAlpha2 = pLine1[ nTmpX++ ];
+ const long nAlpha1 = pLine0[ nTmpX ];
+ const long nAlpha3 = pLine1[ nTmpX ];
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ *pLineW++ = MAP( n0, n1, nTmpFY );
+ }
+ else
+ *pLineW++ = 255;
+ }
+ }
+ }
+ else
+ {
+ const BitmapColor aTrans( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapColor aAlphaVal( 0 );
+
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ const long nAlpha0 = pAcc->GetPixel( nTmpY, nTmpX ).GetIndex();
+ const long nAlpha1 = pAcc->GetPixel( nTmpY, ++nTmpX ).GetIndex();
+ const long nAlpha3 = pAcc->GetPixel( ++nTmpY, nTmpX ).GetIndex();
+ const long nAlpha2 = pAcc->GetPixel( nTmpY, --nTmpX ).GetIndex();
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ aAlphaVal.SetIndex( MAP( n0, n1, nTmpFY ) );
+ pWAcc->SetPixel( nY, nX, aAlphaVal );
+ }
+ else
+ pWAcc->SetPixel( nY, nX, aTrans );
+ }
+ }
+ }
+
+ aOutAlpha.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aAlpha.ReleaseAccess( pAcc );
+ }
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
+ }
+ else
+ {
+ Bitmap aOutMsk( Size( nDstW, nDstH ), 1 );
+ pWAcc = aOutMsk.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ Bitmap aMsk( rBmpEx.GetMask() );
+ const BitmapColor aB( pWAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aW( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapReadAccess* pMAcc = NULL;
+
+ if( !aMsk || ( ( pMAcc = aMsk.AcquireReadAccess() ) != NULL ) )
+ {
+ long* pMapLX = new long[ nUnRotW ];
+ long* pMapLY = new long[ nUnRotH ];
+ BitmapColor aTestB;
+
+ if( pMAcc )
+ aTestB = pMAcc->GetBestMatchingColor( Color( COL_BLACK ) );
+
+ // create new horizontal mapping table
+ for( nX = 0UL; nX < nUnRotW; nX++ )
+ pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576. );
+
+ // create new vertical mapping table
+ for( nY = 0UL; nY < nUnRotH; nY++ )
+ pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576. );
+
+ // do mask rotation
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ if( pMAcc )
+ {
+ if( pMAcc->GetPixel( pMapLY[ nUnRotY ], pMapLX[ nUnRotX ] ) == aTestB )
+ pWAcc->SetPixel( nY, nX, aB );
+ else
+ pWAcc->SetPixel( nY, nX, aW );
+ }
+ else
+ pWAcc->SetPixel( nY, nX, aB );
+ }
+ else
+ pWAcc->SetPixel( nY, nX, aW );
+ }
+ }
+
+ delete[] pMapLX;
+ delete[] pMapLY;
+
+ if( pMAcc )
+ aMsk.ReleaseAccess( pMAcc );
+
+ bRet = TRUE;
+ }
+
+ aOutMsk.ReleaseAccess( pWAcc );
+ }
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
+ }
+
+ if( !bRet )
+ rOutBmpEx = aOutBmp;
+ }
+ else
+ rOutBmpEx = aOutBmp;
+
+ delete[] pSinX;
+ delete[] pCosX;
+ delete[] pSinY;
+ delete[] pCosY;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, ULONG nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case( GRAPHICDRAWMODE_MONO ):
+ rBmpEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+ break;
+
+ case( GRAPHICDRAWMODE_GREYS ):
+ rBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );
+ break;
+
+ case( GRAPHICDRAWMODE_WATERMARK ):
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
+ {
+ rBmpEx.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
+ {
+ rBmpEx.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
+ {
+ rBmpEx.Rotate( aAttr.GetRotation(), Color( COL_TRANSPARENT ) );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ AlphaMask aAlpha;
+ BYTE cTrans = aAttr.GetTransparency();
+
+ if( !rBmpEx.IsTransparent() )
+ aAlpha = AlphaMask( rBmpEx.GetSizePixel(), &cTrans );
+ else if( !rBmpEx.IsAlpha() )
+ {
+ aAlpha = rBmpEx.GetMask();
+ aAlpha.Replace( 0, cTrans );
+ }
+ else
+ {
+ aAlpha = rBmpEx.GetAlpha();
+ BitmapWriteAccess* pA = aAlpha.AcquireWriteAccess();
+
+ if( pA )
+ {
+ ULONG nTrans = cTrans, nNewTrans;
+ const long nWidth = pA->Width(), nHeight = pA->Height();
+
+ if( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ Scanline pAScan = pA->GetScanline( nY );
+
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ nNewTrans = nTrans + *pAScan;
+ *pAScan++ = (BYTE) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans );
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aAlphaValue( 0 );
+
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ nNewTrans = nTrans + pA->GetPixel( nY, nX ).GetIndex();
+ aAlphaValue.SetIndex( (BYTE) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans ) );
+ pA->SetPixel( nY, nX, aAlphaValue );
+ }
+ }
+ }
+
+ aAlpha.ReleaseAccess( pA );
+ }
+ }
+
+ rBmpEx = BitmapEx( rBmpEx.GetBitmap(), aAlpha );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, ULONG nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case( GRAPHICDRAWMODE_MONO ):
+ rMtf.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
+ break;
+
+ case( GRAPHICDRAWMODE_GREYS ):
+ rMtf.Convert( MTF_CONVERSION_8BIT_GREYS );
+ break;
+
+ case( GRAPHICDRAWMODE_WATERMARK ):
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
+ {
+ rMtf.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
+ {
+ rMtf.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
+ {
+ rMtf.Rotate( aAttr.GetRotation() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ DBG_ERROR( "Missing implementation: Mtf-Transparency" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, ULONG nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case( GRAPHICDRAWMODE_MONO ):
+ rAnimation.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+ break;
+
+ case( GRAPHICDRAWMODE_GREYS ):
+ rAnimation.Convert( BMP_CONVERSION_8BIT_GREYS );
+ break;
+
+ case( GRAPHICDRAWMODE_WATERMARK ):
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
+ {
+ rAnimation.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
+ {
+ rAnimation.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
+ {
+ DBG_ERROR( "Missing implementation: Animation-Rotation" );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ DBG_ERROR( "Missing implementation: Animation-Transparency" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GDIMetaFile& rMtf, const GraphicAttr& rAttr )
+{
+ USHORT nRot10 = rAttr.GetRotation() % 3600;
+ Point aOutPt( rPt );
+ Size aOutSz( rSz );
+
+ if( nRot10 )
+ {
+ Polygon aPoly( Rectangle( aOutPt, aOutSz ) );
+
+ aPoly.Rotate( aOutPt, nRot10 );
+ const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
+ aOutPt = aRotBoundRect.TopLeft();
+ aOutSz = aRotBoundRect.GetSize();
+ }
+
+ pOut->Push( PUSH_CLIPREGION );
+ pOut->IntersectClipRegion( Rectangle( aOutPt, aOutSz ) );
+
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( pOut, aOutPt, aOutSz );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+
+ pOut->Pop();
+}
+
+// -----------------------------------------------------------------------------
+
+struct ImplTileInfo
+{
+ ImplTileInfo() : aTileTopLeft(), aNextTileTopLeft(), aTileSizePixel(), nTilesEmptyX(0), nTilesEmptyY(0) {}
+
+ Point aTileTopLeft; // top, left position of the rendered tile
+ Point aNextTileTopLeft; // top, left position for next recursion
+ // level's tile
+ Size aTileSizePixel; // size of the generated tile (might
+ // differ from
+ // aNextTileTopLeft-aTileTopLeft, because
+ // this is nExponent*prevTileSize. The
+ // generated tile is always nExponent
+ // times the previous tile, such that it
+ // can be used in the next stage. The
+ // required area coverage is often
+ // less. The extraneous area covered is
+ // later overwritten by the next stage)
+ int nTilesEmptyX; // number of original tiles empty right of
+ // this tile. This counts from
+ // aNextTileTopLeft, i.e. the additional
+ // area covered by aTileSizePixel is not
+ // considered here. This is for
+ // unification purposes, as the iterative
+ // calculation of the next level's empty
+ // tiles has to be based on this value.
+ int nTilesEmptyY; // as above, for Y
+};
+
+
+bool GraphicObject::ImplRenderTempTile( VirtualDevice& rVDev, int nExponent,
+ int nNumTilesX, int nNumTilesY,
+ const Size& rTileSizePixel,
+ const GraphicAttr* pAttr, ULONG nFlags )
+{
+ if( nExponent <= 1 )
+ return false;
+
+ // determine MSB factor
+ int nMSBFactor( 1 );
+ while( nNumTilesX / nMSBFactor != 0 ||
+ nNumTilesY / nMSBFactor != 0 )
+ {
+ nMSBFactor *= nExponent;
+ }
+
+ // one less
+ nMSBFactor /= nExponent;
+
+ ImplTileInfo aTileInfo;
+
+ // #105229# Switch off mapping (converting to logic and back to
+ // pixel might cause roundoff errors)
+ BOOL bOldMap( rVDev.IsMapModeEnabled() );
+ rVDev.EnableMapMode( FALSE );
+
+ bool bRet( ImplRenderTileRecursive( rVDev, nExponent, nMSBFactor, nNumTilesX, nNumTilesY,
+ nNumTilesX, nNumTilesY, rTileSizePixel, pAttr, nFlags, aTileInfo ) );
+
+ rVDev.EnableMapMode( bOldMap );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// define for debug drawings
+//#define DBG_TEST
+
+// see header comment. this works similar to base conversion of a
+// number, i.e. if the exponent is 10, then the number for every tile
+// size is given by the decimal place of the corresponding decimal
+// representation.
+bool GraphicObject::ImplRenderTileRecursive( VirtualDevice& rVDev, int nExponent, int nMSBFactor,
+ int nNumOrigTilesX, int nNumOrigTilesY,
+ int nRemainderTilesX, int nRemainderTilesY,
+ const Size& rTileSizePixel, const GraphicAttr* pAttr,
+ ULONG nFlags, ImplTileInfo& rTileInfo )
+{
+ // gets loaded with our tile bitmap
+ GraphicObject aTmpGraphic;
+
+ // stores a flag that renders the zero'th tile position
+ // (i.e. (0,0)+rCurrPos) only if we're at the bottom of the
+ // recursion stack. All other position already have that tile
+ // rendered, because the lower levels painted their generated tile
+ // there.
+ bool bNoFirstTileDraw( false );
+
+ // what's left when we're done with our tile size
+ const int nNewRemainderX( nRemainderTilesX % nMSBFactor );
+ const int nNewRemainderY( nRemainderTilesY % nMSBFactor );
+
+ // gets filled out from the recursive call with info of what's
+ // been generated
+ ImplTileInfo aTileInfo;
+
+ // current output position while drawing
+ Point aCurrPos;
+ int nX, nY;
+
+ // check for recursion's end condition: LSB place reached?
+ if( nMSBFactor == 1 )
+ {
+ aTmpGraphic = *this;
+
+ // set initial tile size -> orig size
+ aTileInfo.aTileSizePixel = rTileSizePixel;
+ aTileInfo.nTilesEmptyX = nNumOrigTilesX;
+ aTileInfo.nTilesEmptyY = nNumOrigTilesY;
+ }
+ else if( ImplRenderTileRecursive( rVDev, nExponent, nMSBFactor/nExponent,
+ nNumOrigTilesX, nNumOrigTilesY,
+ nNewRemainderX, nNewRemainderY,
+ rTileSizePixel, pAttr, nFlags, aTileInfo ) )
+ {
+ // extract generated tile -> see comment on the first loop below
+ BitmapEx aTileBitmap( rVDev.GetBitmap( aTileInfo.aTileTopLeft, aTileInfo.aTileSizePixel ) );
+
+ aTmpGraphic = GraphicObject( aTileBitmap );
+
+ // fill stripes left over from upstream levels:
+ //
+ // x0000
+ // 0
+ // 0
+ // 0
+ // 0
+ //
+ // where x denotes the place filled by our recursive predecessors
+
+ // check whether we have to fill stripes here. Although not
+ // obvious, there is one case where we can skip this step: if
+ // the previous recursion level (the one who filled our
+ // aTileInfo) had zero area to fill, then there are no white
+ // stripes left, naturally. This happens if the digit
+ // associated to that level has a zero, and can be checked via
+ // aTileTopLeft==aNextTileTopLeft.
+ if( aTileInfo.aTileTopLeft != aTileInfo.aNextTileTopLeft )
+ {
+ // now fill one row from aTileInfo.aNextTileTopLeft.X() all
+ // the way to the right
+ aCurrPos.X() = aTileInfo.aNextTileTopLeft.X();
+ aCurrPos.Y() = aTileInfo.aTileTopLeft.Y();
+ for( nX=0; nX < aTileInfo.nTilesEmptyX; nX += nMSBFactor )
+ {
+ if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
+ return false;
+
+ aCurrPos.X() += aTileInfo.aTileSizePixel.Width();
+ }
+
+#ifdef DBG_TEST
+// rVDev.SetFillColor( COL_WHITE );
+ rVDev.SetFillColor();
+ rVDev.SetLineColor( Color( 255 * nExponent / nMSBFactor, 255 - 255 * nExponent / nMSBFactor, 128 - 255 * nExponent / nMSBFactor ) );
+ rVDev.DrawEllipse( Rectangle(aTileInfo.aNextTileTopLeft.X(), aTileInfo.aTileTopLeft.Y(),
+ aTileInfo.aNextTileTopLeft.X() - 1 + (aTileInfo.nTilesEmptyX/nMSBFactor)*aTileInfo.aTileSizePixel.Width(),
+ aTileInfo.aTileTopLeft.Y() + aTileInfo.aTileSizePixel.Height() - 1) );
+#endif
+
+ // now fill one column from aTileInfo.aNextTileTopLeft.Y() all
+ // the way to the bottom
+ aCurrPos.X() = aTileInfo.aTileTopLeft.X();
+ aCurrPos.Y() = aTileInfo.aNextTileTopLeft.Y();
+ for( nY=0; nY < aTileInfo.nTilesEmptyY; nY += nMSBFactor )
+ {
+ if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
+ return false;
+
+ aCurrPos.Y() += aTileInfo.aTileSizePixel.Height();
+ }
+
+#ifdef DBG_TEST
+ rVDev.DrawEllipse( Rectangle(aTileInfo.aTileTopLeft.X(), aTileInfo.aNextTileTopLeft.Y(),
+ aTileInfo.aTileTopLeft.X() + aTileInfo.aTileSizePixel.Width() - 1,
+ aTileInfo.aNextTileTopLeft.Y() - 1 + (aTileInfo.nTilesEmptyY/nMSBFactor)*aTileInfo.aTileSizePixel.Height()) );
+#endif
+ }
+ else
+ {
+ // Thought that aTileInfo.aNextTileTopLeft tile has always
+ // been drawn already, but that's wrong: typically,
+ // _parts_ of that tile have been drawn, since the
+ // previous level generated the tile there. But when
+ // aTileInfo.aNextTileTopLeft!=aTileInfo.aTileTopLeft, the
+ // difference between these two values is missing in the
+ // lower right corner of this first tile. So, can do that
+ // only here.
+ bNoFirstTileDraw = true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ // calc number of original tiles in our drawing area without
+ // remainder
+ nRemainderTilesX -= nNewRemainderX;
+ nRemainderTilesY -= nNewRemainderY;
+
+ // fill tile info for calling method
+ rTileInfo.aTileTopLeft = aTileInfo.aNextTileTopLeft;
+ rTileInfo.aNextTileTopLeft = Point( rTileInfo.aTileTopLeft.X() + rTileSizePixel.Width()*nRemainderTilesX,
+ rTileInfo.aTileTopLeft.Y() + rTileSizePixel.Height()*nRemainderTilesY );
+ rTileInfo.aTileSizePixel = Size( rTileSizePixel.Width()*nMSBFactor*nExponent,
+ rTileSizePixel.Height()*nMSBFactor*nExponent );
+ rTileInfo.nTilesEmptyX = aTileInfo.nTilesEmptyX - nRemainderTilesX;
+ rTileInfo.nTilesEmptyY = aTileInfo.nTilesEmptyY - nRemainderTilesY;
+
+ // init output position
+ aCurrPos = aTileInfo.aNextTileTopLeft;
+
+ // fill our drawing area. Fill possibly more, to create the next
+ // bigger tile size -> see bitmap extraction above. This does no
+ // harm, since everything right or below our actual area is
+ // overdrawn by our caller. Just in case we're in the last level,
+ // we don't draw beyond the right or bottom border.
+ for( nY=0; nY < aTileInfo.nTilesEmptyY && nY < nExponent*nMSBFactor; nY += nMSBFactor )
+ {
+ aCurrPos.X() = aTileInfo.aNextTileTopLeft.X();
+
+ for( nX=0; nX < aTileInfo.nTilesEmptyX && nX < nExponent*nMSBFactor; nX += nMSBFactor )
+ {
+ if( bNoFirstTileDraw )
+ bNoFirstTileDraw = false; // don't draw first tile position
+ else if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
+ return false;
+
+ aCurrPos.X() += aTileInfo.aTileSizePixel.Width();
+ }
+
+ aCurrPos.Y() += aTileInfo.aTileSizePixel.Height();
+ }
+
+#ifdef DBG_TEST
+// rVDev.SetFillColor( COL_WHITE );
+ rVDev.SetFillColor();
+ rVDev.SetLineColor( Color( 255 * nExponent / nMSBFactor, 255 - 255 * nExponent / nMSBFactor, 128 - 255 * nExponent / nMSBFactor ) );
+ rVDev.DrawRect( Rectangle((rTileInfo.aTileTopLeft.X())*rTileSizePixel.Width(),
+ (rTileInfo.aTileTopLeft.Y())*rTileSizePixel.Height(),
+ (rTileInfo.aNextTileTopLeft.X())*rTileSizePixel.Width()-1,
+ (rTileInfo.aNextTileTopLeft.Y())*rTileSizePixel.Height()-1) );
+#endif
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+bool GraphicObject::ImplDrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSizePixel,
+ const Size& rOffset, const GraphicAttr* pAttr, ULONG nFlags, int nTileCacheSize1D )
+{
+ // how many tiles to generate per recursion step
+ enum{ SubdivisionExponent=2 };
+
+ const MapMode aOutMapMode( pOut->GetMapMode() );
+ const MapMode aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
+ bool bRet( false );
+
+ // #i42643# Casting to Int64, to avoid integer overflow for
+ // huge-DPI output devices
+ if( GetGraphic().GetType() == GRAPHIC_BITMAP &&
+ static_cast<sal_Int64>(rSizePixel.Width()) * rSizePixel.Height() <
+ static_cast<sal_Int64>(nTileCacheSize1D)*nTileCacheSize1D )
+ {
+ // First combine very small bitmaps into a larger tile
+ // ===================================================
+
+ VirtualDevice aVDev;
+ const int nNumTilesInCacheX( (nTileCacheSize1D + rSizePixel.Width()-1) / rSizePixel.Width() );
+ const int nNumTilesInCacheY( (nTileCacheSize1D + rSizePixel.Height()-1) / rSizePixel.Height() );
+
+ aVDev.SetOutputSizePixel( Size( nNumTilesInCacheX*rSizePixel.Width(),
+ nNumTilesInCacheY*rSizePixel.Height() ) );
+ aVDev.SetMapMode( aMapMode );
+
+ // draw bitmap content
+ if( ImplRenderTempTile( aVDev, SubdivisionExponent, nNumTilesInCacheX,
+ nNumTilesInCacheY, rSizePixel, pAttr, nFlags ) )
+ {
+ BitmapEx aTileBitmap( aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ) );
+
+ // draw alpha content, if any
+ if( IsTransparent() )
+ {
+ GraphicObject aAlphaGraphic;
+
+ if( GetGraphic().IsAlpha() )
+ aAlphaGraphic.SetGraphic( GetGraphic().GetBitmapEx().GetAlpha().GetBitmap() );
+ else
+ aAlphaGraphic.SetGraphic( GetGraphic().GetBitmapEx().GetMask() );
+
+ if( aAlphaGraphic.ImplRenderTempTile( aVDev, SubdivisionExponent, nNumTilesInCacheX,
+ nNumTilesInCacheY, rSizePixel, pAttr, nFlags ) )
+ {
+ // Combine bitmap and alpha/mask
+ if( GetGraphic().IsAlpha() )
+ aTileBitmap = BitmapEx( aTileBitmap.GetBitmap(),
+ AlphaMask( aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ) ) );
+ else
+ aTileBitmap = BitmapEx( aTileBitmap.GetBitmap(),
+ aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ).CreateMask( Color(COL_WHITE) ) );
+ }
+ }
+
+ // paint generated tile
+ GraphicObject aTmpGraphic( aTileBitmap );
+ bRet = aTmpGraphic.ImplDrawTiled( pOut, rArea,
+ aTileBitmap.GetSizePixel(),
+ rOffset, pAttr, nFlags, nTileCacheSize1D );
+ }
+ }
+ else
+ {
+ const Size aOutOffset( pOut->LogicToPixel( rOffset, aOutMapMode ) );
+ const Rectangle aOutArea( pOut->LogicToPixel( rArea, aOutMapMode ) );
+
+ // number of invisible (because out-of-area) tiles
+ int nInvisibleTilesX;
+ int nInvisibleTilesY;
+
+ // round towards -infty for negative offset
+ if( aOutOffset.Width() < 0 )
+ nInvisibleTilesX = (aOutOffset.Width() - rSizePixel.Width() + 1) / rSizePixel.Width();
+ else
+ nInvisibleTilesX = aOutOffset.Width() / rSizePixel.Width();
+
+ // round towards -infty for negative offset
+ if( aOutOffset.Height() < 0 )
+ nInvisibleTilesY = (aOutOffset.Height() - rSizePixel.Height() + 1) / rSizePixel.Height();
+ else
+ nInvisibleTilesY = aOutOffset.Height() / rSizePixel.Height();
+
+ // origin from where to 'virtually' start drawing in pixel
+ const Point aOutOrigin( pOut->LogicToPixel( Point( rArea.Left() - rOffset.Width(),
+ rArea.Top() - rOffset.Height() ) ) );
+ // position in pixel from where to really start output
+ const Point aOutStart( aOutOrigin.X() + nInvisibleTilesX*rSizePixel.Width(),
+ aOutOrigin.Y() + nInvisibleTilesY*rSizePixel.Height() );
+
+ pOut->Push( PUSH_CLIPREGION );
+ pOut->IntersectClipRegion( rArea );
+
+ // Paint all tiles
+ // ===============
+
+ bRet = ImplDrawTiled( *pOut, aOutStart,
+ (aOutArea.GetWidth() + aOutArea.Left() - aOutStart.X() + rSizePixel.Width() - 1) / rSizePixel.Width(),
+ (aOutArea.GetHeight() + aOutArea.Top() - aOutStart.Y() + rSizePixel.Height() - 1) / rSizePixel.Height(),
+ rSizePixel, pAttr, nFlags );
+
+ pOut->Pop();
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+bool GraphicObject::ImplDrawTiled( OutputDevice& rOut, const Point& rPosPixel,
+ int nNumTilesX, int nNumTilesY,
+ const Size& rTileSizePixel, const GraphicAttr* pAttr, ULONG nFlags )
+{
+ Point aCurrPos( rPosPixel );
+ Size aTileSizeLogic( rOut.PixelToLogic( rTileSizePixel ) );
+ int nX, nY;
+
+ // #107607# Use logical coordinates for metafile playing, too
+ bool bDrawInPixel( rOut.GetConnectMetaFile() == NULL && GRAPHIC_BITMAP == GetType() );
+ BOOL bRet( FALSE );
+
+ // #105229# Switch off mapping (converting to logic and back to
+ // pixel might cause roundoff errors)
+ BOOL bOldMap( rOut.IsMapModeEnabled() );
+
+ if( bDrawInPixel )
+ rOut.EnableMapMode( FALSE );
+
+ for( nY=0; nY < nNumTilesY; ++nY )
+ {
+ aCurrPos.X() = rPosPixel.X();
+
+ for( nX=0; nX < nNumTilesX; ++nX )
+ {
+ // #105229# work with pixel coordinates here, mapping is disabled!
+ // #104004# don't disable mapping for metafile recordings
+ // #108412# don't quit the loop if one draw fails
+
+ // update return value. This method should return true, if
+ // at least one of the looped Draws succeeded.
+ bRet |= Draw( &rOut,
+ bDrawInPixel ? aCurrPos : rOut.PixelToLogic( aCurrPos ),
+ bDrawInPixel ? rTileSizePixel : aTileSizeLogic,
+ pAttr, nFlags );
+
+ aCurrPos.X() += rTileSizePixel.Width();
+ }
+
+ aCurrPos.Y() += rTileSizePixel.Height();
+ }
+
+ if( bDrawInPixel )
+ rOut.EnableMapMode( bOldMap );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplTransformBitmap( BitmapEx& rBmpEx,
+ const GraphicAttr& rAttr,
+ const Size& rCropLeftTop,
+ const Size& rCropRightBottom,
+ const Rectangle& rCropRect,
+ const Size& rDstSize,
+ BOOL bEnlarge ) const
+{
+ // #107947# Extracted from svdograf.cxx
+
+ // #104115# Crop the bitmap
+ if( rAttr.IsCropped() )
+ {
+ rBmpEx.Crop( rCropRect );
+
+ // #104115# Negative crop sizes mean: enlarge bitmap and pad
+ if( bEnlarge && (
+ rCropLeftTop.Width() < 0 ||
+ rCropLeftTop.Height() < 0 ||
+ rCropRightBottom.Width() < 0 ||
+ rCropRightBottom.Height() < 0 ) )
+ {
+ Size aBmpSize( rBmpEx.GetSizePixel() );
+ sal_Int32 nPadLeft( rCropLeftTop.Width() < 0 ? -rCropLeftTop.Width() : 0 );
+ sal_Int32 nPadTop( rCropLeftTop.Height() < 0 ? -rCropLeftTop.Height() : 0 );
+ sal_Int32 nPadTotalWidth( aBmpSize.Width() + nPadLeft + (rCropRightBottom.Width() < 0 ? -rCropRightBottom.Width() : 0) );
+ sal_Int32 nPadTotalHeight( aBmpSize.Height() + nPadTop + (rCropRightBottom.Height() < 0 ? -rCropRightBottom.Height() : 0) );
+
+ BitmapEx aBmpEx2;
+
+ if( rBmpEx.IsTransparent() )
+ {
+ if( rBmpEx.IsAlpha() )
+ aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), rBmpEx.GetAlpha() );
+ else
+ aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), rBmpEx.GetMask() );
+ }
+ else
+ {
+ // #104115# Generate mask bitmap and init to zero
+ Bitmap aMask( aBmpSize, 1 );
+ aMask.Erase( Color(0,0,0) );
+
+ // #104115# Always generate transparent bitmap, we need the border transparent
+ aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), aMask );
+
+ // #104115# Add opaque mask to source bitmap, otherwise the destination remains transparent
+ rBmpEx = aBmpEx2;
+ }
+
+ aBmpEx2.SetSizePixel( Size(nPadTotalWidth, nPadTotalHeight) );
+ aBmpEx2.Erase( Color(0xFF,0,0,0) );
+ aBmpEx2.CopyPixel( Rectangle( Point(nPadLeft, nPadTop), aBmpSize ), Rectangle( Point(0, 0), aBmpSize ), &rBmpEx );
+ rBmpEx = aBmpEx2;
+ }
+ }
+
+ const Size aSizePixel( rBmpEx.GetSizePixel() );
+
+ if( rAttr.GetRotation() != 0 && !IsAnimated() )
+ {
+ if( aSizePixel.Width() && aSizePixel.Height() && rDstSize.Width() && rDstSize.Height() )
+ {
+ double fSrcWH = (double) aSizePixel.Width() / aSizePixel.Height();
+ double fDstWH = (double) rDstSize.Width() / rDstSize.Height();
+ double fScaleX = 1.0, fScaleY = 1.0;
+
+ // always choose scaling to shrink bitmap
+ if( fSrcWH < fDstWH )
+ fScaleY = aSizePixel.Width() / ( fDstWH * aSizePixel.Height() );
+ else
+ fScaleX = fDstWH * aSizePixel.Height() / aSizePixel.Width();
+
+ rBmpEx.Scale( fScaleX, fScaleY );
+ }
+ }
+}
+
diff --git a/svtools/source/graphic/makefile.mk b/svtools/source/graphic/makefile.mk
new file mode 100644
index 000000000000..37870b46b80b
--- /dev/null
+++ b/svtools/source/graphic/makefile.mk
@@ -0,0 +1,66 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=graphic
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+.IF "$(GUI)"=="WIN"
+LINKFLAGS=$(LINKFLAGS) /PACKC:32768
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/grfattr.obj \
+ $(SLO)$/grfmgr.obj \
+ $(SLO)$/grfmgr2.obj \
+ $(SLO)$/grfcache.obj \
+ $(SLO)$/descriptor.obj \
+ $(SLO)$/provider.obj \
+ $(SLO)$/graphic.obj \
+ $(SLO)$/renderer.obj \
+ $(SLO)$/graphicunofactory.obj \
+ $(SLO)$/transformer.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/descriptor.obj \
+ $(SLO)$/provider.obj \
+ $(SLO)$/graphic.obj \
+ $(SLO)$/renderer.obj \
+ $(SLO)$/graphicunofactory.obj \
+ $(SLO)$/transformer.obj
+
+# --- Target -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/graphic/provider.cxx b/svtools/source/graphic/provider.cxx
new file mode 100644
index 000000000000..fbf95406a63a
--- /dev/null
+++ b/svtools/source/graphic/provider.cxx
@@ -0,0 +1,861 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/image.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/imagerepository.hxx>
+#include <tools/rcid.h>
+#include <tools/resid.hxx>
+#include <tools/resmgr.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <svtools/filter.hxx>
+#include <svl/solar.hrc>
+#include <vcl/salbtype.hxx>
+#include <vcl/virdev.hxx>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
+
+#include "descriptor.hxx"
+#include "graphic.hxx"
+#include <svtools/grfmgr.hxx>
+#include "provider.hxx"
+
+using namespace com::sun::star;
+
+namespace unographic {
+
+#define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
+
+// -------------------
+// - GraphicProvider -
+// -------------------
+
+uno::Reference< uno::XInterface > SAL_CALL GraphicProvider_CreateInstance( const uno::Reference< lang::XMultiServiceFactory >& )
+{
+ return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicProvider );
+}
+
+GraphicProvider::GraphicProvider()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+GraphicProvider::~GraphicProvider()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString GraphicProvider::getImplementationName_Static()
+ throw()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicProvider" ) );
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > GraphicProvider::getSupportedServiceNames_Static()
+ throw()
+{
+ uno::Sequence< ::rtl::OUString > aSeq( 1 );
+
+ aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) );
+
+ return aSeq;
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL GraphicProvider::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL GraphicProvider::supportsService( const ::rtl::OUString& ServiceName )
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
+ const ::rtl::OUString* pArray = aSNL.getConstArray();
+
+ for( int i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > SAL_CALL GraphicProvider::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< uno::Type > SAL_CALL GraphicProvider::getTypes()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< uno::Type > aTypes( 3 );
+ uno::Type* pTypes = aTypes.getArray();
+
+ *pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< graphic::XGraphicProvider>*)0);
+
+ return aTypes;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< sal_Int8 > SAL_CALL GraphicProvider::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ 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;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadGraphicObject( const ::rtl::OUString& rResourceURL ) const
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ if( rResourceURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 )
+ {
+ // graphic manager url
+ String aTmpStr( rResourceURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 ) );
+ ByteString aUniqueID( aTmpStr, RTL_TEXTENCODING_UTF8 );
+ GraphicObject aGrafObj( aUniqueID );
+ // I don't call aGrafObj.GetXGraphic because it will call us back
+ // into implLoadMemory ( with "private:memorygraphic" test )
+ ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
+ pUnoGraphic->init( aGrafObj.GetGraphic() );
+ xRet = pUnoGraphic;
+ }
+ return xRet;
+}
+
+uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadMemory( const ::rtl::OUString& rResourceURL ) const
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ sal_Int32 nIndex = 0;
+
+ if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:memorygraphic" ) ) )
+ {
+ sal_Int64 nGraphicAddress = rResourceURL.getToken( 0, '/', nIndex ).toInt64();
+
+ if( nGraphicAddress )
+ {
+ ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
+
+ pUnoGraphic->init( *reinterpret_cast< ::Graphic* >( nGraphicAddress ) );
+ xRet = pUnoGraphic;
+ }
+ }
+
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadRepositoryImage( const ::rtl::OUString& rResourceURL ) const
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ sal_Int32 nIndex = 0;
+
+ if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:graphicrepository" ) ) )
+ {
+ String sPathName( rResourceURL.copy( nIndex ) );
+ BitmapEx aBitmap;
+ if ( ::vcl::ImageRepository::loadImage( sPathName, aBitmap, false ) )
+ {
+ Image aImage( aBitmap );
+ xRet = aImage.GetXGraphic();
+ }
+ }
+ return xRet;
+}
+
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadStandardImage( const ::rtl::OUString& rResourceURL ) const
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ sal_Int32 nIndex = 0;
+
+ if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:standardimage" ) ) )
+ {
+ rtl::OUString sImageName( rResourceURL.copy( nIndex ) );
+ if ( sImageName.compareToAscii( "info" ) )
+ {
+ xRet = InfoBox::GetStandardImage().GetXGraphic();
+ }
+ else if ( sImageName.compareToAscii( "warning" ) )
+ {
+ xRet = WarningBox::GetStandardImage().GetXGraphic();
+ }
+ else if ( sImageName.compareToAscii( "error" ) )
+ {
+ xRet = ErrorBox::GetStandardImage().GetXGraphic();
+ }
+ else if ( sImageName.compareToAscii( "query" ) )
+ {
+ xRet = QueryBox::GetStandardImage().GetXGraphic();
+ }
+ }
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadBitmap( const uno::Reference< awt::XBitmap >& xBtm ) const
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ uno::Sequence< sal_Int8 > aBmpSeq( xBtm->getDIB() );
+ uno::Sequence< sal_Int8 > aMaskSeq( xBtm->getMaskDIB() );
+ SvMemoryStream aBmpStream( aBmpSeq.getArray(), aBmpSeq.getLength(), STREAM_READ );
+ Bitmap aBmp;
+ aBmpStream >> aBmp;
+
+ BitmapEx aBmpEx;
+
+ if( aMaskSeq.getLength() )
+ {
+ SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), STREAM_READ );
+ Bitmap aMask;
+ aMaskStream >> aMask;
+ aBmpEx = BitmapEx( aBmp, aMask );
+ }
+ else
+ aBmpEx = BitmapEx( aBmp );
+
+ if( !aBmpEx.IsEmpty() )
+ {
+ ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
+
+ pUnoGraphic->init( aBmpEx );
+ xRet = pUnoGraphic;
+ }
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadResource( const ::rtl::OUString& rResourceURL ) const
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ sal_Int32 nIndex = 0;
+
+ if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:resource" ) ) )
+ {
+ ByteString aResMgrName( String( rResourceURL.getToken( 0, '/', nIndex ) ), RTL_TEXTENCODING_ASCII_US );
+
+ ResMgr* pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+
+ if( pResMgr )
+ {
+ const ::rtl::OUString aResourceType( rResourceURL.getToken( 0, '/', nIndex ) );
+ const ResId aResId( rResourceURL.getToken( 0, '/', nIndex ).toInt32(), *pResMgr );
+
+ if( aResourceType.getLength() )
+ {
+ BitmapEx aBmpEx;
+
+ if( ( 0 == aResourceType.compareToAscii( "bitmap" ) ) ||
+ ( 0 == aResourceType.compareToAscii( "bitmapex" ) ) )
+ {
+ aResId.SetRT( RSC_BITMAP );
+
+ if( pResMgr->IsAvailable( aResId ) )
+ {
+ aBmpEx = BitmapEx( aResId );
+ }
+ }
+ else if( 0 == aResourceType.compareToAscii( "image" ) )
+ {
+ aResId.SetRT( RSC_IMAGE );
+
+ if( pResMgr->IsAvailable( aResId ) )
+ {
+ const Image aImage( aResId );
+ aBmpEx = aImage.GetBitmapEx();
+ }
+ }
+ else if( 0 == aResourceType.compareToAscii( "imagelist" ) )
+ {
+ aResId.SetRT( RSC_IMAGELIST );
+
+ if( pResMgr->IsAvailable( aResId ) )
+ {
+ const ImageList aImageList( aResId );
+ sal_Int32 nImageId = ( nIndex > -1 ) ? rResourceURL.getToken( 0, '/', nIndex ).toInt32() : 0;
+
+ if( 0 < nImageId )
+ {
+ const Image aImage( aImageList.GetImage( sal::static_int_cast< USHORT >(nImageId) ) );
+ aBmpEx = aImage.GetBitmapEx();
+ }
+ else
+ {
+ aBmpEx = aImageList.GetAsHorizontalStrip();
+ }
+ }
+ }
+
+ if( !aBmpEx.IsEmpty() )
+ {
+ ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
+
+ pUnoGraphic->init( aBmpEx );
+ xRet = pUnoGraphic;
+ }
+ }
+
+ delete pResMgr;
+ }
+ }
+
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< beans::XPropertySet > SAL_CALL GraphicProvider::queryGraphicDescriptor( const uno::Sequence< beans::PropertyValue >& rMediaProperties )
+ throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xRet;
+
+ ::rtl::OUString aURL;
+ uno::Reference< io::XInputStream > xIStm;
+ uno::Reference< awt::XBitmap >xBtm;
+
+ for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !xRet.is(); ++i )
+ {
+ const ::rtl::OUString aName( rMediaProperties[ i ].Name );
+ const uno::Any aValue( rMediaProperties[ i ].Value );
+
+ if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) )
+ {
+ aValue >>= aURL;
+ }
+ else if( COMPARE_EQUAL == aName.compareToAscii( "InputStream" ) )
+ {
+ aValue >>= xIStm;
+ }
+ else if( COMPARE_EQUAL == aName.compareToAscii( "Bitmap" ) )
+ {
+ aValue >>= xBtm;
+ }
+ }
+
+ if( xIStm.is() )
+ {
+ GraphicDescriptor* pDescriptor = new GraphicDescriptor;
+ pDescriptor->init( xIStm, aURL );
+ xRet = pDescriptor;
+ }
+ else if( aURL.getLength() )
+ {
+ uno::Reference< ::graphic::XGraphic > xGraphic( implLoadMemory( aURL ) );
+ if( !xGraphic.is() )
+ xGraphic = implLoadResource( aURL );
+ if( !xGraphic.is() )
+ xGraphic = implLoadGraphicObject( aURL );
+
+ if ( !xGraphic.is() )
+ xGraphic = implLoadRepositoryImage( aURL );
+
+ if ( !xGraphic.is() )
+ xGraphic = implLoadStandardImage( aURL );
+
+ if( xGraphic.is() )
+ {
+ xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
+ }
+ else
+ {
+ GraphicDescriptor* pDescriptor = new GraphicDescriptor;
+ pDescriptor->init( aURL );
+ xRet = pDescriptor;
+ }
+ }
+ else if( xBtm.is() )
+ {
+ uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) );
+ if( xGraphic.is() )
+ xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
+ }
+
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( const uno::Sequence< ::beans::PropertyValue >& rMediaProperties )
+ throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Reference< ::graphic::XGraphic > xRet;
+ String aPath;
+ SvStream* pIStm = NULL;
+
+ uno::Reference< io::XInputStream > xIStm;
+ uno::Reference< awt::XBitmap >xBtm;
+
+ for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !pIStm && !xRet.is(); ++i )
+ {
+ const ::rtl::OUString aName( rMediaProperties[ i ].Name );
+ const uno::Any aValue( rMediaProperties[ i ].Value );
+
+ if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) )
+ {
+ ::rtl::OUString aURL;
+ aValue >>= aURL;
+ aPath = aURL;
+ }
+ else if( COMPARE_EQUAL == aName.compareToAscii( "InputStream" ) )
+ {
+ aValue >>= xIStm;
+ }
+ else if( COMPARE_EQUAL == aName.compareToAscii( "Bitmap" ) )
+ {
+ aValue >>= xBtm;
+ }
+ }
+
+ if( xIStm.is() )
+ {
+ pIStm = ::utl::UcbStreamHelper::CreateStream( xIStm );
+ }
+ else if( aPath.Len() )
+ {
+ xRet = implLoadMemory( aPath );
+
+ if( !xRet.is() )
+ xRet = implLoadGraphicObject( aPath );
+
+ if( !xRet.is() )
+ xRet = implLoadResource( aPath );
+
+ if ( !xRet.is() )
+ xRet = implLoadRepositoryImage( aPath );
+
+ if ( !xRet.is() )
+ xRet = implLoadStandardImage( aPath );
+
+ if( !xRet.is() )
+ pIStm = ::utl::UcbStreamHelper::CreateStream( aPath, STREAM_READ );
+ }
+ else if( xBtm.is() )
+ {
+ xRet = implLoadBitmap( xBtm );
+ }
+
+ if( pIStm )
+ {
+ ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter();
+
+ if( pFilter )
+ {
+ ::Graphic aVCLGraphic;
+
+ if( ( pFilter->ImportGraphic( aVCLGraphic, aPath, *pIStm ) == GRFILTER_OK ) &&
+ ( aVCLGraphic.GetType() != GRAPHIC_NONE ) )
+ {
+ ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
+
+ pUnoGraphic->init( aVCLGraphic );
+ xRet = pUnoGraphic;
+ }
+ }
+
+ delete pIStm;
+ }
+
+ return xRet;
+}
+
+void ImplCalculateCropRect( ::Graphic& rGraphic, const text::GraphicCrop& rGraphicCropLogic, Rectangle& rGraphicCropPixel )
+{
+ if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom )
+ {
+ Size aSourceSizePixel( rGraphic.GetSizePixel() );
+ if ( aSourceSizePixel.Width() && aSourceSizePixel.Height() )
+ {
+ if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom )
+ {
+ Size aSize100thMM( 0, 0 );
+ if( rGraphic.GetPrefMapMode().GetMapUnit() != MAP_PIXEL )
+ {
+ aSize100thMM = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), MAP_100TH_MM );
+ }
+ else
+ {
+ aSize100thMM = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), MAP_100TH_MM );
+ }
+ if ( aSize100thMM.Width() && aSize100thMM.Height() )
+ {
+ double fSourceSizePixelWidth = static_cast<double>(aSourceSizePixel.Width());
+ double fSourceSizePixelHeight= static_cast<double>(aSourceSizePixel.Height());
+ rGraphicCropPixel.Left() = static_cast< sal_Int32 >((fSourceSizePixelWidth * rGraphicCropLogic.Left ) / aSize100thMM.Width());
+ rGraphicCropPixel.Top() = static_cast< sal_Int32 >((fSourceSizePixelHeight * rGraphicCropLogic.Top ) / aSize100thMM.Height());
+ rGraphicCropPixel.Right() = static_cast< sal_Int32 >(( fSourceSizePixelWidth * ( aSize100thMM.Width() - rGraphicCropLogic.Right ) ) / aSize100thMM.Width() );
+ rGraphicCropPixel.Bottom() = static_cast< sal_Int32 >(( fSourceSizePixelHeight * ( aSize100thMM.Height() - rGraphicCropLogic.Bottom ) ) / aSize100thMM.Height() );
+ }
+ }
+ }
+ }
+}
+
+void ImplApplyBitmapScaling( ::Graphic& rGraphic, sal_Int32 nPixelWidth, sal_Int32 nPixelHeight )
+{
+ if ( nPixelWidth && nPixelHeight )
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+ MapMode aPrefMapMode( aBmpEx.GetPrefMapMode() );
+ Size aPrefSize( aBmpEx.GetPrefSize() );
+ aBmpEx.Scale( Size( nPixelWidth, nPixelHeight ) );
+ aBmpEx.SetPrefMapMode( aPrefMapMode );
+ aBmpEx.SetPrefSize( aPrefSize );
+ rGraphic = aBmpEx;
+ }
+}
+
+void ImplApplyBitmapResolution( ::Graphic& rGraphic, sal_Int32 nImageResolution, const Size& rVisiblePixelSize, const awt::Size& rLogicalSize )
+{
+ if ( nImageResolution && rLogicalSize.Width && rLogicalSize.Height )
+ {
+ const double fImageResolution = static_cast<double>( nImageResolution );
+ const double fSourceDPIX = ( static_cast<double>(rVisiblePixelSize.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize.Width);
+ const double fSourceDPIY = ( static_cast<double>(rVisiblePixelSize.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize.Height);
+ const sal_Int32 nSourcePixelWidth( rGraphic.GetSizePixel().Width() );
+ const sal_Int32 nSourcePixelHeight( rGraphic.GetSizePixel().Height() );
+ const double fSourcePixelWidth = static_cast<double>( nSourcePixelWidth );
+ const double fSourcePixelHeight= static_cast<double>( nSourcePixelHeight );
+
+ sal_Int32 nDestPixelWidth = nSourcePixelWidth;
+ sal_Int32 nDestPixelHeight = nSourcePixelHeight;
+
+ // check, if the bitmap DPI exceeds the maximum DPI
+ if( fSourceDPIX > fImageResolution )
+ {
+ nDestPixelWidth = static_cast<sal_Int32>(( fSourcePixelWidth * fImageResolution ) / fSourceDPIX);
+ if ( !nDestPixelWidth || ( nDestPixelWidth > nSourcePixelWidth ) )
+ nDestPixelWidth = nSourcePixelWidth;
+ }
+ if ( fSourceDPIY > fImageResolution )
+ {
+ nDestPixelHeight= static_cast<sal_Int32>(( fSourcePixelHeight* fImageResolution ) / fSourceDPIY);
+ if ( !nDestPixelHeight || ( nDestPixelHeight > nSourcePixelHeight ) )
+ nDestPixelHeight = nSourcePixelHeight;
+ }
+ if ( ( nDestPixelWidth != nSourcePixelWidth ) || ( nDestPixelHeight != nSourcePixelHeight ) )
+ ImplApplyBitmapScaling( rGraphic, nDestPixelWidth, nDestPixelHeight );
+ }
+}
+
+void ImplApplyFilterData( ::Graphic& rGraphic, uno::Sequence< beans::PropertyValue >& rFilterData )
+{
+ /* this method applies following attributes to the graphic, in the first step the
+ cropping area (logical size in 100thmm) is applied, in the second step the resolution
+ is applied, in the third step the graphic is scaled to the corresponding pixelsize.
+ if a parameter value is zero or not available the corresponding step will be skipped */
+
+ sal_Int32 nPixelWidth = 0;
+ sal_Int32 nPixelHeight= 0;
+ sal_Int32 nImageResolution = 0;
+ awt::Size aLogicalSize( 0, 0 );
+ text::GraphicCrop aCropLogic( 0, 0, 0, 0 );
+ sal_Bool bRemoveCropArea = sal_True;
+
+ for( sal_Int32 i = 0; i < rFilterData.getLength(); ++i )
+ {
+ const ::rtl::OUString aName( rFilterData[ i ].Name );
+ const uno::Any aValue( rFilterData[ i ].Value );
+
+ if( COMPARE_EQUAL == aName.compareToAscii( "PixelWidth" ) )
+ aValue >>= nPixelWidth;
+ else if( COMPARE_EQUAL == aName.compareToAscii( "PixelHeight" ) )
+ aValue >>= nPixelHeight;
+ else if( COMPARE_EQUAL == aName.compareToAscii( "LogicalSize" ) )
+ aValue >>= aLogicalSize;
+ else if (COMPARE_EQUAL == aName.compareToAscii( "GraphicCropLogic" ) )
+ aValue >>= aCropLogic;
+ else if (COMPARE_EQUAL == aName.compareToAscii( "RemoveCropArea" ) )
+ aValue >>= bRemoveCropArea;
+ else if (COMPARE_EQUAL == aName.compareToAscii( "ImageResolution" ) )
+ aValue >>= nImageResolution;
+ }
+ if ( rGraphic.GetType() == GRAPHIC_BITMAP )
+ {
+ Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() );
+ ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel );
+ if ( bRemoveCropArea )
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+ aBmpEx.Crop( aCropPixel );
+ rGraphic = aBmpEx;
+ }
+ Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() );
+ ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize );
+ ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight );
+ }
+ else if ( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && nImageResolution )
+ {
+ VirtualDevice aDummyVDev;
+ GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
+ Size aMtfSize( aDummyVDev.LogicToLogic( aMtf.GetPrefSize(), aMtf.GetPrefMapMode(), MAP_100TH_MM ) );
+ if ( aMtfSize.Width() && aMtfSize.Height() )
+ {
+ MapMode aNewMapMode( MAP_100TH_MM );
+ aNewMapMode.SetScaleX( static_cast< double >( aLogicalSize.Width ) / static_cast< double >( aMtfSize.Width() ) );
+ aNewMapMode.SetScaleY( static_cast< double >( aLogicalSize.Height ) / static_cast< double >( aMtfSize.Height() ) );
+ aDummyVDev.EnableOutput( sal_False );
+ aDummyVDev.SetMapMode( aNewMapMode );
+
+ for( sal_uInt32 i = 0, nObjCount = aMtf.GetActionCount(); i < nObjCount; i++ )
+ {
+ MetaAction* pAction = aMtf.GetAction( i );
+ switch( pAction->GetType() )
+ {
+ // only optimizing common bitmap actions:
+ case( META_MAPMODE_ACTION ):
+ {
+ const_cast< MetaAction* >( pAction )->Execute( &aDummyVDev );
+ break;
+ }
+ case( META_PUSH_ACTION ):
+ {
+ const MetaPushAction* pA = (const MetaPushAction*)pAction;
+ aDummyVDev.Push( pA->GetFlags() );
+ break;
+ }
+ case( META_POP_ACTION ):
+ {
+ aDummyVDev.Pop();
+ break;
+ }
+ case( META_BMPSCALE_ACTION ):
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ BitmapEx aBmpEx;
+ Point aPos;
+ Size aSize;
+ if ( pAction->GetType() == META_BMPSCALE_ACTION )
+ {
+ MetaBmpScaleAction* pScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction );
+ aBmpEx = pScaleAction->GetBitmap();
+ aPos = pScaleAction->GetPoint();
+ aSize = pScaleAction->GetSize();
+ }
+ else
+ {
+ MetaBmpExScaleAction* pScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction );
+ aBmpEx = pScaleAction->GetBitmapEx();
+ aPos = pScaleAction->GetPoint();
+ aSize = pScaleAction->GetSize();
+ }
+ ::Graphic aGraphic( aBmpEx );
+ const Size aSize100thmm( aDummyVDev.LogicToPixel( aSize ) );
+ Size aSize100thmm2( aDummyVDev.PixelToLogic( aSize100thmm, MAP_100TH_MM ) );
+
+ ImplApplyBitmapResolution( aGraphic, nImageResolution,
+ aGraphic.GetSizePixel(), awt::Size( aSize100thmm2.Width(), aSize100thmm2.Height() ) );
+
+ MetaAction* pNewAction;
+ if ( pAction->GetType() == META_BMPSCALE_ACTION )
+ pNewAction = new MetaBmpScaleAction ( aPos, aSize, aGraphic.GetBitmap() );
+ else
+ pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() );
+
+ aMtf.ReplaceAction( pNewAction, i );
+ pAction->Delete();
+ break;
+ }
+ default:
+ case( META_BMP_ACTION ):
+ case( META_BMPSCALEPART_ACTION ):
+ case( META_BMPEX_ACTION ):
+ case( META_BMPEXSCALEPART_ACTION ):
+ case( META_MASK_ACTION ):
+ case( META_MASKSCALE_ACTION ):
+ break;
+ }
+ }
+ rGraphic = aMtf;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL GraphicProvider::storeGraphic( const uno::Reference< ::graphic::XGraphic >& rxGraphic, const uno::Sequence< beans::PropertyValue >& rMediaProperties )
+ throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ SvStream* pOStm = NULL;
+ String aPath;
+ sal_Int32 i;
+
+ for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i )
+ {
+ const ::rtl::OUString aName( rMediaProperties[ i ].Name );
+ const uno::Any aValue( rMediaProperties[ i ].Value );
+
+ if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) )
+ {
+ ::rtl::OUString aURL;
+
+ aValue >>= aURL;
+ pOStm = ::utl::UcbStreamHelper::CreateStream( aURL, STREAM_WRITE | STREAM_TRUNC );
+ aPath = aURL;
+ }
+ else if( COMPARE_EQUAL == aName.compareToAscii( "OutputStream" ) )
+ {
+ uno::Reference< io::XStream > xOStm;
+
+ aValue >>= xOStm;
+
+ if( xOStm.is() )
+ pOStm = ::utl::UcbStreamHelper::CreateStream( xOStm );
+ }
+ }
+
+ if( pOStm )
+ {
+ uno::Sequence< beans::PropertyValue > aFilterDataSeq;
+ const char* pFilterShortName = NULL;
+
+ for( i = 0; i < rMediaProperties.getLength(); ++i )
+ {
+ const ::rtl::OUString aName( rMediaProperties[ i ].Name );
+ const uno::Any aValue( rMediaProperties[ i ].Value );
+
+ if( COMPARE_EQUAL == aName.compareToAscii( "FilterData" ) )
+ {
+ aValue >>= aFilterDataSeq;
+ }
+ else if( COMPARE_EQUAL == aName.compareToAscii( "MimeType" ) )
+ {
+ ::rtl::OUString aMimeType;
+
+ aValue >>= aMimeType;
+
+ if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_BMP ) )
+ pFilterShortName = "bmp";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EPS ) )
+ pFilterShortName = "eps";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_GIF ) )
+ pFilterShortName = "gif";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_JPG ) )
+ pFilterShortName = "jpg";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_MET ) )
+ pFilterShortName = "met";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PNG ) )
+ pFilterShortName = "png";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PCT ) )
+ pFilterShortName = "pct";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PBM ) )
+ pFilterShortName = "pbm";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PGM ) )
+ pFilterShortName = "pgm";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PPM ) )
+ pFilterShortName = "ppm";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_RAS ) )
+ pFilterShortName = "ras";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVM ) )
+ pFilterShortName = "svm";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_TIF ) )
+ pFilterShortName = "tif";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EMF ) )
+ pFilterShortName = "emf";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_WMF ) )
+ pFilterShortName = "wmf";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_XPM ) )
+ pFilterShortName = "xpm";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVG ) )
+ pFilterShortName = "svg";
+ else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_VCLGRAPHIC ) )
+ pFilterShortName = MIMETYPE_VCLGRAPHIC;
+ }
+ }
+
+ if( pFilterShortName )
+ {
+ ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter();
+
+ if( pFilter )
+ {
+ const uno::Reference< XInterface > xIFace( rxGraphic, uno::UNO_QUERY );
+ const ::Graphic* pGraphic = ::unographic::Graphic::getImplementation( xIFace );
+
+ if( pGraphic && ( pGraphic->GetType() != GRAPHIC_NONE ) )
+ {
+ ::Graphic aGraphic( *pGraphic );
+ ImplApplyFilterData( aGraphic, aFilterDataSeq );
+
+ /* sj: using a temporary memory stream, because some graphic filters are seeking behind
+ stream end (which leads to an invalid argument exception then). */
+ SvMemoryStream aMemStrm;
+ aMemStrm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+ if( 0 == strcmp( pFilterShortName, MIMETYPE_VCLGRAPHIC ) )
+ aMemStrm << aGraphic;
+ else
+ {
+ pFilter->ExportGraphic( aGraphic, aPath, aMemStrm,
+ pFilter->GetExportFormatNumberForShortName( ::rtl::OUString::createFromAscii( pFilterShortName ) ),
+ ( aFilterDataSeq.getLength() ? &aFilterDataSeq : NULL ) );
+ }
+ aMemStrm.Seek( STREAM_SEEK_TO_END );
+ pOStm->Write( aMemStrm.GetData(), aMemStrm.Tell() );
+ }
+ }
+ }
+ delete pOStm;
+ }
+}
+
+}
diff --git a/svtools/source/graphic/renderer.cxx b/svtools/source/graphic/renderer.cxx
new file mode 100644
index 000000000000..b8a0ea73b92c
--- /dev/null
+++ b/svtools/source/graphic/renderer.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_svtools.hxx"
+
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <svl/itemprop.hxx>
+#include <svtools/grfmgr.hxx>
+#include "graphic.hxx"
+#include "renderer.hxx"
+
+#define UNOGRAPHIC_DEVICE 1
+#define UNOGRAPHIC_DESTINATIONRECT 2
+#define UNOGRAPHIC_RENDERDATA 3
+
+using namespace ::com::sun::star;
+
+namespace unographic {
+
+// ---------------------
+// - GraphicRendererVCL -
+// ---------------------
+
+uno::Reference< uno::XInterface > SAL_CALL GraphicRendererVCL_CreateInstance( const uno::Reference< lang::XMultiServiceFactory >& )
+{
+ return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicRendererVCL );
+}
+
+
+GraphicRendererVCL::GraphicRendererVCL() :
+ ::comphelper::PropertySetHelper( createPropertySetInfo() ),
+ mpOutDev( NULL )
+{
+}
+
+// ------------------------------------------------------------------------------
+
+GraphicRendererVCL::~GraphicRendererVCL()
+ throw()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString GraphicRendererVCL::getImplementationName_Static()
+ throw()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicRendererVCL" ) );
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > GraphicRendererVCL::getSupportedServiceNames_Static()
+ throw( )
+{
+ uno::Sequence< ::rtl::OUString > aSeq( 1 );
+
+ aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicRendererVCL" ) );
+
+ return aSeq;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Any SAL_CALL GraphicRendererVCL::queryAggregation( const uno::Type & rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aAny;
+
+ if( rType == ::getCppuType((const uno::Reference< lang::XServiceInfo >*)0) )
+ aAny <<= uno::Reference< lang::XServiceInfo >(this);
+ else if( rType == ::getCppuType((const uno::Reference< lang::XTypeProvider >*)0) )
+ aAny <<= uno::Reference< lang::XTypeProvider >(this);
+ else if( rType == ::getCppuType((const uno::Reference< beans::XPropertySet >*)0) )
+ aAny <<= uno::Reference< beans::XPropertySet >(this);
+ else if( rType == ::getCppuType((const uno::Reference< beans::XPropertyState >*)0) )
+ aAny <<= uno::Reference< beans::XPropertyState >(this);
+ else if( rType == ::getCppuType((const uno::Reference< beans::XMultiPropertySet >*)0) )
+ aAny <<= uno::Reference< beans::XMultiPropertySet >(this);
+ else if( rType == ::getCppuType((const uno::Reference< graphic::XGraphicRenderer >*)0) )
+ aAny <<= uno::Reference< graphic::XGraphicRenderer >(this);
+ else
+ aAny <<= OWeakAggObject::queryAggregation( rType );
+
+ return aAny;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Any SAL_CALL GraphicRendererVCL::queryInterface( const uno::Type & rType )
+ throw( uno::RuntimeException )
+{
+ return OWeakAggObject::queryInterface( rType );
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL GraphicRendererVCL::acquire()
+ throw()
+{
+ OWeakAggObject::acquire();
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL GraphicRendererVCL::release()
+ throw()
+{
+ OWeakAggObject::release();
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL GraphicRendererVCL::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL GraphicRendererVCL::supportsService( const rtl::OUString& ServiceName )
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
+ const ::rtl::OUString* pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL GraphicRendererVCL::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< uno::Type > SAL_CALL GraphicRendererVCL::getTypes()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< uno::Type > aTypes( 7 );
+ uno::Type* pTypes = aTypes.getArray();
+
+ *pTypes++ = ::getCppuType((const uno::Reference< uno::XAggregation>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< beans::XPropertySet>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< beans::XPropertyState>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< beans::XMultiPropertySet>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< graphic::XGraphicRenderer>*)0);
+
+ return aTypes;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< sal_Int8 > SAL_CALL GraphicRendererVCL::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ 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;
+}
+
+// ------------------------------------------------------------------------------
+
+::comphelper::PropertySetInfo* GraphicRendererVCL::createPropertySetInfo()
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ ::comphelper::PropertySetInfo* pRet = new ::comphelper::PropertySetInfo();
+
+ static ::comphelper::PropertyMapEntry aEntries[] =
+ {
+ { MAP_CHAR_LEN( "Device" ), UNOGRAPHIC_DEVICE, &::getCppuType( (const uno::Any*)(0)), 0, 0 },
+ { MAP_CHAR_LEN( "DestinationRect" ), UNOGRAPHIC_DESTINATIONRECT, &::getCppuType( (const awt::Rectangle*)(0)), 0, 0 },
+ { MAP_CHAR_LEN( "RenderData" ), UNOGRAPHIC_RENDERDATA, &::getCppuType( (const uno::Any*)(0)), 0, 0 },
+
+ { 0,0,0,0,0,0 }
+ };
+
+ pRet->acquire();
+ pRet->add( aEntries );
+
+ return pRet;
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicRendererVCL::_setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const uno::Any* pValues )
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ while( *ppEntries )
+ {
+ switch( (*ppEntries)->mnHandle )
+ {
+ case( UNOGRAPHIC_DEVICE ):
+ {
+ uno::Reference< awt::XDevice > xDevice;
+
+ if( ( *pValues >>= xDevice ) && xDevice.is() )
+ {
+ mxDevice = xDevice;
+ mpOutDev = VCLUnoHelper::GetOutputDevice( xDevice );
+ }
+ else
+ {
+ mxDevice.clear();
+ mpOutDev = NULL;
+ }
+ }
+ break;
+
+ case( UNOGRAPHIC_DESTINATIONRECT ):
+ {
+ awt::Rectangle aAWTRect;
+
+ if( *pValues >>= aAWTRect )
+ {
+ maDestRect = Rectangle( Point( aAWTRect.X, aAWTRect.Y ),
+ Size( aAWTRect.Width, aAWTRect.Height ) );
+ }
+ }
+ break;
+
+ case( UNOGRAPHIC_RENDERDATA ):
+ {
+ *pValues >>= maRenderData;
+ }
+ break;
+ }
+
+ ++ppEntries;
+ ++pValues;
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void GraphicRendererVCL::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, uno::Any* pValues )
+ throw( beans::UnknownPropertyException, lang::WrappedTargetException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ while( *ppEntries )
+ {
+ switch( (*ppEntries)->mnHandle )
+ {
+ case( UNOGRAPHIC_DEVICE ):
+ {
+ if( mxDevice.is() )
+ *pValues <<= mxDevice;
+ }
+ break;
+
+ case( UNOGRAPHIC_DESTINATIONRECT ):
+ {
+ const awt::Rectangle aAWTRect( maDestRect.Left(), maDestRect.Top(),
+ maDestRect.GetWidth(), maDestRect.GetHeight() );
+
+ *pValues <<= aAWTRect;
+ }
+ break;
+
+ case( UNOGRAPHIC_RENDERDATA ):
+ {
+ *pValues <<= maRenderData;
+ }
+ break;
+ }
+
+ ++ppEntries;
+ ++pValues;
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL GraphicRendererVCL::render( const uno::Reference< graphic::XGraphic >& rxGraphic )
+ throw (uno::RuntimeException)
+{
+ if( mpOutDev && mxDevice.is() && rxGraphic.is() )
+ {
+ const uno::Reference< XInterface > xIFace( rxGraphic, uno::UNO_QUERY );
+ const ::Graphic* pGraphic = ::unographic::Graphic::getImplementation( xIFace );
+
+ if( pGraphic )
+ {
+ GraphicObject aGraphicObject( *pGraphic );
+ aGraphicObject.Draw( mpOutDev, maDestRect.TopLeft(), maDestRect.GetSize() );
+ }
+ }
+}
+
+}
diff --git a/svtools/source/graphic/transformer.cxx b/svtools/source/graphic/transformer.cxx
new file mode 100644
index 000000000000..5c234c8d5ecb
--- /dev/null
+++ b/svtools/source/graphic/transformer.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_svtools.hxx"
+
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/image.hxx>
+#include <vcl/metaact.hxx>
+#include <tools/rcid.h>
+#include <tools/resid.hxx>
+#include <tools/resmgr.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <svl/solar.hrc>
+#include <vcl/salbtype.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/bmpacc.hxx>
+#include <com/sun/star/text/GraphicCrop.hpp>
+
+#include "graphic.hxx"
+#include "transformer.hxx"
+
+using namespace com::sun::star;
+
+namespace unographic {
+
+// ----------------------
+// - GraphicTransformer -
+// ----------------------
+
+GraphicTransformer::GraphicTransformer()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+GraphicTransformer::~GraphicTransformer()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+void setAlpha( Bitmap& rBitmap, AlphaMask& rAlpha, sal_Int32 nColorFrom, sal_Int8 nAlphaTo )
+{
+ BitmapWriteAccess* pWriteAccess = rAlpha.AcquireWriteAccess();
+ BitmapReadAccess* pReadAccess = rBitmap.AcquireReadAccess();
+ BitmapColor aColorFrom( static_cast< sal_uInt8 >( nColorFrom >> 16 ),
+ static_cast< sal_uInt8 >( nColorFrom >> 8 ),
+ static_cast< sal_uInt8 >( nColorFrom ) );
+ if ( pReadAccess && pWriteAccess )
+ {
+ for ( sal_Int32 nY = 0; nY < pReadAccess->Height(); nY++ )
+ {
+ for ( sal_Int32 nX = 0; nX < pReadAccess->Width(); nX++ )
+ {
+ BitmapColor aColor( pReadAccess->GetPixel( nY, nX ) );
+ if ( aColor == aColorFrom )
+ pWriteAccess->SetPixel( nY, nX, nAlphaTo );
+ }
+ }
+ }
+ rBitmap.ReleaseAccess( pReadAccess );
+ rAlpha.ReleaseAccess( pWriteAccess );
+}
+
+// XGraphicTransformer
+uno::Reference< graphic::XGraphic > SAL_CALL GraphicTransformer::colorChange(
+ const uno::Reference< graphic::XGraphic >& rxGraphic, sal_Int32 nColorFrom, sal_Int8 nTolerance, sal_Int32 nColorTo, sal_Int8 nAlphaTo )
+ throw ( lang::IllegalArgumentException, uno::RuntimeException)
+{
+ const uno::Reference< uno::XInterface > xIFace( rxGraphic, uno::UNO_QUERY );
+ ::Graphic aGraphic( *::unographic::Graphic::getImplementation( xIFace ) );
+
+ BitmapColor aColorFrom( static_cast< sal_uInt8 >( nColorFrom ), static_cast< sal_uInt8 >( nColorFrom >> 8 ), static_cast< sal_uInt8 >( nColorFrom >> 16 ) );
+ BitmapColor aColorTo( static_cast< sal_uInt8 >( nColorTo ), static_cast< sal_uInt8 >( nColorTo >> 8 ), static_cast< sal_uInt8 >( nColorTo >> 16 ) );
+
+ if ( aGraphic.GetType() == GRAPHIC_BITMAP )
+ {
+ BitmapEx aBitmapEx( aGraphic.GetBitmapEx() );
+ Bitmap aBitmap( aBitmapEx.GetBitmap() );
+
+ if ( aBitmapEx.IsAlpha() )
+ {
+ AlphaMask aAlphaMask( aBitmapEx.GetAlpha() );
+ setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
+ aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
+ aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
+ }
+ else if ( aBitmapEx.IsTransparent() )
+ {
+ if ( ( nAlphaTo == 0 ) || ( nAlphaTo == sal::static_int_cast<sal_Int8>(0xff) ) )
+ {
+ Bitmap aMask( aBitmapEx.GetMask() );
+ Bitmap aMask2( aBitmap.CreateMask( aColorFrom, nTolerance ) );
+ aMask.CombineSimple( aMask2, BMP_COMBINE_OR );
+ aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
+ aGraphic = ::Graphic( BitmapEx( aBitmap, aMask ) );
+ }
+ else
+ {
+ AlphaMask aAlphaMask( aBitmapEx.GetMask() );
+ setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
+ aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
+ aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
+ }
+ }
+ else
+ {
+ if ( ( nAlphaTo == 0 ) || ( nAlphaTo == sal::static_int_cast<sal_Int8>(0xff) ) )
+ {
+ Bitmap aMask( aBitmap.CreateMask( aColorFrom, nTolerance ) );
+ aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
+ aGraphic = ::Graphic( BitmapEx( aBitmap, aMask ) );
+ }
+ else
+ {
+ AlphaMask aAlphaMask( aBitmapEx.GetSizePixel() );
+ setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
+ aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
+ aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
+ }
+ }
+ }
+ ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic();
+ pUnoGraphic->init( aGraphic );
+ uno::Reference< graphic::XGraphic > xRet( pUnoGraphic );
+ return xRet;
+}
+
+}
diff --git a/svtools/source/graphic/transformer.hxx b/svtools/source/graphic/transformer.hxx
new file mode 100644
index 000000000000..c4002bb4bbae
--- /dev/null
+++ b/svtools/source/graphic/transformer.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 _GOODIES_GRAPHICTRANSFORMER_HXX
+#define _GOODIES_GRAPHICTRANSFORMER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+
+using namespace com::sun::star;
+
+namespace unographic {
+
+// ----------------------
+// - GraphicTransformer -
+// ----------------------
+
+typedef ::cppu::WeakAggImplHelper1<
+ ::com::sun::star::graphic::XGraphicTransformer
+ > GraphicTransformer_UnoImplHelper1;
+class GraphicTransformer : public GraphicTransformer_UnoImplHelper1
+{
+ public:
+
+ GraphicTransformer();
+ ~GraphicTransformer();
+
+ // XGraphicTransformer
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > SAL_CALL colorChange(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rGraphic,
+ sal_Int32 nColorFrom, sal_Int8 nTolerance, sal_Int32 nColorTo, sal_Int8 nAlphaTo )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+};
+
+}
+
+#endif
diff --git a/svtools/source/hatchwindow/documentcloser.cxx b/svtools/source/hatchwindow/documentcloser.cxx
new file mode 100644
index 000000000000..09dc7018dc42
--- /dev/null
+++ b/svtools/source/hatchwindow/documentcloser.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_svtools.hxx"
+#include <com/sun/star/util/XCloseBroadcaster.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/dialog.hxx>
+#include <tools/link.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include "documentcloser.hxx"
+
+using namespace ::com::sun::star;
+
+
+// ====================================================================
+// MainThreadFrameCloserRequest
+// ====================================================================
+
+class MainThreadFrameCloserRequest
+{
+ uno::Reference< frame::XFrame > m_xFrame;
+
+ public:
+ MainThreadFrameCloserRequest( const uno::Reference< frame::XFrame >& xFrame )
+ : m_xFrame( xFrame )
+ {}
+
+ DECL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest* );
+
+ static void Start( MainThreadFrameCloserRequest* pRequest );
+};
+
+// --------------------------------------------------------
+void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest* pMTRequest )
+{
+ if ( pMTRequest )
+ {
+ if ( Application::GetMainThreadIdentifier() == osl_getThreadIdentifier( NULL ) )
+ {
+ // this is the main thread
+ worker( NULL, pMTRequest );
+ }
+ else
+ Application::PostUserEvent( STATIC_LINK( NULL, MainThreadFrameCloserRequest, worker ), pMTRequest );
+ }
+}
+
+// --------------------------------------------------------
+IMPL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest*, pMTRequest )
+{
+ (void) pThis; // unused
+ if ( pMTRequest )
+ {
+ if ( pMTRequest->m_xFrame.is() )
+ {
+ // this is the main thread, the solar mutex must be locked
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ uno::Reference< awt::XWindow > xWindow = pMTRequest->m_xFrame->getContainerWindow();
+ uno::Reference< awt::XVclWindowPeer > xWinPeer( xWindow, uno::UNO_QUERY_THROW );
+
+ xWindow->setVisible( sal_False );
+
+ // reparent the window
+ xWinPeer->setProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginParent" ) ),
+ uno::makeAny( (sal_Int64) 0 ) );
+
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ Dialog::EndAllDialogs( pWindow );
+ }
+ catch( uno::Exception& )
+ {
+ // ignore all the errors
+ }
+
+ try
+ {
+ uno::Reference< util::XCloseable > xCloseable( pMTRequest->m_xFrame, uno::UNO_QUERY_THROW );
+ xCloseable->close( sal_True );
+ }
+ catch( uno::Exception& )
+ {
+ // ignore all the errors
+ }
+ }
+
+ delete pMTRequest;
+ }
+
+ return 0;
+}
+
+
+// ====================================================================
+// ODocumentCloser
+// ====================================================================
+
+// --------------------------------------------------------
+ODocumentCloser::ODocumentCloser( const uno::Reference< uno::XComponentContext >& xContext )
+: m_xContext( xContext )
+, m_pListenersContainer( NULL )
+, m_bDisposed( sal_False )
+, m_bInitialized( sal_False )
+{
+}
+
+// --------------------------------------------------------
+ODocumentCloser::~ODocumentCloser()
+{
+ if ( m_pListenersContainer )
+ {
+ delete m_pListenersContainer;
+ m_pListenersContainer = NULL;
+ }
+}
+
+// XComponent
+// --------------------------------------------------------
+void SAL_CALL ODocumentCloser::dispose()
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+ if ( m_pListenersContainer )
+ m_pListenersContainer->disposeAndClear( aSource );
+
+ // TODO: trigger a main thread execution to close the frame
+ if ( m_xFrame.is() )
+ {
+ // the created object will be deleted after thread execution
+ MainThreadFrameCloserRequest* pCloser = new MainThreadFrameCloserRequest( m_xFrame );
+ MainThreadFrameCloserRequest::Start( pCloser );
+ }
+
+ m_bDisposed = sal_True;
+}
+
+// --------------------------------------------------------
+void SAL_CALL ODocumentCloser::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bDisposed )
+ throw lang::DisposedException(); // TODO
+
+ if ( !m_pListenersContainer )
+ m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
+
+ m_pListenersContainer->addInterface( xListener );
+}
+
+// --------------------------------------------------------
+void SAL_CALL ODocumentCloser::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pListenersContainer )
+ m_pListenersContainer->removeInterface( xListener );
+}
+
+// XInitialization
+// --------------------------------------------------------
+void SAL_CALL ODocumentCloser::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bInitialized )
+ throw frame::DoubleInitializationException();
+
+ if ( m_bDisposed )
+ throw lang::DisposedException(); // TODO
+
+ if ( !m_refCount )
+ throw uno::RuntimeException(); // the object must be refcounted already!
+
+ sal_Int32 nLen = aArguments.getLength();
+ if ( nLen != 1 )
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ),
+ uno::Reference< uno::XInterface >(),
+ 0 );
+
+ if ( !( aArguments[0] >>= m_xFrame ) || !m_xFrame.is() )
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ),
+ uno::Reference< uno::XInterface >(),
+ 0 );
+
+ m_bInitialized = sal_True;
+}
+
+
+// XServiceInfo
+// --------------------------------------------------------
+::rtl::OUString SAL_CALL ODocumentCloser::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return impl_staticGetImplementationName();
+}
+
+// --------------------------------------------------------
+::sal_Bool SAL_CALL ODocumentCloser::supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
+
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
+ return sal_True;
+
+ return sal_False;
+}
+
+// --------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::getSupportedServiceNames()
+ throw (uno::RuntimeException)
+{
+ return impl_staticGetSupportedServiceNames();
+}
+
+// Static methods
+// --------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::impl_staticGetSupportedServiceNames()
+{
+ const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.DocumentCloser" ) );
+ return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
+}
+
+// --------------------------------------------------------
+::rtl::OUString SAL_CALL ODocumentCloser::impl_staticGetImplementationName()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.DocumentCloser" ) );
+}
+
+// --------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL ODocumentCloser::impl_staticCreateSelfInstance(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ uno::Reference< uno::XComponentContext > xContext;
+ uno::Reference< beans::XPropertySet > xPropSet( xServiceManager, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;
+
+ if ( !xContext.is() )
+ {
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain component context from service manager!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ return static_cast< cppu::OWeakObject * >( new ODocumentCloser( xContext ) );
+}
+
diff --git a/svtools/source/hatchwindow/documentcloser.hxx b/svtools/source/hatchwindow/documentcloser.hxx
new file mode 100644
index 000000000000..98e30b4d1683
--- /dev/null
+++ b/svtools/source/hatchwindow/documentcloser.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 __DOCUMENTCLOSER_HXX_
+#define __DOCUMENTCLOSER_HXX_
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/embed/XActionsApproval.hpp>
+#include <com/sun/star/embed/Actions.hpp>
+#include <cppuhelper/weakref.hxx>
+#include <osl/mutex.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+
+// the service is implemented as a wrapper to be able to die by refcount
+// the disposing mechanics is required for java related scenarios
+class ODocumentCloser : public ::cppu::WeakImplHelper3< ::com::sun::star::lang::XComponent,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::lang::XServiceInfo >
+{
+ ::osl::Mutex m_aMutex;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > m_xFrame;
+
+ ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners
+
+ sal_Bool m_bDisposed;
+ sal_Bool m_bInitialized;
+
+public:
+ ODocumentCloser( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext );
+ ~ODocumentCloser();
+
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ impl_staticGetSupportedServiceNames();
+
+ static ::rtl::OUString SAL_CALL impl_staticGetImplementationName();
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ impl_staticCreateSelfInstance(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
+
+// XComponent
+ virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) 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);
+
+};
+
+#endif
+
diff --git a/svtools/source/hatchwindow/hatchwindow.cxx b/svtools/source/hatchwindow/hatchwindow.cxx
new file mode 100644
index 000000000000..1b84206d6696
--- /dev/null
+++ b/svtools/source/hatchwindow/hatchwindow.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_svtools.hxx"
+#include <com/sun/star/embed/XHatchWindowController.hpp>
+
+#include "hatchwindow.hxx"
+#include "ipwin.hxx"
+
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::com::sun::star;
+
+VCLXHatchWindow::VCLXHatchWindow()
+: VCLXWindow()
+, pHatchWindow(0)
+{
+}
+
+VCLXHatchWindow::~VCLXHatchWindow()
+{
+}
+
+void VCLXHatchWindow::initializeWindow( const uno::Reference< awt::XWindowPeer >& xParent,
+ const awt::Rectangle& aBounds,
+ const awt::Size& aSize )
+{
+ Window* pParent = NULL;
+ VCLXWindow* pParentComponent = VCLXWindow::GetImplementation( xParent );
+
+ if ( pParentComponent )
+ pParent = pParentComponent->GetWindow();
+
+ OSL_ENSURE( pParent, "No parent window is provided!\n" );
+ if ( !pParent )
+ throw lang::IllegalArgumentException(); // TODO
+
+ pHatchWindow = new SvResizeWindow( pParent, this );
+ pHatchWindow->SetPosSizePixel( aBounds.X, aBounds.Y, aBounds.Width, aBounds.Height );
+ aHatchBorderSize = aSize;
+ pHatchWindow->SetHatchBorderPixel( Size( aSize.Width, aSize.Height ) );
+
+ SetWindow( pHatchWindow );
+ pHatchWindow->SetComponentInterface( this );
+
+ //pHatchWindow->Show();
+}
+
+void VCLXHatchWindow::QueryObjAreaPixel( Rectangle & aRect )
+{
+ if ( m_xController.is() )
+ {
+ awt::Rectangle aUnoRequestRect = AWTRectangle( aRect );
+
+ try {
+ awt::Rectangle aUnoResultRect = m_xController->calcAdjustedRectangle( aUnoRequestRect );
+ aRect = VCLRectangle( aUnoResultRect );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Can't adjust rectangle size!\n" );
+ }
+ }
+}
+
+void VCLXHatchWindow::RequestObjAreaPixel( const Rectangle & aRect )
+{
+ if ( m_xController.is() )
+ {
+ awt::Rectangle aUnoRequestRect = AWTRectangle( aRect );
+
+ try {
+ m_xController->requestPositioning( aUnoRequestRect );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Can't request resizing!\n" );
+ }
+ }
+}
+
+void VCLXHatchWindow::InplaceDeactivate()
+{
+ if ( m_xController.is() )
+ {
+ // TODO: communicate with controller
+ }
+}
+
+
+uno::Any SAL_CALL VCLXHatchWindow::queryInterface( const uno::Type & rType )
+ throw( uno::RuntimeException )
+{
+ // Attention:
+ // Don't use mutex or guard in this method!!! Is a method of XInterface.
+
+ uno::Any aReturn( ::cppu::queryInterface( rType,
+ static_cast< embed::XHatchWindow* >( this ) ) );
+
+ if ( aReturn.hasValue() == sal_True )
+ {
+ return aReturn ;
+ }
+
+ return VCLXWindow::queryInterface( rType ) ;
+}
+
+void SAL_CALL VCLXHatchWindow::acquire()
+ throw()
+{
+ VCLXWindow::acquire();
+}
+
+void SAL_CALL VCLXHatchWindow::release()
+ throw()
+{
+ VCLXWindow::release();
+}
+
+uno::Sequence< uno::Type > SAL_CALL VCLXHatchWindow::getTypes()
+ throw( uno::RuntimeException )
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
+
+ if ( pTypeCollection == NULL )
+ {
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const uno::Reference< embed::XHatchWindow >* )NULL ),
+ VCLXHatchWindow::getTypes() );
+
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL VCLXHatchWindow::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
+
+ if ( pID == NULL )
+ {
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+::com::sun::star::awt::Size SAL_CALL VCLXHatchWindow::getHatchBorderSize() throw (::com::sun::star::uno::RuntimeException)
+{
+ return aHatchBorderSize;
+}
+
+void SAL_CALL VCLXHatchWindow::setHatchBorderSize( const ::com::sun::star::awt::Size& _hatchbordersize ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( pHatchWindow )
+ {
+ aHatchBorderSize = _hatchbordersize;
+ pHatchWindow->SetHatchBorderPixel( Size( aHatchBorderSize.Width, aHatchBorderSize.Height ) );
+ }
+}
+
+void SAL_CALL VCLXHatchWindow::setController( const uno::Reference< embed::XHatchWindowController >& xController )
+ throw (uno::RuntimeException)
+{
+ m_xController = xController;
+}
+
+void SAL_CALL VCLXHatchWindow::dispose()
+ throw (uno::RuntimeException)
+{
+ pHatchWindow = 0;
+ VCLXWindow::dispose();
+}
+
+void SAL_CALL VCLXHatchWindow::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ VCLXWindow::addEventListener( xListener );
+}
+
+void SAL_CALL VCLXHatchWindow::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ VCLXWindow::removeEventListener( xListener );
+}
+
+void VCLXHatchWindow::Activated()
+{
+ if ( m_xController.is() )
+ m_xController->activated();
+}
+
+void VCLXHatchWindow::Deactivated()
+{
+ if ( m_xController.is() )
+ m_xController->deactivated();
+}
diff --git a/svtools/source/hatchwindow/hatchwindow.hxx b/svtools/source/hatchwindow/hatchwindow.hxx
new file mode 100644
index 000000000000..fa3e70ee8901
--- /dev/null
+++ b/svtools/source/hatchwindow/hatchwindow.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 _SVT_HATCHWINDOW_HXX
+#define _SVT_HATCHWINDOW_HXX
+
+#include <com/sun/star/embed/XHatchWindow.hpp>
+
+#include <toolkit/awt/vclxwindow.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+class SvResizeWindow;
+class VCLXHatchWindow : public ::com::sun::star::embed::XHatchWindow,
+ public VCLXWindow
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XHatchWindowController > m_xController;
+ ::com::sun::star::awt::Size aHatchBorderSize;
+ SvResizeWindow* pHatchWindow;
+
+public:
+ VCLXHatchWindow();
+ ~VCLXHatchWindow();
+
+ void initializeWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParent,
+ const ::com::sun::star::awt::Rectangle& aBounds,
+ const ::com::sun::star::awt::Size& aSize );
+
+ void QueryObjAreaPixel( Rectangle & );
+ void RequestObjAreaPixel( const Rectangle & );
+ void InplaceDeactivate();
+ void Activated();
+ void Deactivated();
+
+ // XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw();
+ void SAL_CALL release() throw();
+
+ // XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ // XHatchWindow
+ virtual void SAL_CALL setController( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XHatchWindowController >& xController ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getHatchBorderSize() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setHatchBorderSize( const ::com::sun::star::awt::Size& _hatchbordersize ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+#endif // _SVT_HATCHWINDOW_HXX
+
diff --git a/svtools/source/hatchwindow/hatchwindowfactory.cxx b/svtools/source/hatchwindow/hatchwindowfactory.cxx
new file mode 100644
index 000000000000..f8dbddff3761
--- /dev/null
+++ b/svtools/source/hatchwindow/hatchwindowfactory.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_svtools.hxx"
+
+#include "hatchwindowfactory.hxx"
+#include "hatchwindow.hxx"
+#include "cppuhelper/factory.hxx"
+
+#include "documentcloser.hxx"
+
+using namespace ::com::sun::star;
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OHatchWindowFactory::impl_staticGetSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > aRet(2);
+ aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.HatchWindowFactory");
+ aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.HatchWindowFactory");
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OHatchWindowFactory::impl_staticGetImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.HatchWindowFactory");
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OHatchWindowFactory::impl_staticCreateSelfInstance(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ return uno::Reference< uno::XInterface >( *new OHatchWindowFactory( xServiceManager ) );
+}
+
+
+//-------------------------------------------------------------------------
+uno::Reference< embed::XHatchWindow > SAL_CALL OHatchWindowFactory::createHatchWindowInstance(
+ const uno::Reference< awt::XWindowPeer >& xParent,
+ const awt::Rectangle& aBounds,
+ const awt::Size& aHandlerSize )
+ throw (uno::RuntimeException)
+{
+ if ( !xParent.is() )
+ throw lang::IllegalArgumentException(); // TODO
+
+ VCLXHatchWindow* pResult = new VCLXHatchWindow();
+ pResult->initializeWindow( xParent, aBounds, aHandlerSize );
+ return uno::Reference< embed::XHatchWindow >( static_cast< embed::XHatchWindow* >( pResult ) );
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OHatchWindowFactory::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetImplementationName();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OHatchWindowFactory::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
+
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
+ return sal_True;
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OHatchWindowFactory::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetSupportedServiceNames();
+}
+
+//-------------------------------------------------------------------------
+
+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 */, void * pRegistryKey)
+{
+ if (pRegistryKey)
+ {
+ uno::Reference< registry::XRegistryKey> xRegistryKey (
+ reinterpret_cast< registry::XRegistryKey* >(pRegistryKey));
+ uno::Reference< registry::XRegistryKey> xNewKey;
+
+ // OHatchWindowFactory registration
+
+ xNewKey = xRegistryKey->createKey (
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
+ OHatchWindowFactory::impl_staticGetImplementationName() +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );
+
+ uno::Sequence< ::rtl::OUString > aServices =
+ OHatchWindowFactory::impl_staticGetSupportedServiceNames();
+ for (sal_Int32 i = 0, n = aServices.getLength(); i < n; i++ )
+ xNewKey->createKey( aServices.getConstArray()[i] );
+
+
+ // ODocumentCloser registration
+
+ xNewKey = xRegistryKey->createKey (
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
+ ODocumentCloser::impl_staticGetImplementationName() +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );
+
+ aServices = ODocumentCloser::impl_staticGetSupportedServiceNames();
+ for (sal_Int32 i = 0, n = aServices.getLength(); i < n; i++ )
+ xNewKey->createKey( aServices.getConstArray()[i] );
+
+
+ return sal_True;
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
+ const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */)
+{
+ void * pResult = 0;
+ if (pServiceManager)
+ {
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+ if (OHatchWindowFactory::impl_staticGetImplementationName().compareToAscii (pImplementationName ) == 0)
+ {
+ xFactory = cppu::createOneInstanceFactory(
+ reinterpret_cast< lang::XMultiServiceFactory* >(pServiceManager),
+ OHatchWindowFactory::impl_staticGetImplementationName(),
+ OHatchWindowFactory::impl_staticCreateSelfInstance,
+ OHatchWindowFactory::impl_staticGetSupportedServiceNames());
+ }
+ else if (ODocumentCloser::impl_staticGetImplementationName().compareToAscii (pImplementationName ) == 0)
+ {
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
+ ODocumentCloser::impl_staticGetImplementationName(),
+ ODocumentCloser::impl_staticCreateSelfInstance,
+ ODocumentCloser::impl_staticGetSupportedServiceNames() );
+ }
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pResult = xFactory.get();
+ }
+ }
+ return pResult;
+}
+
+} // extern "C"
diff --git a/svtools/source/hatchwindow/hatchwindowfactory.hxx b/svtools/source/hatchwindow/hatchwindowfactory.hxx
new file mode 100644
index 000000000000..9a59c7a95f6d
--- /dev/null
+++ b/svtools/source/hatchwindow/hatchwindowfactory.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 _XHATCHWINDOWFACTORY_HXX_
+#define _XHATCHWINDOWFACTORY_HXX_
+
+#include <com/sun/star/embed/XHatchWindowFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+
+#ifndef _CPPUHELPER_IMPLBASE5_HXX_
+#include <cppuhelper/implbase2.hxx>
+#endif
+
+
+class OHatchWindowFactory : public ::cppu::WeakImplHelper2<
+ ::com::sun::star::embed::XHatchWindowFactory,
+ ::com::sun::star::lang::XServiceInfo >
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+public:
+ OHatchWindowFactory(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
+ : m_xFactory( xFactory )
+ {
+ OSL_ENSURE( xFactory.is(), "No service manager is provided!\n" );
+ }
+
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL impl_staticGetSupportedServiceNames();
+
+ static ::rtl::OUString SAL_CALL impl_staticGetImplementationName();
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ impl_staticCreateSelfInstance(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
+
+
+ // XHatchWindowFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XHatchWindow > SAL_CALL createHatchWindowInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParent, const ::com::sun::star::awt::Rectangle& aBounds, const ::com::sun::star::awt::Size& aSize ) 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/svtools/source/hatchwindow/ipwin.cxx b/svtools/source/hatchwindow/ipwin.cxx
new file mode 100644
index 000000000000..1beae4a54355
--- /dev/null
+++ b/svtools/source/hatchwindow/ipwin.cxx
@@ -0,0 +1,644 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+#include <vcl/svapp.hxx>
+
+#include <ipwin.hxx>
+#include <hatchwindow.hxx>
+
+/************************************************************************/
+/*************************************************************************
+|* SvResizeHelper::SvResizeHelper()
+|*
+|* Beschreibung
+*************************************************************************/
+SvResizeHelper::SvResizeHelper()
+ : aBorder( 5, 5 )
+ , nGrab( -1 )
+ , bResizeable( TRUE )
+{
+}
+
+/*************************************************************************
+|* SvResizeHelper::FillHandleRects()
+|*
+|* Beschreibung: Die acht Handles zum vergroessern
+*************************************************************************/
+void SvResizeHelper::FillHandleRectsPixel( Rectangle aRects[ 8 ] ) const
+{
+ // nur wegen EMPTY_RECT
+ Point aBottomRight = aOuter.BottomRight();
+
+ // Links Oben
+ aRects[ 0 ] = Rectangle( aOuter.TopLeft(), aBorder );
+ // Oben Mitte
+ aRects[ 1 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
+ aOuter.Top() ),
+ aBorder );
+ // Oben Rechts
+ aRects[ 2 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
+ aOuter.Top() ),
+ aBorder );
+ // Mitte Rechts
+ aRects[ 3 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
+ aOuter.Center().Y() - aBorder.Height() / 2 ),
+ aBorder );
+ // Unten Rechts
+ aRects[ 4 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
+ aBottomRight.Y() - aBorder.Height() +1 ),
+ aBorder );
+ // Mitte Unten
+ aRects[ 5 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
+ aBottomRight.Y() - aBorder.Height() +1),
+ aBorder );
+ // Links Unten
+ aRects[ 6 ] = Rectangle( Point( aOuter.Left(),
+ aBottomRight.Y() - aBorder.Height() +1),
+ aBorder );
+ // Mitte Links
+ aRects[ 7 ] = Rectangle( Point( aOuter.Left(),
+ aOuter.Center().Y() - aBorder.Height() / 2 ),
+ aBorder );
+}
+
+/*************************************************************************
+|* SvResizeHelper::FillMoveRectsPixel()
+|*
+|* Beschreibung: Die vier Kanten werden berechnet
+*************************************************************************/
+void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const
+{
+ // Oben
+ aRects[ 0 ] = aOuter;
+ aRects[ 0 ].Bottom() = aRects[ 0 ].Top() + aBorder.Height() -1;
+ // Rechts
+ aRects[ 1 ] = aOuter;
+ aRects[ 1 ].Left() = aRects[ 1 ].Right() - aBorder.Width() -1;
+ //Unten
+ aRects[ 2 ] = aOuter;
+ aRects[ 2 ].Top() = aRects[ 2 ].Bottom() - aBorder.Height() -1;
+ //Links
+ aRects[ 3 ] = aOuter;
+ aRects[ 3 ].Right() = aRects[ 3 ].Left() + aBorder.Width() -1;
+}
+
+/*************************************************************************
+|* SvResizeHelper::Draw()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeHelper::Draw( OutputDevice * pDev )
+{
+ pDev->Push();
+ pDev->SetMapMode( MapMode() );
+ Color aColBlack;
+ Color aFillColor( COL_LIGHTGRAY );
+
+ pDev->SetFillColor( aFillColor );
+ pDev->SetLineColor();
+
+ Rectangle aMoveRects[ 4 ];
+ FillMoveRectsPixel( aMoveRects );
+ USHORT i;
+ for( i = 0; i < 4; i++ )
+ pDev->DrawRect( aMoveRects[ i ] );
+ if( bResizeable )
+ {
+ // Handles malen
+ pDev->SetFillColor( aColBlack );
+ Rectangle aRects[ 8 ];
+ FillHandleRectsPixel( aRects );
+ for( i = 0; i < 8; i++ )
+ pDev->DrawRect( aRects[ i ] );
+ }
+ pDev->Pop();
+}
+
+/*************************************************************************
+|* SvResizeHelper::InvalidateBorder()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeHelper::InvalidateBorder( Window * pWin )
+{
+ Rectangle aMoveRects[ 4 ];
+ FillMoveRectsPixel( aMoveRects );
+ for( USHORT i = 0; i < 4; i++ )
+ pWin->Invalidate( aMoveRects[ i ] );
+}
+
+/*************************************************************************
+|* SvResizeHelper::SelectBegin()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SvResizeHelper::SelectBegin( Window * pWin, const Point & rPos )
+{
+ if( -1 == nGrab )
+ {
+ nGrab = SelectMove( pWin, rPos );
+ if( -1 != nGrab )
+ {
+ aSelPos = rPos; // Start-Position merken
+ pWin->CaptureMouse();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|* SvResizeHelper::SelectMove()
+|*
+|* Beschreibung
+*************************************************************************/
+short SvResizeHelper::SelectMove( Window * pWin, const Point & rPos )
+{
+ if( -1 == nGrab )
+ {
+ if( bResizeable )
+ {
+ Rectangle aRects[ 8 ];
+ FillHandleRectsPixel( aRects );
+ for( USHORT i = 0; i < 8; i++ )
+ if( aRects[ i ].IsInside( rPos ) )
+ return i;
+ }
+ // Move-Rect ueberlappen Handles
+ Rectangle aMoveRects[ 4 ];
+ FillMoveRectsPixel( aMoveRects );
+ for( USHORT i = 0; i < 4; i++ )
+ if( aMoveRects[ i ].IsInside( rPos ) )
+ return 8;
+ }
+ else
+ {
+ Rectangle aRect( GetTrackRectPixel( rPos ) );
+ aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) );
+ aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) );
+ pWin->ShowTracking( aRect );
+ }
+ return nGrab;
+}
+
+Point SvResizeHelper::GetTrackPosPixel( const Rectangle & rRect ) const
+{
+ // wie das Rechteck zurueckkommt ist egal, es zaehlt welches Handle
+ // initial angefasst wurde
+ Point aPos;
+ Rectangle aRect( rRect );
+ aRect.Justify();
+ // nur wegen EMPTY_RECT
+ Point aBR = aOuter.BottomRight();
+ Point aTR = aOuter.TopRight();
+ Point aBL = aOuter.BottomLeft();
+ switch( nGrab )
+ {
+ case 0:
+ aPos = aRect.TopLeft() - aOuter.TopLeft();
+ break;
+ case 1:
+ aPos.Y() = aRect.Top() - aOuter.Top();
+ break;
+ case 2:
+ aPos = aRect.TopRight() - aTR;
+ break;
+ case 3:
+ aPos.X() = aRect.Right() - aTR.X();
+ break;
+ case 4:
+ aPos = aRect.BottomRight() - aBR;
+ break;
+ case 5:
+ aPos.Y() = aRect.Bottom() - aBR.Y();
+ break;
+ case 6:
+ aPos = aRect.BottomLeft() - aBL;
+ break;
+ case 7:
+ aPos.X() = aRect.Left() - aOuter.Left();
+ break;
+ case 8:
+ aPos = aRect.TopLeft() - aOuter.TopLeft();
+ break;
+ }
+ return aPos += aSelPos;
+}
+
+/*************************************************************************
+|* SvResizeHelper::GetTrackRectPixel()
+|*
+|* Beschreibung
+*************************************************************************/
+Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const
+{
+ Rectangle aTrackRect;
+ if( -1 != nGrab )
+ {
+ Point aDiff = rTrackPos - aSelPos;
+ aTrackRect = aOuter;
+ Point aBR = aOuter.BottomRight();
+ switch( nGrab )
+ {
+ case 0:
+ aTrackRect.Top() += aDiff.Y();
+ aTrackRect.Left() += aDiff.X();
+ break;
+ case 1:
+ aTrackRect.Top() += aDiff.Y();
+ break;
+ case 2:
+ aTrackRect.Top() += aDiff.Y();
+ aTrackRect.Right() = aBR.X() + aDiff.X();
+ break;
+ case 3:
+ aTrackRect.Right() = aBR.X() + aDiff.X();
+ break;
+ case 4:
+ aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
+ aTrackRect.Right() = aBR.X() + aDiff.X();
+ break;
+ case 5:
+ aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
+ break;
+ case 6:
+ aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
+ aTrackRect.Left() += aDiff.X();
+ break;
+ case 7:
+ aTrackRect.Left() += aDiff.X();
+ break;
+ case 8:
+ if( Application::GetSettings().GetLayoutRTL() )
+ aDiff.X() = -aDiff.X(); // workaround for move in RTL mode
+ aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff );
+ break;
+/*
+ case 0:
+ aTrackRect = Rectangle( rTrackPos, aOuter.BottomRight() );
+ break;
+ case 1:
+ aTrackRect = Rectangle( Point( aOuter.Left(), rTrackPos.Y() ),
+ aOuter.BottomRight() );
+ break;
+ case 2:
+ aTrackRect = Rectangle( rTrackPos, aOuter.BottomLeft() );
+ break;
+ case 3:
+ aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ),
+ aOuter.BottomLeft() );
+ break;
+ case 4:
+ aTrackRect = Rectangle( rTrackPos, aOuter.TopLeft() );
+ break;
+ case 5:
+ aTrackRect = Rectangle( aOuter.TopLeft(),
+ Point( aOuter.Right(), rTrackPos.Y() ) );
+ break;
+ case 6:
+ aTrackRect = Rectangle( aOuter.TopRight(), rTrackPos );
+ break;
+ case 7:
+ aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ),
+ aOuter.BottomRight() );
+ break;
+ case 8:
+ aTrackRect = Rectangle( aOuter.TopLeft() + rTrackPos - aSelPos,
+ aOuter.GetSize() );
+ break;
+*/
+ }
+ }
+ return aTrackRect;
+}
+
+void SvResizeHelper::ValidateRect( Rectangle & rValidate ) const
+{
+ switch( nGrab )
+ {
+ case 0:
+ if( rValidate.Top() > rValidate.Bottom() )
+ {
+ rValidate.Top() = rValidate.Bottom();
+ rValidate.Bottom() = RECT_EMPTY;
+ }
+ if( rValidate.Left() > rValidate.Right() )
+ {
+ rValidate.Left() = rValidate.Right();
+ rValidate.Right() = RECT_EMPTY;
+ }
+ break;
+ case 1:
+ if( rValidate.Top() > rValidate.Bottom() )
+ {
+ rValidate.Top() = rValidate.Bottom();
+ rValidate.Bottom() = RECT_EMPTY;
+ }
+ break;
+ case 2:
+ if( rValidate.Top() > rValidate.Bottom() )
+ {
+ rValidate.Top() = rValidate.Bottom();
+ rValidate.Bottom() = RECT_EMPTY;
+ }
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.Right() = RECT_EMPTY;
+ break;
+ case 3:
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.Right() = RECT_EMPTY;
+ break;
+ case 4:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.Bottom() = RECT_EMPTY;
+ if( rValidate.Left() > rValidate.Right() )
+ rValidate.Right() = RECT_EMPTY;
+ break;
+ case 5:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.Bottom() = RECT_EMPTY;
+ break;
+ case 6:
+ if( rValidate.Top() > rValidate.Bottom() )
+ rValidate.Bottom() = RECT_EMPTY;
+ if( rValidate.Left() > rValidate.Right() )
+ {
+ rValidate.Left() = rValidate.Right();
+ rValidate.Right() = RECT_EMPTY;
+ }
+ break;
+ case 7:
+ if( rValidate.Left() > rValidate.Right() )
+ {
+ rValidate.Left() = rValidate.Right();
+ rValidate.Right() = RECT_EMPTY;
+ }
+ break;
+ }
+ if( rValidate.Right() == RECT_EMPTY )
+ rValidate.Right() = rValidate.Left();
+ if( rValidate.Bottom() == RECT_EMPTY )
+ rValidate.Bottom() = rValidate.Top();
+
+ // Mindestgr"osse 5 x 5
+ if( rValidate.Left() + 5 > rValidate.Right() )
+ rValidate.Right() = rValidate.Left() +5;
+ if( rValidate.Top() + 5 > rValidate.Bottom() )
+ rValidate.Bottom() = rValidate.Top() +5;
+}
+
+/*************************************************************************
+|* SvResizeHelper::SelectRelease()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SvResizeHelper::SelectRelease( Window * pWin, const Point & rPos,
+ Rectangle & rOutPosSize )
+{
+ if( -1 != nGrab )
+ {
+ rOutPosSize = GetTrackRectPixel( rPos );
+ rOutPosSize.Justify();
+ nGrab = -1;
+ pWin->ReleaseMouse();
+ pWin->HideTracking();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|* SvResizeHelper::Release()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeHelper::Release( Window * pWin )
+{
+ if( nGrab != -1 )
+ {
+ pWin->ReleaseMouse();
+ pWin->HideTracking();
+ nGrab = -1;
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::SvResizeWindow()
+|*
+|* Beschreibung
+*************************************************************************/
+SvResizeWindow::SvResizeWindow
+(
+ Window * pParent,
+ VCLXHatchWindow* pWrapper
+)
+ : Window( pParent, WB_CLIPCHILDREN )
+ , m_nMoveGrab( -1 )
+ , m_bActive( sal_False )
+ , m_pWrapper( pWrapper )
+{
+ OSL_ENSURE( pParent != NULL && pWrapper != NULL, "Wrong initialization of hatch window!\n" );
+ SetBackground();
+ SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT );
+ m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
+}
+
+/*************************************************************************
+|* SvResizeWindow::SetHatchBorderPixel()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::SetHatchBorderPixel( const Size & rSize )
+{
+ m_aResizer.SetBorderPixel( rSize );
+}
+
+/*************************************************************************
+|* SvResizeWindow::SelectMouse()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::SelectMouse( const Point & rPos )
+{
+ short nGrab = m_aResizer.SelectMove( this, rPos );
+ if( nGrab >= 4 )
+ nGrab -= 4;
+ if( m_nMoveGrab != nGrab )
+ { // Pointer hat sich geaendert
+ if( -1 == nGrab )
+ SetPointer( m_aOldPointer );
+ else
+ {
+ PointerStyle aStyle = POINTER_MOVE;
+ if( nGrab == 3 )
+ aStyle = POINTER_ESIZE;
+ else if( nGrab == 2 )
+ aStyle = POINTER_NESIZE;
+ else if( nGrab == 1 )
+ aStyle = POINTER_SSIZE;
+ else if( nGrab == 0 )
+ aStyle = POINTER_SESIZE;
+ if( m_nMoveGrab == -1 ) // das erste mal
+ {
+ m_aOldPointer = GetPointer();
+ SetPointer( Pointer( aStyle ) );
+ }
+ else
+ SetPointer( Pointer( aStyle ) );
+ }
+ m_nMoveGrab = nGrab;
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::MouseButtonDown()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt )
+{
+ if( m_aResizer.SelectBegin( this, rEvt.GetPosPixel() ) )
+ SelectMouse( rEvt.GetPosPixel() );
+}
+
+/*************************************************************************
+|* SvResizeWindow::MouseMove()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::MouseMove( const MouseEvent & rEvt )
+{
+ if( m_aResizer.GetGrab() == -1 )
+ SelectMouse( rEvt.GetPosPixel() );
+ else
+ {
+ Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) );
+ Point aDiff = GetPosPixel();
+ aRect.SetPos( aRect.TopLeft() + aDiff );
+ m_aResizer.ValidateRect( aRect );
+
+ m_pWrapper->QueryObjAreaPixel( aRect );
+ aRect.SetPos( aRect.TopLeft() - aDiff );
+ Point aPos = m_aResizer.GetTrackPosPixel( aRect );
+
+ SelectMouse( aPos );
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::MouseButtonUp()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::MouseButtonUp( const MouseEvent & rEvt )
+{
+ if( m_aResizer.GetGrab() != -1 )
+ {
+ Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) );
+ Point aDiff = GetPosPixel();
+ aRect.SetPos( aRect.TopLeft() + aDiff );
+ // aRect -= GetAllBorderPixel();
+ m_aResizer.ValidateRect( aRect );
+
+ m_pWrapper->QueryObjAreaPixel( aRect );
+
+ Rectangle aOutRect;
+ if( m_aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) )
+ {
+ m_nMoveGrab = -1;
+ SetPointer( m_aOldPointer );
+ m_pWrapper->RequestObjAreaPixel( aRect );
+ }
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::KeyEvent()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::KeyInput( const KeyEvent & rEvt )
+{
+ if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE )
+ {
+ m_aResizer.Release( this );
+ m_pWrapper->InplaceDeactivate();
+ }
+}
+
+/*************************************************************************
+|* SvResizeWindow::Resize()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::Resize()
+{
+ m_aResizer.InvalidateBorder( this ); // alten Bereich
+ m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
+ m_aResizer.InvalidateBorder( this ); // neuen Bereich
+}
+
+/*************************************************************************
+|* SvResizeWindow::Paint()
+|*
+|* Beschreibung
+*************************************************************************/
+void SvResizeWindow::Paint( const Rectangle & /*rRect*/ )
+{
+ m_aResizer.Draw( this );
+}
+
+long SvResizeWindow::PreNotify( NotifyEvent& rEvt )
+{
+ if ( rEvt.GetType() == EVENT_GETFOCUS && !m_bActive )
+ {
+ m_bActive = sal_True;
+ m_pWrapper->Activated();
+ }
+
+ return Window::PreNotify(rEvt);
+}
+
+long SvResizeWindow::Notify( NotifyEvent& rEvt )
+{
+ if ( rEvt.GetType() == EVENT_LOSEFOCUS && m_bActive )
+ {
+ BOOL bHasFocus = HasChildPathFocus(TRUE);
+ if ( !bHasFocus )
+ {
+ m_bActive = sal_False;
+ m_pWrapper->Deactivated();
+ }
+ }
+
+ return Window::Notify(rEvt);
+}
+
diff --git a/svtools/source/hatchwindow/ipwin.hxx b/svtools/source/hatchwindow/ipwin.hxx
new file mode 100644
index 000000000000..4c7cb6d88d36
--- /dev/null
+++ b/svtools/source/hatchwindow/ipwin.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 _IPWIN_HXX
+#define _IPWIN_HXX
+
+#include <tools/gen.hxx>
+#include <vcl/window.hxx>
+#include <tools/svborder.hxx>
+
+/********************** SvResizeHelper ***********************************
+*************************************************************************/
+class SvResizeHelper
+{
+ Size aBorder;
+ Rectangle aOuter;
+ short nGrab; // -1 kein Grab, 0 - 7, 8 = Move, siehe FillHandle...
+ Point aSelPos;
+ BOOL bResizeable;
+public:
+ SvResizeHelper();
+
+ void SetResizeable( BOOL b ) { bResizeable = b; }
+ short GetGrab() const { return nGrab; }
+ void SetBorderPixel( const Size & rBorderP )
+ { aBorder = rBorderP; }
+ const Size & GetBorderPixel() const { return aBorder; }
+ const Rectangle & GetOuterRectPixel() const
+ { return aOuter; }
+ void SetOuterRectPixel( const Rectangle & rRect )
+ { aOuter = rRect; }
+ Rectangle GetInnerRectPixel() const
+ {
+ Rectangle aRect( aOuter );
+ aRect.Top() += aBorder.Height();
+ aRect.Left() += aBorder.Width();
+ aRect.Bottom() -= aBorder.Height();
+ aRect.Right() -= aBorder.Width();
+ return aRect;
+ }
+ // Im Uhrzeigersinn, beginnend bei Linksoben
+ void FillHandleRectsPixel( Rectangle aRects[ 8 ] ) const;
+ void FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const;
+ void Draw( OutputDevice * );
+ void InvalidateBorder( Window * );
+ BOOL SelectBegin( Window *, const Point & rPos );
+ short SelectMove( Window * pWin, const Point & rPos );
+ Point GetTrackPosPixel( const Rectangle & rRect ) const;
+ Rectangle GetTrackRectPixel( const Point & rTrackPos ) const;
+ void ValidateRect( Rectangle & rValidate ) const;
+ BOOL SelectRelease( Window *, const Point & rPos, Rectangle & rOutPosSize );
+ void Release( Window * pWin );
+};
+
+/********************** SvResizeWindow ***********************************
+*************************************************************************/
+class VCLXHatchWindow;
+class SvResizeWindow : public Window
+{
+ Pointer m_aOldPointer;
+ short m_nMoveGrab; // Letzer Pointertyp
+ SvResizeHelper m_aResizer;
+ sal_Bool m_bActive;
+
+ VCLXHatchWindow* m_pWrapper;
+public:
+ SvResizeWindow( Window* pParent, VCLXHatchWindow* pWrapper );
+
+ void SetHatchBorderPixel( const Size & rSize );
+
+ void SelectMouse( const Point & rPos );
+ virtual void MouseButtonUp( const MouseEvent & rEvt );
+ virtual void MouseMove( const MouseEvent & rEvt );
+ virtual void MouseButtonDown( const MouseEvent & rEvt );
+ virtual void KeyInput( const KeyEvent & rEvt );
+ virtual void Resize();
+ virtual void Paint( const Rectangle & );
+ virtual long Notify( NotifyEvent& rNEvt );
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ void QueryObjAreaPixel( Rectangle & );
+ void RequestObjAreaPixel( const Rectangle & );
+};
+
+#endif // _IPWIN_HXX
+
diff --git a/svtools/source/hatchwindow/makefile.mk b/svtools/source/hatchwindow/makefile.mk
new file mode 100644
index 000000000000..316e4ab1bfe2
--- /dev/null
+++ b/svtools/source/hatchwindow/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=svtools
+TARGET=hatchwindowfactory.uno
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE=
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/hatchwindow.obj\
+ $(SLO)$/hatchwindowfactory.obj\
+ $(SLO)$/documentcloser.obj\
+ $(SLO)$/ipwin.obj
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+SHL1OBJS= $(SLOFILES)
+SHL1STDLIBS=\
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(TOOLSLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/inc/accessibletableimp.hxx b/svtools/source/inc/accessibletableimp.hxx
new file mode 100644
index 000000000000..3a01c01567d3
--- /dev/null
+++ b/svtools/source/inc/accessibletableimp.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 SVTOOLS_SOURCE_INC_ACCESSIBLETABLEIMP_HXX
+#define SVTOOLS_SOURCE_INC_ACCESSIBLETABLEIMP_HXX
+
+#include "svtaccessiblefactory.hxx"
+
+namespace svt { namespace table
+{
+//........................................................................
+
+
+ class AccessibleTableControl_Impl
+ {
+ public:
+ AccessibleFactoryAccess m_aFactoryAccess;
+ IAccessibleTableControl* m_pAccessible;
+
+ public:
+ AccessibleTableControl_Impl() : m_pAccessible(NULL)
+ {
+ }
+
+
+ /// @see AccessibleTableControl::getTableRowHeader
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ getAccessibleTableHeader( AccessibleTableControlObjType _eObjType );
+ /// @see AccessibleTableControl::getTable
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ getAccessibleTable( );
+
+ };
+
+//........................................................................
+} } // namespace svt::table
+//........................................................................
+
+#endif // SVTOOLS_SOURCE_INC_ACCESSIBLETABLEIMP_HXX
diff --git a/svtools/source/inc/configitems/accessibilityoptions_const.hxx b/svtools/source/inc/configitems/accessibilityoptions_const.hxx
new file mode 100644
index 000000000000..177edce8c3f0
--- /dev/null
+++ b/svtools/source/inc/configitems/accessibilityoptions_const.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifndef INCLUDE_CONFIGITEMS_ACCESSIBILITYOPTIONS_CONST_HXX
+#define INCLUDE_CONFIGITEMS_ACCESSIBILITYOPTIONS_CONST_HXX
+
+#include <rtl/ustring.hxx>
+
+namespace
+{
+ static const ::rtl::OUString s_sAccessibility = ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/Accessibility");
+ static const ::rtl::OUString s_sAutoDetectSystemHC = ::rtl::OUString::createFromAscii("AutoDetectSystemHC");
+ static const ::rtl::OUString s_sIsForPagePreviews = ::rtl::OUString::createFromAscii("IsForPagePreviews");
+ static const ::rtl::OUString s_sIsHelpTipsDisappear = ::rtl::OUString::createFromAscii("IsHelpTipsDisappear");
+ static const ::rtl::OUString s_sHelpTipSeconds = ::rtl::OUString::createFromAscii("HelpTipSeconds");
+ static const ::rtl::OUString s_sIsAllowAnimatedGraphics = ::rtl::OUString::createFromAscii("IsAllowAnimatedGraphics");
+ static const ::rtl::OUString s_sIsAllowAnimatedText = ::rtl::OUString::createFromAscii("IsAllowAnimatedText");
+ static const ::rtl::OUString s_sIsAutomaticFontColor = ::rtl::OUString::createFromAscii("IsAutomaticFontColor");
+ static const ::rtl::OUString s_sIsSystemFont = ::rtl::OUString::createFromAscii("IsSystemFont");
+ static const ::rtl::OUString s_sIsSelectionInReadonly = ::rtl::OUString::createFromAscii("IsSelectionInReadonly");
+}
+
+#endif // INCLUDE_CONFIGITEMS_ACCESSIBILITYOPTIONS_CONST_HXX
diff --git a/svtools/source/inc/filectrl.hrc b/svtools/source/inc/filectrl.hrc
new file mode 100644
index 000000000000..1707e306e1b0
--- /dev/null
+++ b/svtools/source/inc/filectrl.hrc
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SV_FILECTRL_HRC
+#define _SV_FILECTRL_HRC
+
+#define STR_FILECTRL_BUTTONTEXT 333 // ID-Range?!
+
+#endif
+
diff --git a/svtools/source/inc/gifread.hxx b/svtools/source/inc/gifread.hxx
new file mode 100644
index 000000000000..de4c6935ef67
--- /dev/null
+++ b/svtools/source/inc/gifread.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 _GIFREAD_HXX
+#define _GIFREAD_HXX
+
+#ifndef _GRAPH_HXX
+#include <vcl/graph.hxx>
+#endif
+#ifndef _BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+
+#ifdef _GIFPRIVATE
+
+// ---------
+// - Enums -
+// ---------
+
+enum GIFAction
+{
+ GLOBAL_HEADER_READING,
+ MARKER_READING,
+ EXTENSION_READING,
+ LOCAL_HEADER_READING,
+ FIRST_BLOCK_READING,
+ NEXT_BLOCK_READING,
+ ABORT_READING,
+ END_READING
+};
+
+// ------------------------------------------------------------------------
+
+enum ReadState
+{
+ GIFREAD_OK,
+ GIFREAD_ERROR,
+ GIFREAD_NEED_MORE
+};
+
+// -------------
+// - GIFReader -
+// -------------
+
+class GIFLZWDecompressor;
+
+class SvStream;
+
+class GIFReader : public GraphicReader
+{
+ Graphic aImGraphic;
+ Animation aAnimation;
+ Bitmap aBmp8;
+ Bitmap aBmp1;
+ BitmapPalette aGPalette;
+ BitmapPalette aLPalette;
+ SvStream& rIStm;
+ void* pCallerData;
+ HPBYTE pSrcBuf;
+ GIFLZWDecompressor* pDecomp;
+ BitmapWriteAccess* pAcc8;
+ BitmapWriteAccess* pAcc1;
+ long nYAcc;
+ long nLastPos;
+ sal_uInt32 nLogWidth100;
+ sal_uInt32 nLogHeight100;
+ USHORT nTimer;
+ USHORT nGlobalWidth; // maximale Bildbreite aus Header
+ USHORT nGlobalHeight; // maximale Bildhoehe aus Header
+ USHORT nImageWidth; // maximale Bildbreite aus Header
+ USHORT nImageHeight; // maximale Bildhoehe aus Header
+ USHORT nImagePosX;
+ USHORT nImagePosY;
+ USHORT nImageX; // maximale Bildbreite aus Header
+ USHORT nImageY; // maximale Bildhoehe aus Header
+ USHORT nLastImageY;
+ USHORT nLastInterCount;
+ USHORT nLoops;
+ GIFAction eActAction;
+ BOOL bStatus;
+ BOOL bGCTransparent; // Ob das Bild Transparent ist, wenn ja:
+ BOOL bInterlaced;
+ BOOL bOverreadBlock;
+ BOOL bImGraphicReady;
+ BOOL bGlobalPalette;
+ BYTE nBackgroundColor; // Hintergrundfarbe
+ BYTE nGCTransparentIndex; // Pixel von diesem Index sind durchsichtig
+ BYTE nGCDisposalMethod; // 'Disposal Method' (siehe GIF-Doku)
+ BYTE cTransIndex1;
+ BYTE cNonTransIndex1;
+
+ void ReadPaletteEntries( BitmapPalette* pPal, ULONG nCount );
+ void ClearImageExtensions();
+ BOOL CreateBitmaps( long nWidth, long nHeight, BitmapPalette* pPal, BOOL bWatchForBackgroundColor );
+ BOOL ReadGlobalHeader();
+ BOOL ReadExtension();
+ BOOL ReadLocalHeader();
+ ULONG ReadNextBlock();
+ void FillImages( HPBYTE pBytes, ULONG nCount );
+ void CreateNewBitmaps();
+ BOOL ProcessGIF();
+
+public:
+
+ ReadState ReadGIF( Graphic& rGraphic );
+ const Graphic& GetIntermediateGraphic();
+
+ GIFReader( SvStream& rStm );
+ virtual ~GIFReader();
+};
+
+#endif // _GIFPRIVATE
+
+// -------------
+// - ImportGIF -
+// -------------
+
+ BOOL ImportGIF( SvStream& rStream, Graphic& rGraphic );
+
+#endif // _GIFREAD_HXX
diff --git a/svtools/source/inc/gradwrap.hxx b/svtools/source/inc/gradwrap.hxx
new file mode 100644
index 000000000000..41887b67822a
--- /dev/null
+++ b/svtools/source/inc/gradwrap.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 _SVGEN_HXX
+#include <svgen.hxx>
+#endif
+
+
+/******************************************************************************
+|*
+|* class GradientWrapper
+|*
+|* Ersterstellung: KA 24.11.95
+|* letzte Aenderung: KA 24.11.95
+|*
+|* Zeck: dient beim MetaFile-Export dazu, die eigentliche Berechungs-
+|* funktionalitaet zu kapseln. Das Schreiben der Records fuer
+|* die unterschiedlichen File-Formate geschieht ueber LinkHandler.
+|*
+|* Klassen, die diesen Wrapper benutzen, muessen drei Linkhandler
+|* zur Verfuegung stellen, die im Ctor uebergeben werden:
+|*
+|* 1. Linkhandler zum Schreiben eines Records fuer Polygonausgabe
+|* 2. Linkhandler zum Schreiben eines Records fuer PolyPolygonausgabe
+|* 3. Linkhandler zum Schreiben eines Records fuer Setzen der Brush
+|*
+\******************************************************************************/
+
+
+class GradientWrapper
+{
+ Link aDrawPolyRecordHdl;
+ Link aDrawPolyPolyRecordHdl;
+ Link aSetFillInBrushRecordHdl;
+
+ GradientWrapper() {};
+
+
+public:
+ GradientWrapper(const Link& rDrawPolyRecordHdl,
+ const Link& rDrawPolyPolyRecordHdl,
+ const Link& rSetFillInBrushHdl);
+ ~GradientWrapper();
+
+
+ void WriteLinearGradient(const Rectangle& rRect,
+ const Gradient& rGradient);
+ void WriteRadialGradient(const Rectangle& rRect,
+ const Gradient& rGradient);
+ void WriteRectGradient(const Rectangle& rRect,
+ const Gradient& rGradient);
+};
diff --git a/svtools/source/inc/iodlg.hrc b/svtools/source/inc/iodlg.hrc
new file mode 100644
index 000000000000..e78e3fb687fe
--- /dev/null
+++ b/svtools/source/inc/iodlg.hrc
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _SVTOOLS_IODLGIMPL_HRC
+#define _SVTOOLS_IODLGIMPL_HRC
+
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+// ModalDialog DLG_SVT_EXPLORERFILE
+
+#define FT_EXPLORERFILE_CURRENTPATH 10
+#define BTN_EXPLORERFILE_NEWFOLDER 11
+#define BTN_EXPLORERFILE_LISTVIEW 12
+#define BTN_EXPLORERFILE_DETAILSVIEW 13
+#define BTN_EXPLORERFILE_UP 14
+#define BTN_EXPLORERFILE_STANDARD 15
+#define BTN_EXPLORERFILE_OPEN 16
+#define BTN_EXPLORERFILE_CANCEL 17
+#define BTN_EXPLORERFILE_HELP 18
+
+#define IMG_FILEDLG_BTN_UP 10
+#define IMG_FILEDLG_BTN_STD 11
+#define IMG_FILEDLG_CREATEFOLDER 15
+
+#define CTL_EXPLORERFILE_FILELIST 20
+
+#define FT_EXPLORERFILE_FILENAME 30
+#define ED_EXPLORERFILE_FILENAME 31
+#define FT_EXPLORERFILE_SHARED_LISTBOX 32
+#define LB_EXPLORERFILE_SHARED_LISTBOX 33
+#define FT_EXPLORERFILE_FILETYPE 34
+#define LB_EXPLORERFILE_FILETYPE 35
+
+#define CB_EXPLORERFILE_READONLY 40
+#define CB_EXPLORERFILE_PASSWORD 41
+#define CB_AUTO_EXTENSION 42
+#define CB_OPTIONS 43
+
+// -----------------------------------------------
+
+#define STR_EXPLORERFILE_OPEN 1
+#define STR_EXPLORERFILE_SAVE 2
+#define STR_EXPLORERFILE_BUTTONSAVE 3
+#define STR_PATHNAME 4
+#define STR_PATHSELECT 5
+#define STR_BUTTONSELECT 6
+#define STR_ACTUALVERSION 7
+
+// DLG_SVT_QUERYFOLDERNAME -----------------------
+
+#define FT_SVT_QUERYFOLDERNAME_DLG_NAME 10
+#define ED_SVT_QUERYFOLDERNAME_DLG_NAME 11
+#define FL_SVT_QUERYFOLDERNAME_DLG_NAME 12
+#define BT_SVT_QUERYFOLDERNAME_DLG_OK 13
+#define BT_SVT_QUERYFOLDERNAME_DLG_CANCEL 14
+#define BT_SVT_QUERYFOLDERNAME_DLG_HELP 15
+
+// -----------------------------------------------
+
+#define SID_SFX_START 5000
+#define SID_OPENURL (SID_SFX_START + 596)
+
+#define HID_FILEDLG_STANDARD (HID_SFX_START + 27)
+#define HID_FILEDLG_MANAGER (HID_SFX_START + 28)
+#define HID_FILEDLG_URL (HID_SFX_START + 29)
+#define HID_FILEDLG_USE_PASSWD (HID_SFX_START + 31)
+#define HID_FILEDLG_READ_ONLY (HID_SFX_START + 32)
+
+#define HID_FILEDLG_AUTOCOMPLETEBOX (HID_SFX_START + 218)
+#define HID_FILEDLG_SAVE_BTN (HID_SFX_START + 219)
+#define HID_FILEDLG_SAVE_FILENAME (HID_SFX_START + 220)
+#define HID_FILEDLG_SAVE_FILETYPE (HID_SFX_START + 221)
+#define HID_FILEDLG_INSERT_BTN (HID_SFX_START + 222)
+#define HID_FILEDLG_PATH_BTN (HID_SFX_START + 223)
+#define HID_FILEDLG_PATH_FILENAME (HID_SFX_START + 224)
+#define HID_FILEDLG_FOLDER_BTN (HID_SFX_START + 225)
+#define HID_FILEDLG_FOLDER_FILENAME (HID_SFX_START + 226)
+#define HID_FILEDLG_SRCHFOLDER_BTN (HID_SFX_START + 227)
+
+#endif
+
diff --git a/svtools/source/inc/jpeg.hxx b/svtools/source/inc/jpeg.hxx
new file mode 100644
index 000000000000..9923190c5e21
--- /dev/null
+++ b/svtools/source/inc/jpeg.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _JPEG_HXX
+#define _JPEG_HXX
+
+#ifndef _GRAPH_HXX
+#include <vcl/graph.hxx>
+#endif
+#include <svtools/fltcall.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+
+#ifdef _JPEGPRIVATE
+
+// --------
+// - Enum -
+// --------
+
+enum ReadState
+{
+ JPEGREAD_OK,
+ JPEGREAD_ERROR,
+ JPEGREAD_NEED_MORE
+};
+
+// --------------
+// - JPEGReader -
+// --------------
+
+class JPEGReader : public GraphicReader
+{
+ SvStream& rIStm;
+ Bitmap aBmp;
+ Bitmap aBmp1;
+ BitmapWriteAccess* pAcc;
+ BitmapWriteAccess* pAcc1;
+ void* pBuffer;
+ long nLastPos;
+ long nFormerPos;
+ long nLastLines;
+ sal_Bool bSetLogSize;
+
+ Graphic CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines );
+ void FillBitmap();
+
+public:
+
+ void* CreateBitmap( void* JPEGCreateBitmapParam );
+
+public:
+
+
+
+ JPEGReader( SvStream& rStm, void* pCallData, sal_Bool bSetLogSize );
+ virtual ~JPEGReader();
+
+
+ ReadState Read( Graphic& rGraphic );
+};
+
+// --------------
+// - JPEGWriter -
+// --------------
+
+class JPEGWriter
+{
+ SvStream& rOStm;
+ Bitmap aBmp;
+ BitmapReadAccess* pAcc;
+ BYTE* pBuffer;
+ BOOL bNative;
+
+ sal_Bool bGreys;
+ sal_Int32 nQuality;
+
+ bool* pExpWasGrey;
+
+ com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
+
+public:
+
+ void* GetScanline( long nY );
+
+ JPEGWriter( SvStream& rOStm, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
+ bool* pExportWasGrey = NULL );
+ ~JPEGWriter() {};
+
+ BOOL Write( const Graphic& rGraphic );
+};
+
+#endif // _JPEGPRIVATE
+
+// ---------------------
+// - Import/ExportJPEG -
+// ---------------------
+
+BOOL ImportJPEG( SvStream& rStream, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags );
+
+BOOL ExportJPEG( SvStream& rStream,
+ const Graphic& rGraphic,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
+ bool* pExportWasGrey = NULL
+ );
+
+#endif // _JPEG_HXX
diff --git a/svtools/source/inc/msgrd.hxx b/svtools/source/inc/msgrd.hxx
new file mode 100644
index 000000000000..2d3dcccb1244
--- /dev/null
+++ b/svtools/source/inc/msgrd.hxx
@@ -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 _MSGRD_HXX
+#define _MSGRD_HXX
+
+
+BOOL ConvertMSGToGDIMetaFile( SvStream & rMSG, GDIMetaFile & rGDIMetaFile,
+ BOOL(*pCallback)(void *, USHORT), void * pCallerData,
+ ULONG nMinPercent, ULONG nMaxPercent);
+
+
+#endif // _MSGRD_HXX
diff --git a/svtools/source/inc/msgwr.hxx b/svtools/source/inc/msgwr.hxx
new file mode 100644
index 000000000000..7e72e98c124c
--- /dev/null
+++ b/svtools/source/inc/msgwr.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _MSGWR_HXX
+#define _MSGWR_HXX
+
+
+BOOL ConvertGraphicToMSG(const Graphic & rGraphic, SvStream & rTargetStream,
+ BOOL(*pCallback)(void *, USHORT), void * pCallerData,
+ ULONG nMinPercent, ULONG nMaxPercent);
+
+
+#endif // _MSGWR_HXX
+
diff --git a/svtools/source/inc/property.hxx b/svtools/source/inc/property.hxx
new file mode 100644
index 000000000000..689da1faf140
--- /dev/null
+++ b/svtools/source/inc/property.hxx
@@ -0,0 +1,585 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SV_PROPERTY_HXX
+#define SV_PROPERTY_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_GROUP_HXX
+#include <vcl/group.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 <vcl/combobox.hxx>
+#include <vcl/field.hxx>
+#include <svl/svarray.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/scrbar.hxx>
+#include <svl/svarray.hxx>
+
+#ifndef _SVSTDARR_STRINGS
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+#endif
+#include <vcl/tabpage.hxx>
+#include <vcl/tabctrl.hxx>
+
+//------------------------------------------------------------------------
+
+//========================================================================
+enum eKindOfControl { KOC_UNDEFINED=0,KOC_LISTBOX=1, KOC_COMBOBOX=2,
+ KOC_EDIT=3,KOC_USERDEFINED=5};
+
+class SvXPropertyCtrListener;
+
+class SvXPropertyControl : public Control
+{
+public:
+ SvXPropertyControl( Window* pParent, WinBits nWinStyle = 0 );
+ SvXPropertyControl( Window* pParent, const ResId& rResId );
+
+ virtual void SetSvXPropertyCtrListener(SvXPropertyCtrListener*)=0;
+
+ virtual SvXPropertyCtrListener* GetSvXPropertyCtrListener()=0;
+ virtual void SetProperty(const String &rString)=0;
+ virtual String GetProperty()const=0;
+ virtual BOOL HasList()=0;
+ virtual void ClearList()=0;
+ virtual void InsertEntry( const String& rString,
+ USHORT nPos = LISTBOX_APPEND )=0;
+
+ virtual void SetCtrSize(const Size& rSize)=0;
+ virtual void SetLocked(BOOL bLocked=TRUE)=0;
+
+ virtual void SetMyName(const String &rString)=0;
+ virtual String GetMyName()const=0;
+
+ virtual void SetMyData(void*)=0;
+ virtual void* GetMyData()=0;
+};
+
+class SvXPropertyCtrListener
+{
+
+public:
+ virtual void Modified (SvXPropertyControl *pSvXPCtr)=0;
+ virtual void GetFocus (SvXPropertyControl *pSvXPCtr)=0;
+ virtual void LoseFocus(SvXPropertyControl *pSvXPCtr)=0;
+ virtual void KeyInput (SvXPropertyControl *pSvXPCtr ,const KeyCode&)=0;
+};
+
+
+class SvXPropertyEdit : public SvXPropertyControl
+{
+private:
+
+ String aName;
+ SvXPropertyCtrListener* pListener;
+ Edit aEdit;
+ void* pData;
+
+ DECL_LINK(ModifiedHdl,Edit*);
+ DECL_LINK(GetFocusHdl,Edit*);
+ DECL_LINK(LoseFocusHdl,Edit*);
+
+public:
+ SvXPropertyEdit( Window* pParent, WinBits nWinStyle = 0 );
+ SvXPropertyEdit( Window* pParent, const ResId& rResId );
+
+ virtual void SetSvXPropertyCtrListener(SvXPropertyCtrListener*);
+
+ virtual SvXPropertyCtrListener* GetSvXPropertyCtrListener();
+
+ virtual void SetProperty(const String &rString);
+ virtual String GetProperty()const;
+
+ virtual BOOL HasList();
+ virtual void ClearList();
+ virtual void InsertEntry( const String& rString,
+ USHORT nPos = LISTBOX_APPEND );
+
+ virtual void SetCtrSize(const Size& rSize);
+ virtual void SetLocked(BOOL bLocked=TRUE);
+
+ virtual void SetMyName(const String &rString);
+ virtual String GetMyName()const;
+
+ virtual void SetMyData(void*);
+ virtual void* GetMyData();
+};
+
+
+class SvXPropertyListBox : public SvXPropertyControl
+{
+private:
+
+ String aName;
+ SvXPropertyCtrListener* pListener;
+ ListBox aListBox;
+ void* pData;
+
+ DECL_LINK(ModifiedHdl,ListBox*);
+ DECL_LINK(GetFocusHdl,ListBox*);
+ DECL_LINK(LoseFocusHdl,ListBox*);
+
+
+public:
+ SvXPropertyListBox( Window* pParent, WinBits nWinStyle = 0 );
+ SvXPropertyListBox( Window* pParent, const ResId& rResId );
+
+ virtual void SetSvXPropertyCtrListener(SvXPropertyCtrListener*);
+
+ virtual SvXPropertyCtrListener* GetSvXPropertyCtrListener();
+
+ ListBox* GetListBox();
+
+ virtual void SetProperty(const String &rString);
+ virtual String GetProperty()const;
+
+ virtual BOOL HasList();
+ virtual void ClearList();
+ virtual void InsertEntry( const String& rString,
+ USHORT nPos = LISTBOX_APPEND );
+
+ virtual void SetCtrSize(const Size& rSize);
+ virtual void SetLocked(BOOL bLocked=TRUE);
+
+ virtual void SetMyName(const String &rString);
+ virtual String GetMyName()const;
+
+ virtual void SetMyData(void*);
+ virtual void* GetMyData();
+};
+
+class SvXPropertyComboBox : public SvXPropertyControl
+{
+private:
+
+ String aName;
+ SvXPropertyCtrListener* pListener;
+ ComboBox aComboBox;
+ void* pData;
+
+ DECL_LINK(ModifiedHdl,ComboBox*);
+ DECL_LINK(GetFocusHdl,ComboBox*);
+ DECL_LINK(LoseFocusHdl,ComboBox*);
+
+
+public:
+ SvXPropertyComboBox( Window* pParent, WinBits nWinStyle = 0 );
+ SvXPropertyComboBox( Window* pParent, const ResId& rResId );
+
+ virtual void SetSvXPropertyCtrListener(SvXPropertyCtrListener*);
+
+ virtual SvXPropertyCtrListener* GetSvXPropertyCtrListener();
+
+ ComboBox* GetComboBox();
+
+ virtual void SetProperty(const String &rString);
+ virtual String GetProperty()const;
+
+ virtual BOOL HasList();
+ virtual void ClearList();
+ virtual void InsertEntry( const String& rString,
+ USHORT nPos = LISTBOX_APPEND );
+
+ virtual void SetCtrSize(const Size& rSize);
+ virtual void SetLocked(BOOL bLocked=TRUE);
+
+ virtual void SetMyName(const String &rString);
+ virtual String GetMyName()const;
+
+ virtual void SetMyData(void*);
+ virtual void* GetMyData();
+};
+
+
+
+class SvPropertyLine : public Control
+{
+private:
+ FixedText aName;
+ USHORT nNameWidth;
+ BOOL bNeedsRepaint;
+ SvXPropertyControl* pSvXPropertyControl;
+
+ PushButton aXButton;
+ BOOL bIsLocked;
+ BOOL bHasXButton;
+ BOOL bIsHyperlink;
+ eKindOfControl eKindOfCtr;
+
+protected:
+ virtual void Resize();
+
+public:
+ SvPropertyLine( Window* pParent,
+ WinBits nWinStyle = 0 );
+ SvPropertyLine( Window* pParent,
+ const ResId& rResId );
+
+ BOOL NeedsRepaint();
+ void SetNeedsRepaint(BOOL bFlag);
+ void SetSvXPropertyControl(SvXPropertyControl*);
+ SvXPropertyControl* GetSvXPropertyControl();
+
+ void SetKindOfControl(eKindOfControl);
+ eKindOfControl GetKindOfControl();
+
+ void SetName(const String& rString );
+ String GetName() const;
+ void SetNameWidth(USHORT);
+
+ void ShowXButton();
+ void HideXButton();
+ BOOL IsVisibleXButton();
+ void ShowAsHyperLink(BOOL nFlag=TRUE);
+ BOOL IsShownAsHyperlink();
+
+ void Locked(BOOL nFlag=TRUE);
+ BOOL IsLineLocked();
+
+ void SetClickHdl(const Link&);
+
+};
+
+
+class SvPropertyData
+{
+public:
+ eKindOfControl eKind;
+ String aName;
+ String aValue;
+ SvStrings theValues; // ???
+
+ BOOL bHasVisibleXButton;
+ BOOL bIsHyperLink;
+ BOOL bIsLocked;
+ void* pDataPtr;
+ SvXPropertyControl* pControl;
+};
+
+class SvPropertyDataObjectControl
+{
+};
+
+class SvPropertyDataControl
+{
+public:
+ virtual void Modified( const String& aName,
+ const String& aVal,
+ void* pData)=0;
+
+ virtual void Clicked( const String& aName,
+ const String& aVal,
+ void* pData)=0;
+
+ virtual void Commit( const String& aName,
+ const String& aVal,
+ void* pData)=0;
+
+ virtual void Select( const String& aName,
+ void* pData)=0;
+
+ virtual void LinkClicked(const String& aName,
+ void* pData)=0;
+};
+
+class SvXPropEvListener: public SvXPropertyCtrListener
+{
+ Link aModifyLink;
+ Link aGetFocusLink;
+ Link aLoseFocusLink;
+ Link aKeyInputLink;
+ String aModifiedResult;
+
+ SvXPropertyControl * pTheActiveControl;
+ KeyCode aKeyCode;
+
+public:
+ SvXPropEvListener();
+ virtual ~SvXPropEvListener();
+
+ virtual void Modified (SvXPropertyControl *pSvXPCtr);
+ virtual void GetFocus (SvXPropertyControl *pSvXPCtr);
+ virtual void LoseFocus(SvXPropertyControl *pSvXPCtr);
+ virtual void KeyInput(SvXPropertyControl *pSvXPCtr ,const KeyCode&);
+
+ SvXPropertyControl * GetPropertyControl();
+ KeyCode GetKeyCode() const;
+
+ void SetModifyHdl( const Link& rLink ) { aModifyLink = rLink; }
+ const Link& GetModifyHdl() const { return aModifyLink; }
+
+ void SetGetFocusHdl( const Link& rLink ) { aGetFocusLink = rLink; }
+ const Link& GetGetFocusHdl() const { return aGetFocusLink; }
+
+ void SetLoseFocusHdl( const Link& rLink ) { aLoseFocusLink = rLink; }
+ const Link& GetLoseFocusHdl() const { return aLoseFocusLink; }
+
+ void SetKeyInputHdl( const Link& rLink ) { aKeyInputLink = rLink; }
+ const Link& GetKeyInputHdl() const { return aKeyInputLink; }
+
+
+};
+
+typedef SvPropertyLine * SvPropertyLinePtr;
+
+SV_DECL_PTRARR(SvPropLineArray,SvPropertyLinePtr,1,1)
+
+class SvListBoxForProperties: public Control
+{
+private:
+
+ SvXPropEvListener aListener;
+ Window aPlayGround;
+ ScrollBar aVScroll;
+ SvPropLineArray PLineArray;
+ SvPropertyDataControl* pPropDataControl;
+ USHORT nRowHeight;
+ BOOL bUpdate;
+ USHORT nTheNameSize;
+ long nYOffset;
+
+ DECL_LINK( ScrollHdl,ScrollBar*);
+ DECL_LINK( ClickHdl ,PushButton*);
+
+ DECL_LINK( ModifyHdl,SvXPropEvListener*);
+ DECL_LINK( GetFocusHdl,SvXPropEvListener*);
+ DECL_LINK(LoseFocusHdl,SvXPropEvListener*);
+ DECL_LINK( KeyInputHdl,SvXPropEvListener*);
+
+protected:
+ void UpdateAll();
+ void UpdatePosNSize();
+ void UpdatePlayGround();
+ void UpdateVScroll();
+
+ void Resize();
+
+public:
+ SvListBoxForProperties( Window* pParent, WinBits nWinStyle = 0 );
+ SvListBoxForProperties( Window* pParent, const ResId& rResId );
+
+ ~SvListBoxForProperties();
+
+ virtual USHORT CalcVisibleLines();
+ virtual void EnableUpdate();
+ virtual void DisableUpdate();
+
+ virtual void SetController(SvPropertyDataControl *);
+
+ virtual void Clear();
+
+ virtual USHORT InsertEntry( const SvPropertyData&, USHORT nPos = LISTBOX_APPEND );
+
+ virtual void ChangeEntry( const SvPropertyData&, USHORT nPos);
+
+ virtual USHORT AppendEntry( const SvPropertyData&);
+
+ virtual void SetPropertyValue( const String & rEntryName, const String & rValue );
+
+ virtual void SetFirstVisibleEntry(USHORT nPos);
+ virtual USHORT GetFirstVisibleEntry();
+
+ virtual void SetSelectedEntry(USHORT nPos);
+ virtual USHORT GetSelectedEntry();
+};
+
+class SvTabPageForProperties: public TabPage
+{
+
+private:
+
+ SvListBoxForProperties aLbProp;
+
+protected:
+
+ virtual void Resize();
+
+public:
+ SvTabPageForProperties(Window* pParent,WinBits nWinStyle = 0 );
+
+ SvListBoxForProperties* GetTheListBox();
+};
+
+
+class SvBasicPropertyDataControl: public SvPropertyDataControl
+{
+private:
+
+ BOOL bCorrectness;
+ String aEntryName;
+ String aEntryProperty;
+ String aCorrectProperty;
+ void* pTheData;
+ Link aModifyLink;
+ Link aClickedLink;
+ Link aCommitLink;
+ Link aSelectLink;
+
+public:
+ virtual ~SvBasicPropertyDataControl();
+
+ virtual void Modified( const String& aName,
+ const String& aVal,
+ void* pData); //User has modified Property
+
+ virtual void Clicked( const String& aName,
+ const String& aVal,
+ void* pData); //Xtension-Button pressed
+
+ virtual void Commit( const String& aName,
+ const String& aVal,
+ void* pData); //User accept changes
+
+ virtual void Select( const String& aName,
+ void* pData); //User select new Row
+
+ virtual void LinkClicked(const String& aName,
+ void* pData);
+
+ virtual void SetIsCorrect(BOOL nFlag);
+
+ //virtual String GetTheCorrectProperty()const;
+ virtual void SetTheCorrectProperty(const String& aName);
+
+ String GetName() const; //Tell's the name of the Property
+ String GetProperty() const; //Tell's the content of the Property
+ void* GetData(); //Tell's the storage
+
+
+ void SetModifyHdl( const Link& rLink ) { aModifyLink = rLink; }
+ const Link& GetModifyHdl() const { return aModifyLink; }
+
+ void SetClickedHdl( const Link& rLink ) { aClickedLink = rLink; }
+ const Link& GetClickedHdl() const { return aClickedLink; }
+
+ void SetCommitHdl( const Link& rLink ) { aCommitLink = rLink; }
+ const Link& GetCommitHdl() const { return aCommitLink; }
+
+ void SetSelectHdl( const Link& rLink ) { aSelectLink = rLink; }
+ const Link& GetSelectHdl() const { return aSelectLink; }
+
+};
+
+
+class SvPropertyBox: public Control
+{
+private:
+ SvPropertyDataControl* pThePropDataCtr;
+ TabControl aTabControl;
+
+protected:
+ virtual void Resize();
+
+public:
+ SvPropertyBox ( Window* pParent, WinBits nWinStyle = 0 );
+ SvPropertyBox ( Window* pParent, const ResId& rResId );
+
+ ~SvPropertyBox();
+
+ virtual USHORT CalcVisibleLines();
+ virtual void EnableUpdate(); // auch IDL?
+ virtual void DisableUpdate(); // auch IDL?
+
+ // AB: Hier beginnt das 'offizielle' Interface, das in IDL uebernommen werden soll
+ virtual void SetController(SvPropertyDataControl *);
+
+ virtual USHORT AppendPage( const String & r );
+ virtual void SetPage( USHORT );
+ virtual USHORT GetCurPage();
+ virtual void ClearAll();
+ virtual void ClearTable();
+
+ virtual void SetPropertyValue( const String & rEntryName, const String & rValue );
+
+ virtual USHORT InsertEntry( const SvPropertyData&, USHORT nPos = LISTBOX_APPEND );
+ virtual void ChangeEntry( const SvPropertyData&, USHORT nPos);
+ virtual USHORT AppendEntry( const SvPropertyData&);
+
+ virtual void SetFirstVisibleEntry(USHORT nPos);
+ virtual USHORT GetFirstVisibleEntry();
+
+ virtual void SetSelectedEntry(USHORT nPos);
+ virtual USHORT GetSelectedEntry();
+};
+
+
+
+/*
+class ScPropertyDlg : public ModalDialog
+{
+private:
+ SvBasicPropertyDataControl aBaProDatCtr;
+ OKButton anOk;
+ CancelButton aCancel;
+ USHORT nCount;
+ USHORT nClickCount;
+
+ SvPropertyData aProperty;
+ SvPropertyBox aPropListBox;
+
+ ListBox aKindOfListBox;
+ FixedText aModAnswer;
+ FixedText aClickAnswer;
+ FixedText aCommitAnswer;
+ FixedText aSelectAnswer;
+
+ DECL_LINK( ModifiedHdl, ListBox*);
+
+ DECL_LINK( RowModifiedHdl, SvBasicPropertyDataControl*);
+ DECL_LINK( ClickHdl , SvBasicPropertyDataControl*);
+ DECL_LINK( SelectHdl , SvBasicPropertyDataControl*);
+ DECL_LINK( CommitHdl , SvBasicPropertyDataControl*);
+
+public:
+ ScPropertyDlg( Window* pParent);
+ ~ScPropertyDlg();
+};
+*/
+#endif // SC_AUTOFMT_HXX
+
+
diff --git a/svtools/source/inc/provider.hxx b/svtools/source/inc/provider.hxx
new file mode 100644
index 000000000000..c54215482a0e
--- /dev/null
+++ b/svtools/source/inc/provider.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 _GOODIES_PROVIDER_HXX
+#define _GOODIES_PROVIDER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+
+using namespace com::sun::star;
+
+namespace unographic {
+
+// -------------------
+// - GraphicProvider -
+// -------------------
+
+class GraphicProvider : public ::cppu::WeakImplHelper1< ::com::sun::star::graphic::XGraphicProvider >
+{
+public:
+
+ GraphicProvider();
+ ~GraphicProvider();
+
+ static ::rtl::OUString getImplementationName_Static() throw();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static() throw();
+
+protected:
+
+ // 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 );
+
+ // 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);
+
+ // XGraphicProvider
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL queryGraphicDescriptor( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& MediaProperties ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > SAL_CALL queryGraphic( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& MediaProperties ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL storeGraphic( const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& Graphic, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& MediaProperties ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+private:
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > implLoadMemory( const ::rtl::OUString& rResourceURL ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > implLoadGraphicObject( const ::rtl::OUString& rResourceURL ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > implLoadResource( const ::rtl::OUString& rResourceURL ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > implLoadRepositoryImage( const ::rtl::OUString& rResourceURL ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > implLoadBitmap( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap >& rBitmap ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > implLoadStandardImage( const ::rtl::OUString& rResourceURL ) const;
+};
+
+}
+
+#endif
diff --git a/svtools/source/inc/renderer.hxx b/svtools/source/inc/renderer.hxx
new file mode 100644
index 000000000000..b58bd065245b
--- /dev/null
+++ b/svtools/source/inc/renderer.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 _GOODIES_RENDERER_HXX
+#define _GOODIES_RENDERER_HXX
+
+#include <tools/gen.hxx>
+#include <comphelper/propertysethelper.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/XGraphicRenderer.hpp>
+
+
+using namespace com::sun::star;
+
+class OutputDevice;
+
+namespace unographic {
+
+// -------------------
+// - GraphicRenderer -
+// -------------------
+
+class GraphicRendererVCL : public ::cppu::OWeakAggObject,
+ public ::com::sun::star::lang::XServiceInfo,
+ public ::com::sun::star::lang::XTypeProvider,
+ public ::comphelper::PropertySetHelper,
+ public ::com::sun::star::graphic::XGraphicRenderer
+{
+public:
+
+ GraphicRendererVCL();
+ ~GraphicRendererVCL() throw();
+
+ static ::rtl::OUString getImplementationName_Static() throw();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static() throw();
+
+protected:
+
+ static ::comphelper::PropertySetInfo* createPropertySetInfo();
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ 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
+ 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 );
+
+ // 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);
+
+ // PropertySetHelper
+ virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const ::com::sun::star::uno::Any* pValues ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException );
+ virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::uno::Any* pValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException );
+
+ // XGraphicRenderer
+ virtual void SAL_CALL render( const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& Graphic ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > mxDevice;
+
+ OutputDevice* mpOutDev;
+ Rectangle maDestRect;
+ ::com::sun::star::uno::Any maRenderData;
+};
+
+}
+
+#endif
diff --git a/svtools/source/inc/sgfbram.hxx b/svtools/source/inc/sgfbram.hxx
new file mode 100644
index 000000000000..2acab5445a8c
--- /dev/null
+++ b/svtools/source/inc/sgfbram.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 _SGFBRAM_HXX
+#define _SGFBRAM_HXX
+
+#include <tools/solar.h>
+
+#define SgfBitImag0 1 /* Bitmap */
+#define SgfBitImag1 4 /* Bitmap */
+#define SgfBitImag2 5 /* Bitmap */
+#define SgfBitImgMo 6 /* Monochrome Bitmap */
+#define SgfSimpVect 2 /* Einfaches Vectorformat */
+#define SgfPostScrp 3 /* Postscript file */
+#define SgfStarDraw 7 /* StarDraw SGV-Datei */
+#define SgfDontKnow 255 /* Unbekannt oder kein SGF/SGV */
+
+// Konstanten fr SgfHeader.SwGrCol
+#define SgfBlckWhit 1 /* Schwarz/Weiá Bild Ä¿ SimpVector, */
+#define SgfGrayscal 2 /* Bild mit Graustufen ³ StarDraw und */
+#define Sgf16Colors 3 /* Farbbild (16 Farben) ÄÙ Bit Image */
+#define SgfVectFarb 4 /* Farben fr Linien verwenden Ä¿ */
+#define SgfVectGray 5 /* Graustufen fr Linien verwenden ³ Nur fr */
+#define SgfVectWdth 6 /* Strichst„rken fr Linien verwenden ÄÙ SimpVector */
+
+
+#define SgfHeaderSize 42
+class SgfHeader
+{
+public:
+ UINT16 Magic;
+ UINT16 Version;
+ UINT16 Typ;
+ UINT16 Xsize;
+ UINT16 Ysize;
+ INT16 Xoffs;
+ INT16 Yoffs;
+ UINT16 Planes; // Layer
+ UINT16 SwGrCol;
+ char Autor[10];
+ char Programm[10];
+ UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (38 mod 4 =2) !
+
+ UINT32 GetOffset();
+ friend SvStream& operator>>(SvStream& rIStream, SgfHeader& rHead);
+ BOOL ChkMagic();
+};
+
+#define SgfEntrySize 22
+class SgfEntry
+{
+public:
+ UINT16 Typ;
+ UINT16 iFrei;
+ UINT16 lFreiLo,lFreiHi;
+ char cFrei[10];
+ UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (18 mod 4 =2) !
+
+ UINT32 GetOffset();
+ friend SvStream& operator>>(SvStream& rIStream, SgfEntry& rEntr);
+};
+
+#define SgfVectorSize 10
+class SgfVector
+{
+public:
+ UINT16 Flag;
+ INT16 x;
+ INT16 y;
+ UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (6 mod 4 =2) !
+
+ friend SvStream& operator>>(SvStream& rIStream, SgfVector& rEntr);
+};
+
+extern long SgfVectXofs;
+extern long SgfVectYofs;
+extern long SgfVectXmul;
+extern long SgfVectYmul;
+extern long SgfVectXdiv;
+extern long SgfVectYdiv;
+extern BOOL SgfVectScal;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Windows BMP /////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define BmpFileHeaderSize 14
+class BmpFileHeader
+{
+public:
+ UINT16 Typ; // = "BM"
+ UINT16 SizeLo,SizeHi; // Filesize in Bytes
+ UINT16 Reserve1; // Reserviert
+ UINT16 Reserve2; // Reserviert
+ UINT16 OfsLo,OfsHi; // Offset?
+
+ void SetSize(UINT32 Size);
+ void SetOfs(UINT32 Size);
+ UINT32 GetOfs();
+ friend SvStream& operator<<(SvStream& rOStream, BmpFileHeader& rHead);
+};
+
+#define BmpInfoHeaderSize 40
+class BmpInfoHeader
+{
+public:
+ UINT32 Size; // GrӇe des BmpInfoHeaders
+ INT32 Width; // Breite in Pixel
+ INT32 Hight; // H”he in Pixel
+ UINT16 Planes; // Anzahl der Planes (immer 1)
+ UINT16 PixBits; // Anzahl der Bit je Pixel (1,4,8,oder 24)
+ UINT32 Compress; // Datenkompression
+ UINT32 ImgSize; // GrӇe der Images in Bytes. Ohne Kompression ist auch 0 erlaubt.
+ INT32 xDpmm; // Dot per Meter (0 ist erlaubt)
+ INT32 yDpmm; // Dot per Meter (0 ist erlaubt)
+ UINT32 ColUsed; // Anzahl der verwendeten Farben (0=alle)
+ UINT32 ColMust; // Anzahl der wichtigen Farben (0=alle)
+
+ friend SvStream& operator<<(SvStream& rOStream, BmpInfoHeader& rHead);
+};
+
+#define RGBQuadSize 4
+class RGBQuad {
+private:
+ BYTE Red;
+ BYTE Grn;
+ BYTE Blu;
+ BYTE Fil;
+public:
+ RGBQuad(BYTE R, BYTE G, BYTE B) { Red=R; Grn=G; Blu=B; Fil=0; }
+};
+
+#endif //_SGFBRAM_HXX
diff --git a/svtools/source/inc/sgffilt.hxx b/svtools/source/inc/sgffilt.hxx
new file mode 100644
index 000000000000..1c75917b8f73
--- /dev/null
+++ b/svtools/source/inc/sgffilt.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SGFFILT_HXX
+#define _SGFFILT_HXX
+#include <tools/urlobj.hxx>
+
+BYTE CheckSgfTyp(SvStream& rInp, USHORT& nVersion);
+BOOL SgfBMapFilter(SvStream& rInp, SvStream& rOut);
+BOOL SgfVectFilter(SvStream& rInp, GDIMetaFile& rMtf);
+BOOL SgfSDrwFilter(SvStream& rInp, GDIMetaFile& rMtf, INetURLObject aIniPath );
+
+// Konstanten fr CheckSgfTyp()
+#define SGF_BITIMAGE 1 /* Bitmap */
+#define SGF_SIMPVECT 2 /* Einfaches Vectorformat */
+#define SGF_POSTSCRP 3 /* Postscript file */
+#define SGF_STARDRAW 7 /* StarDraw SGV-Datei */
+#define SGF_DONTKNOW 255 /* Unbekannt oder kein SGF/SGV */
+
+#define SGV_VERSION 3 /* SGV mit anderer Version wird abgewiesen */
+ /* 3 entspricht StarDraw 2.00/2.01 M„rz'93 */
+#endif //_SGFFILT_HXX
diff --git a/svtools/source/inc/sgvmain.hxx b/svtools/source/inc/sgvmain.hxx
new file mode 100644
index 000000000000..6f69908865c5
--- /dev/null
+++ b/svtools/source/inc/sgvmain.hxx
@@ -0,0 +1,353 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SGVMAIN_HXX
+#define _SGVMAIN_HXX
+
+#include <vcl/font.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/virdev.hxx>
+
+
+#define UCHAR unsigned char
+
+struct PointType {
+ INT16 x;
+ INT16 y;
+};
+
+#define SgfDpmm 40
+
+#define DtHdSize 256
+class DtHdType {
+public:
+ BYTE Reserved[256];
+ friend SvStream& operator>>(SvStream& rIStream, DtHdType& rDtHd);
+ friend void DtHdOverSeek(SvStream& rInp);
+};
+
+
+struct Seitenformat {
+ PointType Size; // 0.00mm...819.175mm (Papiergr��e)
+ INT16 RandL; // links Rand auf
+ INT16 RandR; // rechts dem Papier
+ INT16 RandO; // oben Rand auf
+ INT16 RandU; // unten dem Papier
+ BYTE PColor; // Future Use
+ BYTE PIntens; // erst recht Future use
+// BOOL BorderClip; // Objekte am Rand abschneiden (Schummel wg. Allignment unter NT)
+};
+
+
+#define PageSize 146
+class PageType {
+public:
+ UINT32 Next; // N�chste Seite
+ UINT32 nList; // Objektdaten, erster Record
+ UINT32 ListEnd; // Objektdaten, letzter Record
+ Seitenformat Paper; // Papierdaten
+ BOOL BorderClip; // Objekte am Rand abschneiden (Schummel wg. Allignment unter NT)
+ BYTE StdPg; // welche Standardseite einblenden ?
+ PointType U; // Nullpunkt
+ INT16 HlpLnH[20]; // Hilfslinien
+ INT16 HlpLnV[20];
+ BYTE LnAnzH;
+ BYTE LnAnzV;
+ UCHAR PgName[32]; // Seitenname
+ friend SvStream& operator>>(SvStream& rIStream, PageType& rPage);
+};
+
+
+enum ObjArtType {ObjStrk,ObjRect,ObjPoly,ObjCirc,ObjSpln,
+ ObjText,ObjGrup,ObjBmap,ObjVirt,ObjTxtX,ObjMaxi};
+
+struct ObjLineType {
+ BYTE LFarbe; // [Index]
+ BYTE LBFarbe; // [Index]
+ BYTE LIntens; // [%]
+ BYTE LMuster; // [Index] inkl. Transparenz
+ INT16 LMSize; // [Koeffizient/100]
+ INT16 LDicke; // Strichst�rke
+};
+
+struct ObjAreaType {
+ BYTE FFarbe; // [Index]
+ BYTE FBFarbe; // [Index]
+ BYTE FIntens; // [%]
+ BYTE FDummy1; //
+ INT16 FDummy2; //
+ UINT16 FMuster; // [Index] inkl. Invers, Transparenz
+};
+
+#define ObjTextTypeSize 64
+class ObjTextType {
+public:
+ ObjLineType L; // Text-Outline (future)
+ ObjAreaType F; // Text innen
+ UINT16 FontLo,FontHi;// z.B. 92500 (CG Times), zweigeteilt wegen DWordAllign in TextType.
+ UINT16 Grad; // 0.5..32767.5 Pt - bei 1000 Pt sollte aber schlu� sein
+ UINT16 Breite; // 1..65535% bitte nicht mehr als 500%
+ BYTE Justify; // 2 Bit Vert (Hi), 3 Bit Hor (Lo)
+ BYTE Kapit; // 1..255%
+ UINT16 Schnitt; // 8 Flags
+ UINT16 LnFeed; // 1..32767% vom max. Schriftgrad der Zeile
+ UINT16 Slant; // Kursivwinkel 0.00..89.99� default 15.00� doppelt Breit angesehen)
+ BYTE ZAbst; // Zeichenabstand 0..255% (0=auf der Stelle; 100=normal; 200=Zeichen wird als
+ INT8 ChrVPos; // Zeichen V-Position default 0= on Baseline, 10= 5Pt drunter (-64..63�)
+ ObjLineType ShdL; // Schatten-Outline (neu 2.0)
+ ObjAreaType ShdF; // Schatten-innen (neu 2.0)
+ PointType ShdVers; // Schattenversatz Max.300.00%
+ BOOL ShdAbs; // True-> Schattenversatz ist absolut statt relativ zum Schriftgrad
+ BOOL NoSpc; // True-> kein Zwischenraum (f�r BackArea)
+ ObjAreaType BackF; // Hintergrundfl�che
+ UINT32 GetFont();
+ void SetFont(UINT32 FontID);
+};
+
+class Obj0Type { // SuperClass f�r Apple-VMT
+public:
+ virtual void Draw(OutputDevice& rOut);
+ virtual ~Obj0Type() {}
+};
+
+#define ObjkSize 20 /* eigentlich 21. Wg. Allignment ist Flags jedoch verschoben worden*/
+class ObjkType: public Obj0Type { // Grundkomponenten aller Stardraw-Objekte
+public:
+ UINT32 Last;
+ UINT32 Next;
+ UINT16 MemSize; // in Bytes
+ PointType ObjMin; // XY-Minimum des Objekts
+ PointType ObjMax; // XY-Maximum des Objekts
+ BYTE Art;
+ BYTE Layer;
+// BYTE Flags; // (Schummel f�r Allignment unter NT)
+ friend SvStream& operator>>(SvStream& rIStream, ObjkType& rObjk);
+ friend BOOL ObjOverSeek(SvStream& rInp, ObjkType& rObjk);
+ virtual void Draw(OutputDevice& rOut);
+};
+
+
+#define StrkSize 38
+class StrkType: public ObjkType {
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE LEnden; // Linienenden
+ ObjLineType L;
+ PointType Pos1; // Anfangspunkt
+ PointType Pos2; // Endpunkt
+ friend SvStream& operator>>(SvStream& rIStream, StrkType& rStrk);
+ virtual void Draw(OutputDevice& rOut);
+};
+
+
+#define RectSize 52
+class RectType: public ObjkType {
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE Reserve;
+ ObjLineType L;
+ ObjAreaType F;
+ PointType Pos1; // LO-Ecke = Bezugspunkt
+ PointType Pos2; // R-Ecke
+ INT16 Radius; // Eckenradius
+ UINT16 DrehWink; // 315...<45
+ UINT16 Slant; // >270...<90
+ friend SvStream& operator>>(SvStream& rIStream, RectType& rRect);
+ virtual void Draw(OutputDevice& rOut);
+};
+
+
+#define PolySize 44
+class PolyType: public ObjkType { // identisch mit Spline !
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE LEnden; // nur f�r Polyline
+ ObjLineType L;
+ ObjAreaType F; // nicht f�r Polyline
+ BYTE nPoints;
+ BYTE Reserve;
+ UINT32 SD_EckP; // Zeiger auf die Eckpunkte (StarDraw)
+ PointType* EckP; // Zeiger auf die Eckpunkte (StarView (wird nicht von Disk gelesen!))
+ friend SvStream& operator>>(SvStream& rIStream, PolyType& rPoly);
+ virtual void Draw(OutputDevice& rOut);
+};
+#define PolyClosBit 0x01 // Unterarten von Poly: 0: PolyLine 1: Polygon
+
+
+#define SplnSize 44
+class SplnType: public ObjkType { // identisch mit Poly !
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE LEnden; // nur f�r nSpline
+ ObjLineType L;
+ ObjAreaType F; // nicht f�r nSpline
+ BYTE nPoints;
+ BYTE Reserve;
+ UINT32 SD_EckP; // Zeiger auf die Eckpunkte (StarDraw)
+ PointType* EckP; // Zeiger auf die Eckpunkte (StarView (wird nicht von Disk gelesen!))
+ friend SvStream& operator>>(SvStream& rIStream, SplnType& rSpln);
+ virtual void Draw(OutputDevice& rOut);
+};
+// Unterarten von Spline: siehe Poly
+
+
+#define CircSize 52
+class CircType: public ObjkType {
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE LEnden; // nur Bogen (Kr & El)
+ ObjLineType L;
+ ObjAreaType F; // nicht f�r Bogen (Kr & El)
+ PointType Center; // Mittelpunkt
+ PointType Radius; // Radius
+ UINT16 DrehWink; // nur Ellipse
+ UINT16 StartWink; // � nicht f�r Vollkreis
+ UINT16 RelWink; // � und Vollellipse
+ friend SvStream& operator>>(SvStream& rIStream, CircType& rCirc);
+ virtual void Draw(OutputDevice& rOut);
+};
+#define CircFull 0x00 /* Unterarten von Kreis: 0: Kreis */
+#define CircSect 0x01 /* 1: Kreissektor */
+#define CircAbsn 0x02 /* 2: Kreisabschnitt */
+#define CircArc 0x03 /* 3: Kreisbogen */
+
+
+#define TextSize 116
+class TextType: public ObjkType {
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE Reserve; // f�r Word Allign
+ ObjTextType T; // 64 Bytes << DWord-Allign bei FontID erforderlich
+ PointType Pos1; // Bezugspunkt (ObenLinks)
+ PointType Pos2; // (untenRechts)
+ INT16 TopOfs; // Von Oberkante bis Textbegin (future f�r vJustify)
+ UINT16 DrehWink; // 0...<360
+ UINT16 BoxSlant; // >270...<90 (nur Box)
+ UINT16 BufSize; // Gr��e von Buf f�r Load, Save, Copy und so
+ UINT16 BufLo,BufHi;// (UCHAR*) Zeiger auf den Textbuffer << ShortArr, weil sonst DWord-Allign erforderlich
+ UINT16 ExtLo,ExtHi;// (Ptr) Text �ber mehrere Rahmen << ShortArr, weil sonst DWord-Allign erforderlich
+ PointType FitSize; // Ursprungsgr��e f�r Fit2Size
+ INT16 FitBreit; // Breite zum formatieren bei Fit2Size
+ UCHAR* Buffer; // Diese Variable wird nicht durch Lesen von Disk gef�llt, sondern explizit!
+ friend SvStream& operator>>(SvStream& rIStream, TextType& rText);
+ virtual void Draw(OutputDevice& rOut);
+};
+#define TextOutlBit 0x01 /* 1=Sourcecode f�r Outliner (wird von DrawObjekt() ignoriert) */
+#define TextFitSBit 0x02 /* Bit1: 1=Text-FitToSize, auch Outliner (2.0) */
+#define TextFitZBit 0x08 /* Bit3: 1=Fit2Size Zeilenweise (2.0) */
+#define TextDrftBit 0x04 /* Bit2: 1=DraftDraw (2.0) */
+#define TextFitBits (TextFitSBit | TextFitZBit)
+
+
+enum GrafStat {NoGraf,Pic,Pcx,Hpgl,Img,Msp,Tiff,Dxf,Lot,Usr,Sgf};
+
+#define BmapSize 132
+class BmapType: public ObjkType {
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ BYTE Reserve;
+ ObjAreaType F; // Farbe und Muster der 1-Plane Bitmap
+ PointType Pos1;
+ PointType Pos2;
+ UINT16 DrehWink; // 315...<45 (Future)
+ UINT16 Slant; // >270...<90 (Future)
+ UCHAR Filename[80]; // Pfad
+ PointType PixSize; // Gr��e in Pixel (0 bei Vektor)
+ GrafStat Format; // siehe GpmDef.Pas
+ BYTE nPlanes; // Anzahl der Bitplanes (0 bei Vektor)
+ BOOL RawOut; // als Raw ausgeben ?
+ BOOL InvOut; // invertiert ausgeben ?
+ BOOL LightOut; // aufhellen? (SD20)
+ BYTE GrfFlg; // (SD20) 0=nSGF 1=Pcx 2=Hpgl 4=Raw $FF=Undef(f�r Fix in DrawBmp)
+
+ INetURLObject aFltPath; // F�r GraphicFilter
+ friend SvStream& operator>>(SvStream& rIStream, BmapType& rBmap);
+ virtual void Draw(OutputDevice& rOut);
+ void SetPaths( const INetURLObject rFltPath );
+};
+
+
+#define GrupSize 48
+class GrupType: public ObjkType {
+public:
+ BYTE Flags; // (Schummel f�r Allignment unter NT)
+ UCHAR Name[13]; // Name der Gruppe
+ UINT16 SbLo,SbHi; // (Ptr) Gruppenliste << ShortArr, weil sonst DWord Allign erforderlich
+ UINT16 UpLo,UpHi; // (Ptr) Vaterliste << ShortArr, weil sonst DWord Allign erforderlich
+ UINT16 ChartSize; // Speicherbedarf der Diagrammstruktur Struktur
+ UINT32 ChartPtr; // Diagrammstruktur
+ UINT32 GetSubPtr(); // hier nur zum Checken, ob Sublist evtl. leer ist.
+ friend SvStream& operator>>(SvStream& rIStream, GrupType& rGrup);
+// virtual void Draw(OutputDevice& rOut);
+};
+
+
+void SetLine(ObjLineType& rLine, OutputDevice& rOut);
+void SetArea(ObjAreaType& rArea, OutputDevice& rOut);
+Color Sgv2SvFarbe(BYTE nFrb1, BYTE nFrb2, BYTE nInts);
+void RotatePoint(PointType& P, INT16 cx, INT16 cy, double sn, double cs);
+void RotatePoint(Point& P, INT16 cx, INT16 cy, double sn, double cs);
+INT16 iMulDiv(INT16 a, INT16 Mul, INT16 Div);
+UINT16 MulDiv(UINT16 a, UINT16 Mul, UINT16 Div);
+
+
+class SgfFontOne {
+public:
+ SgfFontOne* Next; // Zeiger f�r Listenverkettung
+ UINT32 IFID;
+ BOOL Bold;
+ BOOL Ital;
+ BOOL Sans;
+ BOOL Serf;
+ BOOL Fixd;
+ FontFamily SVFamil;
+ CharSet SVChSet;
+ String SVFName; // z.B. "Times New Roman" = 15 Chars
+ USHORT SVWidth; // Durchschnittliche Zeichenbreite in %
+ SgfFontOne();
+ void ReadOne( ByteString& ID, ByteString& Dsc);
+};
+
+class SgfFontLst {
+public:
+ String FNam; // vollst�ndiger Filename des Inifiles
+ SgfFontOne* pList; // Listenanfang
+ SgfFontOne* Last; // Listenende
+ UINT32 LastID; // f�r schnelleren Zugriff bei Wiederholungen
+ SgfFontOne* LastLn; // f�r schnelleren Zugriff bei Wiederholungen
+ BOOL Tried;
+ SgfFontLst();
+ ~SgfFontLst();
+ void AssignFN(const String& rFName);
+ void ReadList();
+ void RausList();
+ SgfFontOne* GetFontDesc(UINT32 ID);
+};
+
+#endif //_SGVMAIN_HXX
+
+
diff --git a/svtools/source/inc/sgvspln.hxx b/svtools/source/inc/sgvspln.hxx
new file mode 100644
index 000000000000..29df09247f22
--- /dev/null
+++ b/svtools/source/inc/sgvspln.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 _SGVSPLN_HXX
+#define _SGVSPLN_HXX
+
+/*************************************************************************
+|*
+|* CalcSpline()
+|*
+|* Beschreibung Berechnet die Koeffizienten eines parametrischen
+|* natrlichen oder periodischen kubischen
+|* Polynomsplines. Die Eckpunkte des šbergebenen
+|* Polygons werden als Sttzstellen angenommen.
+|* n liefert die Anzahl der Teilpolynome.
+|* Ist die Berechnung fehlerfrei verlaufen, so
+|* liefert die Funktion TRUE. Nur in diesem Fall
+|* ist Speicher fr die Koeffizientenarrays
+|* allokiert, der dann sp„ter vom Aufrufer mittels
+|* delete freizugeben ist.
+|* Ersterstellung JOE 17-08.93
+|* Letzte Aenderung JOE 17-08.93
+|*
+*************************************************************************/
+
+BOOL CalcSpline(Polygon& rPoly, BOOL Periodic, USHORT& n,
+ double*& ax, double*& ay, double*& bx, double*& by,
+ double*& cx, double*& cy, double*& dx, double*& dy, double*& T);
+
+/*************************************************************************
+|*
+|* Poly2Spline()
+|*
+|* Beschreibung Konvertiert einen parametrichen kubischen
+|* Polynomspline Spline (natrlich oder periodisch)
+|* in ein angen„hertes Polygon.
+|* Die Funktion liefert FALSE, wenn ein Fehler bei
+|* der Koeffizientenberechnung aufgetreten ist oder
+|* das Polygon zu groá wird (>PolyMax=16380). Im 1.
+|* Fall hat das Polygon 0, im 2. Fall PolyMax Punkte.
+|* Um Koordinatenberl„ufe zu vermeiden werden diese
+|* auf +/-32000 begrenzt.
+|* Ersterstellung JOE 23.06.93
+|* Letzte Aenderung JOE 23.06.93
+|*
+*************************************************************************/
+BOOL Spline2Poly(Polygon& rSpln, BOOL Periodic, Polygon& rPoly);
+
+#endif //_SGVSPLN_HXX
diff --git a/svtools/source/inc/svimpbox.hxx b/svtools/source/inc/svimpbox.hxx
new file mode 100644
index 000000000000..92b9f960b65c
--- /dev/null
+++ b/svtools/source/inc/svimpbox.hxx
@@ -0,0 +1,474 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVIMPLBOX_HXX
+#define _SVIMPLBOX_HXX
+
+#ifndef _SELENG_HXX
+#include <vcl/seleng.hxx>
+#endif
+#ifndef _SCRBAR_HXX
+#include <vcl/scrbar.hxx>
+#endif
+#include <vcl/vclevent.hxx>
+// #102891# ----------------
+#include <unotools/intlwrapper.hxx>
+// #97680# -----------------
+#include <vector>
+#include "svtaccessiblefactory.hxx"
+
+class SvTreeListBox;
+class Point;
+class DropEvent;
+class SvLBoxTreeList;
+class SvImpLBox;
+class SvLBoxEntry;
+class SvLBoxItem;
+class SvLBoxTab;
+class TabBar;
+
+class ImpLBSelEng : public FunctionSet
+{
+ SvImpLBox* pImp;
+ SelectionEngine* pSelEng;
+ SvTreeListBox* pView;
+
+public:
+ ImpLBSelEng( SvImpLBox* pImp, SelectionEngine* pSelEng,
+ SvTreeListBox* pView );
+ virtual ~ImpLBSelEng();
+ void BeginDrag();
+ void CreateAnchor();
+ void DestroyAnchor();
+ BOOL SetCursorAtPoint( const Point& rPoint,
+ BOOL bDontSelectAtCursor=FALSE );
+ BOOL IsSelectionAtPoint( const Point& rPoint );
+ void DeselectAtPoint( const Point& rPoint );
+ void DeselectAll();
+};
+
+// Flags fuer nFlag
+#define F_VER_SBARSIZE_WITH_HBAR 0x0001
+#define F_HOR_SBARSIZE_WITH_VBAR 0x0002
+#define F_IGNORE_NEXT_MOUSEMOVE 0x0004 // OS/2 only
+#define F_IN_SCROLLING 0x0008
+#define F_DESEL_ALL 0x0010
+#define F_START_EDITTIMER 0x0020 // MAC only
+#define F_IGNORE_SELECT 0x0040
+#define F_IN_RESIZE 0x0080
+#define F_REMOVED_ENTRY_INVISIBLE 0x0100
+#define F_REMOVED_RECALC_MOST_RIGHT 0x0200
+#define F_IGNORE_CHANGED_TABS 0x0400
+#define F_PAINTED 0x0800
+#define F_IN_PAINT 0x1000
+#define F_ENDSCROLL_SET_VIS_SIZE 0x2000
+#define F_FILLING 0x4000
+
+
+class SvImpLBox
+{
+friend class ImpLBSelEng;
+friend class SvTreeListBox;
+private:
+ SvTreeListBox* pView;
+ SvLBoxTreeList* pTree;
+ SvLBoxEntry* pCursor;
+ SvLBoxEntry* pStartEntry;
+ SvLBoxEntry* pAnchor;
+ SvLBoxEntry* pMostRightEntry;
+ SvLBoxButton* pActiveButton;
+ SvLBoxEntry* pActiveEntry;
+ SvLBoxTab* pActiveTab;
+ TabBar* pTabBar;
+
+ ScrollBar aVerSBar;
+ ScrollBar aHorSBar;
+ ScrollBarBox aScrBarBox;
+
+ ::svt::AccessibleFactoryAccess
+ m_aFactoryAccess;
+
+ static Image* s_pDefCollapsed;
+ static Image* s_pDefExpanded;
+ static Image* s_pDefCollapsedHC;
+ static Image* s_pDefExpandedHC;
+ static oslInterlockedCount s_nImageRefCount; /// When 0 all static images will be destroyed
+
+ // Node Bitmaps
+ enum ImageType
+ {
+ itNodeExpanded = 0, // node is expanded ( usually a bitmap showing a minus )
+ itNodeCollapsed, // node is collapsed ( usually a bitmap showing a plus )
+ itNodeDontKnow, // don't know the node state
+ itEntryDefExpanded, // default for expanded entries
+ itEntryDefCollapsed, // default for collapsed entries
+
+ IT_IMAGE_COUNT
+ };
+
+ // all our images
+ Image m_aNodeAndEntryImages[ IT_IMAGE_COUNT ];
+ // plus the high contrast versions
+ Image m_aNodeAndEntryImages_HC[ IT_IMAGE_COUNT ];
+
+ // wg. kompat. hier
+ Size aOutputSize;
+ SelectionEngine aSelEng;
+ ImpLBSelEng aFctSet;
+ Timer aAsyncBeginDragTimer;
+ Point aAsyncBeginDragPos;
+
+ long nYoffsNodeBmp;
+ long nNodeBmpTabDistance; // typisch kleiner 0
+ long nNodeBmpWidth;
+ long nNextVerVisSize;
+ long nMostRight;
+ ULONG nVisibleCount; // Anzahl Zeilen im Control
+ ULONG nCurUserEvent; //-1 == kein Userevent amn Laufen
+ short nHorSBarHeight, nVerSBarWidth;
+ USHORT nFlags;
+ USHORT nCurTabPos;
+
+ WinBits nWinBits;
+ ExtendedWinBits nExtendedWinBits;
+ BOOL bSimpleTravel : 1; // ist TRUE bei SINGLE_SELECTION
+ BOOL bUpdateMode : 1;
+ BOOL bInVScrollHdl : 1;
+ BOOL bAsyncBeginDrag : 1;
+ BOOL bSubLstOpRet : 1; // open/close sublist with return/enter, defaulted with FALSE
+ BOOL bSubLstOpLR : 1; // open/close sublist with cursor left/right, defaulted with FALSE
+ BOOL bContextMenuHandling : 1;
+ BOOL bIsCellFocusEnabled : 1;
+
+ sal_Bool bAreChildrenTransient;
+
+ Point aEditClickPos;
+ Timer aEditTimer;
+
+ // #102891# -------------------
+ IntlWrapper * pIntlWrapper;
+
+ // #97680# --------------------
+ std::vector< short > aContextBmpWidthVector;
+
+ DECL_LINK( EditTimerCall, Timer * );
+
+ DECL_LINK( BeginDragHdl, void* );
+ DECL_LINK( MyUserEvent,void*);
+ void StopUserEvent();
+
+ void InvalidateEntriesFrom( long nY ) const;
+ void InvalidateEntry( long nY ) const;
+ void ShowVerSBar();
+ // setzt Thumb auf FirstEntryToDraw
+ void SyncVerThumb();
+ BOOL IsLineVisible( long nY ) const;
+ long GetEntryLine( SvLBoxEntry* pEntry ) const;
+ void FillView();
+ void CursorDown();
+ void CursorUp();
+ void KeyLeftRight( long nDiff );
+ void PageDown( USHORT nDelta );
+ void PageUp( USHORT nDelta );
+
+ void SetCursor( SvLBoxEntry* pEntry, BOOL bForceNoSelect = FALSE );
+
+ void DrawNet();
+
+ // ScrollBar-Handler
+ DECL_LINK( ScrollUpDownHdl, ScrollBar * );
+ DECL_LINK( ScrollLeftRightHdl, ScrollBar * );
+ DECL_LINK( EndScrollHdl, ScrollBar * );
+
+ void SetNodeBmpYOffset( const Image& );
+ void SetNodeBmpTabDistance();
+
+ // Selection-Engine
+ SvLBoxEntry* MakePointVisible( const Point& rPoint,
+ BOOL bNotifyScroll=TRUE );
+
+ void SetAnchorSelection( SvLBoxEntry* pOld,
+ SvLBoxEntry* pNewCursor );
+ void BeginDrag();
+ BOOL ButtonDownCheckCtrl( const MouseEvent& rMEvt,
+ SvLBoxEntry* pEntry, long nY );
+ BOOL MouseMoveCheckCtrl( const MouseEvent& rMEvt,
+ SvLBoxEntry* pEntry );
+ BOOL ButtonUpCheckCtrl( const MouseEvent& rMEvt );
+ BOOL ButtonDownCheckExpand( const MouseEvent&,
+ SvLBoxEntry*,long nY );
+
+ void PositionScrollBars( Size& rOSize, USHORT nMask );
+ USHORT AdjustScrollBars( Size& rSize );
+
+ void BeginScroll();
+ void EndScroll();
+ BOOL InScroll() const { return (BOOL)(nFlags & F_IN_SCROLLING)!=0;}
+ Rectangle GetVisibleArea() const;
+ BOOL EntryReallyHit(SvLBoxEntry* pEntry,const Point& rPos,long nLine);
+ void InitScrollBarBox();
+ SvLBoxTab* NextTab( SvLBoxTab* );
+
+ BOOL SetMostRight( SvLBoxEntry* pEntry );
+ void FindMostRight( SvLBoxEntry* EntryToIgnore );
+ void FindMostRight( SvLBoxEntry* pParent, SvLBoxEntry* EntryToIgnore );
+ void FindMostRight_Impl( SvLBoxEntry* pParent,SvLBoxEntry* EntryToIgnore );
+ void NotifyTabsChanged();
+
+ inline BOOL IsExpandable() const // if element at cursor can be expanded in general
+ { return pCursor->HasChilds() || pCursor->HasChildsOnDemand(); }
+ inline BOOL IsNowExpandable() const // if element at cursor can be expanded at this moment
+ { return IsExpandable() && !pView->IsExpanded( pCursor ); }
+
+ static void implInitDefaultNodeImages();
+
+ // #102891# -------------------
+ void UpdateIntlWrapper();
+
+ // #97680# --------------------
+ short UpdateContextBmpWidthVector( SvLBoxEntry* pEntry, short nWidth );
+ void UpdateContextBmpWidthMax( SvLBoxEntry* pEntry );
+ void UpdateContextBmpWidthVectorFromMovedEntry( SvLBoxEntry* pEntry );
+
+ void CalcCellFocusRect( SvLBoxEntry* pEntry, Rectangle& rRect );
+
+ inline sal_Bool AreChildrenTransient() const { return bAreChildrenTransient; }
+ inline void SetChildrenNotTransient() { bAreChildrenTransient = sal_False; }
+
+public:
+ SvImpLBox( SvTreeListBox* pView, SvLBoxTreeList*, WinBits nWinStyle );
+ ~SvImpLBox();
+
+ void Clear();
+ void SetWindowBits( WinBits nWinStyle );
+ void SetExtendedWindowBits( ExtendedWinBits _nBits );
+ ExtendedWinBits GetExtendedWindowBits() const { return nExtendedWinBits; }
+ void SetModel( SvLBoxTreeList* pModel ) { pTree = pModel;}
+
+ void EntryInserted( SvLBoxEntry*);
+ void RemovingEntry( SvLBoxEntry* pEntry );
+ void EntryRemoved();
+ void MovingEntry( SvLBoxEntry* pEntry );
+ void EntryMoved( SvLBoxEntry* pEntry );
+ void TreeInserted( SvLBoxEntry* pEntry );
+
+ void IndentChanged( short nIndentPixel );
+ void EntryExpanded( SvLBoxEntry* pEntry );
+ void EntryCollapsed( SvLBoxEntry* pEntry );
+ void CollapsingEntry( SvLBoxEntry* pEntry );
+ void EntrySelected( SvLBoxEntry*, BOOL bSelect );
+
+ void Paint( const Rectangle& rRect );
+ void RepaintSelectionItems();
+ void MouseButtonDown( const MouseEvent& );
+ void MouseButtonUp( const MouseEvent& );
+ void MouseMove( const MouseEvent&);
+ BOOL KeyInput( const KeyEvent& );
+ void Resize();
+ void GetFocus();
+ void LoseFocus();
+ void UpdateAll(
+ BOOL bInvalidateCompleteView= TRUE,
+ BOOL bUpdateVerSBar = TRUE );
+ void SetEntryHeight( short nHeight );
+ void PaintEntry( SvLBoxEntry* pEntry );
+ void InvalidateEntry( SvLBoxEntry* );
+ void RecalcFocusRect();
+
+ inline void SelectEntry( SvLBoxEntry* pEntry, BOOL bSelect );
+ void SetDragDropMode( DragDropMode eDDMode );
+ void SetSelectionMode( SelectionMode eSelMode );
+ void SetAddMode( BOOL ) { aSelEng.AddAlways(FALSE); }
+ BOOL IsAddMode() const { return aSelEng.IsAlwaysAdding(); }
+
+ SvLBoxEntry* GetCurrentEntry() const { return pCursor; }
+ BOOL IsEntryInView( SvLBoxEntry* ) const;
+ SvLBoxEntry* GetEntry( const Point& rPos ) const;
+ // gibt letzten Eintrag zurueck, falls Pos unter letztem Eintrag
+ SvLBoxEntry* GetClickedEntry( const Point& ) const;
+ SvLBoxEntry* GetCurEntry() const { return pCursor; }
+ void SetCurEntry( SvLBoxEntry* );
+ Point GetEntryPosition( SvLBoxEntry* ) const;
+ void MakeVisible( SvLBoxEntry* pEntry, BOOL bMoveToTop=FALSE );
+
+ void PaintDDCursor( SvLBoxEntry* );
+
+ // Images
+ inline Image& implGetImageLocation( const ImageType _eType, BmpColorMode _eMode );
+ inline Image& implGetImageLocationWithFallback( const ImageType _eType, BmpColorMode _eMode ) const;
+
+ inline void SetExpandedNodeBmp( const Image& _rImg, BmpColorMode _eMode = BMP_COLOR_NORMAL );
+ inline void SetCollapsedNodeBmp( const Image& _rImg, BmpColorMode _eMode = BMP_COLOR_NORMAL );
+ inline void SetDontKnowNodeBmp( const Image& rImg, BmpColorMode _eMode = BMP_COLOR_NORMAL );
+
+ inline const Image& GetExpandedNodeBmp( BmpColorMode _eMode = BMP_COLOR_NORMAL ) const;
+ inline const Image& GetCollapsedNodeBmp( BmpColorMode _eMode = BMP_COLOR_NORMAL ) const;
+ inline const Image& GetDontKnowNodeBmp( BmpColorMode _eMode = BMP_COLOR_NORMAL ) const;
+
+ inline void SetDefaultEntryExpBmp( const Image& _rImg, BmpColorMode _eMode = BMP_COLOR_NORMAL );
+ inline void SetDefaultEntryColBmp( const Image& _rImg, BmpColorMode _eMode = BMP_COLOR_NORMAL );
+ inline const Image& GetDefaultEntryExpBmp( BmpColorMode _eMode = BMP_COLOR_NORMAL );
+ inline const Image& GetDefaultEntryColBmp( BmpColorMode _eMode = BMP_COLOR_NORMAL );
+
+ static const Image& GetDefaultExpandedNodeImage( BmpColorMode _eMode = BMP_COLOR_NORMAL );
+ static const Image& GetDefaultCollapsedNodeImage( BmpColorMode _eMode = BMP_COLOR_NORMAL );
+
+ const Size& GetOutputSize() const { return aOutputSize;}
+ void KeyUp( BOOL bPageUp, BOOL bNotifyScroll = TRUE );
+ void KeyDown( BOOL bPageDown, BOOL bNotifyScroll = TRUE );
+ bool Command( const CommandEvent& rCEvt );
+
+ void Invalidate();
+ void DestroyAnchor() { pAnchor=0; aSelEng.Reset(); }
+ void SelAllDestrAnch( BOOL bSelect,
+ BOOL bDestroyAnchor = TRUE,
+ BOOL bSingleSelToo = FALSE );
+ void ShowCursor( BOOL bShow );
+
+ BOOL RequestHelp( const HelpEvent& rHEvt );
+ void EndSelection();
+ BOOL IsNodeButton( const Point& rPosPixel, SvLBoxEntry* pEntry ) const;
+ void RepaintScrollBars();
+ void EnableAsyncDrag( BOOL b) { bAsyncBeginDrag = b; }
+ void SetUpdateMode( BOOL );
+ void SetUpdateModeFast( BOOL );
+ BOOL GetUpdateMode() const { return bUpdateMode; }
+ Rectangle GetClipRegionRect() const;
+ BOOL HasHorScrollBar() const { return aHorSBar.IsVisible(); }
+ void ShowFocusRect( const SvLBoxEntry* pEntry );
+ void SetTabBar( TabBar* pTabBar );
+ void CancelPendingEdit();
+
+ void CallEventListeners( ULONG nEvent, void* pData = NULL );
+
+ /** Enables, that one cell of a tablistbox entry can be focused */
+ inline BOOL IsCellFocusEnabled() const { return bIsCellFocusEnabled; }
+ inline void EnableCellFocus() { bIsCellFocusEnabled = TRUE; }
+ bool SetCurrentTabPos( USHORT _nNewPos );
+ inline USHORT GetCurrentTabPos() const { return nCurTabPos; }
+
+ bool IsSelectable( const SvLBoxEntry* pEntry );
+};
+
+inline Image& SvImpLBox::implGetImageLocation( const ImageType _eType, BmpColorMode _eMode )
+{
+ DBG_ASSERT( ( BMP_COLOR_HIGHCONTRAST == _eMode ) || ( BMP_COLOR_NORMAL == _eMode ),
+ "SvImpLBox::implGetImageLocation: invalid mode!" );
+ DBG_ASSERT( ( _eType >= 0 ) && ( _eType < IT_IMAGE_COUNT ),
+ "SvImpLBox::implGetImageLocation: invalid image index (will crash)!" );
+
+ Image* _pSet = ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? m_aNodeAndEntryImages_HC : m_aNodeAndEntryImages;
+ return *( _pSet + (sal_Int32)_eType );
+}
+
+inline Image& SvImpLBox::implGetImageLocationWithFallback( const ImageType _eType, BmpColorMode _eMode ) const
+{
+ Image& rImage = const_cast< SvImpLBox* >( this )->implGetImageLocation( _eType, _eMode );
+ if ( !rImage )
+ // fallback to normal images in case the one for the special mode has not been set
+ rImage = const_cast< SvImpLBox* >( this )->implGetImageLocation( _eType, BMP_COLOR_NORMAL );
+ return rImage;
+}
+
+inline void SvImpLBox::SetDontKnowNodeBmp( const Image& rImg, BmpColorMode _eMode )
+{
+ implGetImageLocation( itNodeDontKnow, _eMode ) = rImg;
+}
+
+inline void SvImpLBox::SetExpandedNodeBmp( const Image& rImg, BmpColorMode _eMode )
+{
+ implGetImageLocation( itNodeExpanded, _eMode ) = rImg;
+ SetNodeBmpYOffset( rImg );
+}
+
+inline void SvImpLBox::SetCollapsedNodeBmp( const Image& rImg, BmpColorMode _eMode )
+{
+ implGetImageLocation( itNodeCollapsed, _eMode ) = rImg;
+ SetNodeBmpYOffset( rImg );
+}
+
+inline const Image& SvImpLBox::GetDontKnowNodeBmp( BmpColorMode _eMode ) const
+{
+ return implGetImageLocationWithFallback( itNodeDontKnow, _eMode );
+}
+
+inline const Image& SvImpLBox::GetExpandedNodeBmp( BmpColorMode _eMode ) const
+{
+ return implGetImageLocationWithFallback( itNodeExpanded, _eMode );
+}
+
+inline const Image& SvImpLBox::GetCollapsedNodeBmp( BmpColorMode _eMode ) const
+{
+ return implGetImageLocationWithFallback( itNodeCollapsed, _eMode );
+}
+
+inline void SvImpLBox::SetDefaultEntryExpBmp( const Image& _rImg, BmpColorMode _eMode )
+{
+ implGetImageLocation( itEntryDefExpanded, _eMode ) = _rImg;
+}
+
+inline void SvImpLBox::SetDefaultEntryColBmp( const Image& _rImg, BmpColorMode _eMode )
+{
+ implGetImageLocation( itEntryDefCollapsed, _eMode ) = _rImg;
+}
+
+inline const Image& SvImpLBox::GetDefaultEntryExpBmp( BmpColorMode _eMode )
+{
+ return implGetImageLocationWithFallback( itEntryDefExpanded, _eMode );
+}
+
+inline const Image& SvImpLBox::GetDefaultEntryColBmp( BmpColorMode _eMode )
+{
+ return implGetImageLocationWithFallback( itEntryDefCollapsed, _eMode );
+}
+
+inline Point SvImpLBox::GetEntryPosition( SvLBoxEntry* pEntry ) const
+{
+ return Point( 0, GetEntryLine( pEntry ) );
+}
+
+inline void SvImpLBox::PaintEntry( SvLBoxEntry* pEntry )
+{
+ long nY = GetEntryLine( pEntry );
+ pView->PaintEntry( pEntry, nY );
+}
+
+inline BOOL SvImpLBox::IsLineVisible( long nY ) const
+{
+ BOOL bRet = TRUE;
+ if ( nY < 0 || nY >= aOutputSize.Height() )
+ bRet = FALSE;
+ return bRet;
+}
+
+inline void SvImpLBox::TreeInserted( SvLBoxEntry* pInsTree )
+{
+ EntryInserted( pInsTree );
+}
+
+#endif // #ifndef _SVIMPLBOX_HXX
+
diff --git a/svtools/source/inc/svimpicn.hxx b/svtools/source/inc/svimpicn.hxx
new file mode 100644
index 000000000000..20f98d2bcbbd
--- /dev/null
+++ b/svtools/source/inc/svimpicn.hxx
@@ -0,0 +1,321 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SVIMPICN_HXX
+#define _SVIMPICN_HXX
+
+#ifndef _VIRDEV_HXX
+#include <vcl/virdev.hxx>
+#endif
+
+#ifndef _SCRBAR_HXX
+#include <vcl/scrbar.hxx>
+#endif
+#include <limits.h>
+
+class SvLBoxEntry;
+class SvLBoxTreeList;
+class SvImpIconView;
+class ImpIcnCursor;
+class SvPtrarr;
+
+#define PAINTFLAG_HOR_CENTERED 0x0001
+#define PAINTFLAG_VER_CENTERED 0x0002
+
+#define SELRECT_BORDER_OFFS -7
+// Flags
+#define F_VER_SBARSIZE_WITH_HBAR 0x00000001
+#define F_HOR_SBARSIZE_WITH_VBAR 0x00000002
+#define F_IGNORE_NEXT_MOUSEMOVE 0x00000004 // OS/2 only
+#define F_ENTRY_REMOVED 0x00000008
+// ist gesetzt, wenn nach Clear oder Ctor mind. einmal gepaintet wurde
+#define F_PAINTED 0x00000010
+#define F_ADD_MODE 0x00000020
+#define F_MOVING_SIBLING 0x00000040
+#define F_SELRECT_VISIBLE 0x00000080
+#define F_CMD_ARRIVED 0x00000100
+#define F_DRAG_SOURCE 0x00000200
+#define F_GRIDMODE 0x00000400
+// beim Einfuegen eines Eintrags ergibt sich dessen Position
+// durch simples Addieren auf die Position des zuletzt eingefuegten Eintrags
+#define F_GRID_INSERT 0x00000800
+#define F_DOWN_CTRL 0x00001000
+#define F_DOWN_DESELECT 0x00002000
+// Hack fuer D&D: Hintergrund des Entries nicht painten
+#define F_NO_EMPHASIS 0x00004000
+// Selektion per Gummiband
+#define F_RUBBERING 0x00008000
+#define F_START_EDITTIMER_IN_MOUSEUP 0x00010000
+
+class SvImpIconView
+{
+ friend class ImpIcnCursor;
+ ScrollBar aVerSBar;
+ ScrollBar aHorSBar;
+ Rectangle aCurSelectionRect;
+ SvPtrarr aSelectedRectList;
+ MouseEvent aMouseMoveEvent;
+ Timer aEditTimer; // fuer Inplace-Editieren
+ Timer aMouseMoveTimer; // generiert MouseMoves bei Gummibandselektion
+ // Boundrect des zuletzt eingefuegten Entries
+ Rectangle aPrevBoundRect;
+ Size aOutputSize; // Pixel
+ Size aVirtOutputSize; // expandiert automatisch
+ Point aDDLastEntryPos;
+ Point aDDLastRectPos;
+
+ SvLBoxTreeList* pModel;
+ SvIconView* pView;
+ ImpIcnCursor* pImpCursor;
+ long nMaxVirtWidth; // max.breite aVirtOutputSize
+ SvPtrarr* pZOrderList;
+ long nGridDX,
+ nGridDY;
+ long nHorSBarHeight,
+ nVerSBarWidth;
+ WinBits nWinBits;
+ int nViewMode;
+ long nHorDist;
+ long nVerDist;
+ long nMaxBmpWidth;
+ long nMaxBmpHeight;
+ long nMaxTextWidth;
+ long nMaxBoundHeight; // Hoehe des hoechsten BoundRects
+ ULONG nFlags;
+ ULONG nCurUserEvent;
+ SvLBoxEntry* pCurParent;
+ SvLBoxEntry* pCursor;
+ SvLBoxEntry* pNextCursor; // wird in MovingEntry gesetzt und ist
+ // nur in EntryMoved gueltig!
+ SvLBoxEntry* pDDRefEntry;
+ VirtualDevice* pDDDev;
+ VirtualDevice* pDDBufDev;
+ VirtualDevice* pDDTempDev;
+
+ SvIconViewTextMode eTextMode;
+ BOOL bMustRecalcBoundingRects;
+
+ void CheckAllSizes();
+ void CheckSizes( SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData = 0 );
+ void ShowCursor( BOOL bShow );
+
+ void SetNextEntryPos(const Point& rPos);
+ Point FindNextEntryPos( const Size& rBoundSize );
+ void ImpArrange();
+ void AdjustVirtSize( const Rectangle& );
+ void ResetVirtSize();
+ void CheckScrollBars();
+
+ DECL_LINK( ScrollUpDownHdl, ScrollBar * );
+ DECL_LINK( ScrollLeftRightHdl, ScrollBar * );
+ DECL_LINK( MouseMoveTimeoutHdl, Timer* );
+ DECL_LINK( EditTimeoutHdl, Timer* );
+ DECL_LINK( UserEventHdl, void* );
+ void AdjustScrollBars();
+ void PositionScrollBars( long nRealWidth, long nRealHeight );
+ void CalcDocPos( Point& aMousePos );
+ BOOL GetResizeRect( Rectangle& );
+ void PaintResizeRect( const Rectangle& );
+ SvLBoxEntry* GetNewCursor();
+ void ToggleSelection( SvLBoxEntry* );
+ void DeselectAllBut( SvLBoxEntry* );
+ void Center( SvLBoxEntry* pEntry, SvIcnVwDataEntry* ) const;
+ void StopEditTimer() { aEditTimer.Stop(); }
+ void StartEditTimer() { aEditTimer.Start(); }
+ void ImpHideDDIcon();
+ void ImpDrawXORRect( const Rectangle& rRect );
+ void AddSelectedRect( const Rectangle&, short nOffset = SELRECT_BORDER_OFFS );
+ void ClearSelectedRectList();
+ Rectangle CalcMaxTextRect( const SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const;
+
+ void ClipAtVirtOutRect( Rectangle& rRect ) const;
+ void AdjustAtGrid( const SvPtrarr& rRow, SvLBoxEntry* pStart=0 );
+ Point AdjustAtGrid(
+ const Rectangle& rCenterRect, // "Schwerpunkt" des Objekts (typ. Bmp-Rect)
+ const Rectangle& rBoundRect ) const;
+ SvIconViewTextMode GetEntryTextModeSmart( const SvLBoxEntry* pEntry,
+ const SvIcnVwDataEntry* pViewData ) const;
+
+ BOOL CheckVerScrollBar();
+ BOOL CheckHorScrollBar();
+ void CancelUserEvent();
+
+public:
+
+ SvImpIconView( SvIconView* pView, SvLBoxTreeList*, WinBits nWinStyle );
+ ~SvImpIconView();
+
+ void Clear( BOOL bInCtor = FALSE );
+ void SetWindowBits( WinBits nWinStyle );
+ void SetModel( SvLBoxTreeList* pTree, SvLBoxEntry* pParent )
+ { pModel = pTree; SetCurParent(pParent); }
+ void EntryInserted( SvLBoxEntry*);
+ void RemovingEntry( SvLBoxEntry* pEntry );
+ void EntryRemoved();
+ void MovingEntry( SvLBoxEntry* pEntry );
+ void EntryMoved( SvLBoxEntry* pEntry );
+ void TreeInserted( SvLBoxEntry* pEntry );
+ void ChangedFont();
+ void ModelHasEntryInvalidated( SvListEntry* );
+ void EntryExpanded( SvLBoxEntry* pEntry );
+ void EntryCollapsed( SvLBoxEntry* pEntry );
+ void CollapsingEntry( SvLBoxEntry* pEntry );
+ void EntrySelected( SvLBoxEntry*, BOOL bSelect );
+
+ void Paint( const Rectangle& rRect );
+ void RepaintSelectionItems();
+ void MouseButtonDown( const MouseEvent& );
+ void MouseButtonUp( const MouseEvent& );
+ void MouseMove( const MouseEvent&);
+ BOOL KeyInput( const KeyEvent& );
+ void Resize();
+ void GetFocus();
+ void LoseFocus();
+ void UpdateAll();
+ void PaintEntry( SvLBoxEntry* pEntry,
+ SvIcnVwDataEntry* pViewData = 0 );
+ void PaintEntry( SvLBoxEntry*, const Point&,
+ SvIcnVwDataEntry* pViewData = 0, OutputDevice* pOut = 0);
+ void SetEntryPosition( SvLBoxEntry* pEntry, const Point& rPos,
+ BOOL bAdjustRow = FALSE,
+ BOOL bCheckScrollBars = FALSE );
+ void InvalidateEntry( SvLBoxEntry* );
+ void ViewDataInitialized( SvLBoxEntry* pEntry );
+ SvLBoxItem* GetItem( SvLBoxEntry*, const Point& rAbsPos );
+
+ void SetNoSelection();
+ void SetDragDropMode( DragDropMode eDDMode );
+ void SetSelectionMode( SelectionMode eSelMode );
+
+ void SttDrag( const Point& rPos );
+ void EndDrag();
+
+ SvLBoxEntry* GetCurEntry() const { return pCursor; }
+ void SetCursor( SvLBoxEntry* );
+
+ BOOL IsEntryInView( SvLBoxEntry* );
+ SvLBoxEntry* GetEntry( const Point& rDocPos );
+ SvLBoxEntry* GetNextEntry( const Point& rDocPos, SvLBoxEntry* pCurEntry );
+ SvLBoxEntry* GetPrevEntry( const Point& rDocPos, SvLBoxEntry* pCurEntry );
+
+ Point GetEntryPosition( SvLBoxEntry* );
+ void MakeVisible( SvLBoxEntry* pEntry );
+
+ void Arrange();
+
+ void SetSpaceBetweenEntries( long nHor, long Ver );
+ long GetHorSpaceBetweenEntries() const { return nHorDist; }
+ long GetVerSpaceBetweenEntries() const { return nVerDist; }
+
+ Rectangle CalcFocusRect( SvLBoxEntry* );
+
+ Rectangle CalcBmpRect( SvLBoxEntry*, const Point* pPos = 0,
+ SvIcnVwDataEntry* pViewData=0 );
+ Rectangle CalcTextRect( SvLBoxEntry*, SvLBoxString* pItem = 0,
+ const Point* pPos = 0,
+ BOOL bForInplaceEdit = FALSE,
+ SvIcnVwDataEntry* pViewData = 0 );
+
+ long CalcBoundingWidth( SvLBoxEntry*, const SvIcnVwDataEntry* pViewData = 0) const;
+ long CalcBoundingHeight( SvLBoxEntry*, const SvIcnVwDataEntry* pViewData= 0 ) const;
+ Size CalcBoundingSize( SvLBoxEntry*,
+ SvIcnVwDataEntry* pViewData = 0 ) const;
+ void FindBoundingRect( SvLBoxEntry* pEntry,
+ SvIcnVwDataEntry* pViewData = 0 );
+ // berechnet alle BoundRects neu
+ void RecalcAllBoundingRects();
+ // berechnet alle ungueltigen BoundRects neu
+ void RecalcAllBoundingRectsSmart();
+ const Rectangle& GetBoundingRect( SvLBoxEntry*,
+ SvIcnVwDataEntry* pViewData=0);
+ void InvalidateBoundingRect( SvLBoxEntry* );
+ void InvalidateBoundingRect( Rectangle& rRect ) { rRect.Right() = LONG_MAX; }
+ BOOL IsBoundingRectValid( const Rectangle& rRect ) const { return (BOOL)( rRect.Right() != LONG_MAX ); }
+
+ void PaintEmphasis( const Rectangle&, BOOL bSelected,
+ BOOL bCursored, OutputDevice* pOut = 0 );
+ void PaintItem( const Rectangle& rRect, SvLBoxItem* pItem,
+ SvLBoxEntry* pEntry, USHORT nPaintFlags, OutputDevice* pOut = 0 );
+ // berechnet alle BoundingRects neu, wenn bMustRecalcBoundingRects == TRUE
+ void CheckBoundingRects() { if (bMustRecalcBoundingRects) RecalcAllBoundingRects(); }
+ // berechnet alle invalidierten BoundingRects neu
+ void UpdateBoundingRects();
+ void ShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL bShow );
+ SvLBoxEntry* GetDropTarget( const Point& rPosPixel );
+ BOOL NotifyMoving( SvLBoxEntry* pTarget, SvLBoxEntry* pEntry,
+ SvLBoxEntry*& rpNewParent, ULONG& rNewChildPos );
+ BOOL NotifyCopying( SvLBoxEntry* pTarget, SvLBoxEntry* pEntry,
+ SvLBoxEntry*& rpNewParent, ULONG& rNewChildPos );
+
+ void WriteDragServerInfo( const Point&, SvLBoxDDInfo* );
+ void ReadDragServerInfo( const Point&, SvLBoxDDInfo* );
+ void ToTop( SvLBoxEntry* );
+
+ void SetCurParent( SvLBoxEntry* pNewParent );
+ SvLBoxEntry* GetCurParent() const { return pCurParent; }
+ USHORT GetSelectionCount() const;
+ void SetGrid( long nDX, long nDY );
+ void Scroll( long nDeltaX, long nDeltaY, BOOL bScrollBar = FALSE );
+ const Size& GetItemSize( SvIconView* pView, SvLBoxEntry*, SvLBoxItem*,
+ const SvIcnVwDataEntry* pViewData = 0 ) const;
+ void PrepareCommandEvent( const Point& rPt );
+
+ void HideDDIcon();
+ void ShowDDIcon( SvLBoxEntry* pRefEntry, const Point& rPos );
+ void HideShowDDIcon( SvLBoxEntry* pRefEntry, const Point& rPos );
+
+ SvLBoxEntry* mpViewData;
+
+ BOOL IsOver( SvPtrarr* pSelectedRectList, const Rectangle& rEntryBoundRect ) const;
+ void SelectRect( const Rectangle&, BOOL bAdd = TRUE,
+ SvPtrarr* pOtherRects = 0,
+ short nOffs = SELRECT_BORDER_OFFS );
+ void DrawSelectionRect( const Rectangle& );
+ void HideSelectionRect();
+ void CalcScrollOffsets( const Point& rRefPosPixel,
+ long& rX, long& rY, BOOL bDragDrop = FALSE,
+ USHORT nBorderWidth = 10 );
+ void EndTracking();
+ BOOL IsTextHit( SvLBoxEntry* pEntry, const Point& rDocPos );
+ void MakeVisible( const Rectangle& rDocPos,BOOL bInScrollBarEvent=FALSE);
+ void AdjustAtGrid( SvLBoxEntry* pStart = 0 );
+ void SetTextMode( SvIconViewTextMode, SvLBoxEntry* pEntry = 0 );
+ SvIconViewTextMode GetTextMode( const SvLBoxEntry* pEntry = 0,
+ const SvIcnVwDataEntry* pViewData = 0 ) const;
+ void ShowFocusRect( const SvLBoxEntry* pEntry );
+};
+
+inline void SvImpIconView::MakeVisible( SvLBoxEntry* pEntry )
+{
+ const Rectangle& rRect = GetBoundingRect( pEntry );
+ MakeVisible( rRect );
+}
+
+#endif // #ifndef _SVIMPICN_HXX
+
+
diff --git a/svtools/source/inc/svtaccessiblefactory.hxx b/svtools/source/inc/svtaccessiblefactory.hxx
new file mode 100644
index 000000000000..7760b6427da4
--- /dev/null
+++ b/svtools/source/inc/svtaccessiblefactory.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 SVTOOLS_ACCESSIBLE_FACTORY_ACCESS_HXX
+#define SVTOOLS_ACCESSIBLE_FACTORY_ACCESS_HXX
+
+#include <svtools/accessiblefactory.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= AccessibleFactoryAccess
+ //====================================================================
+ /** a client for the accessibility implementations which have been outsourced
+ from the main svtools library
+
+ All instances of this class share a reference to a common IAccessibleFactory
+ instance, which is used for creating all kind of Accessibility related
+ components.
+
+ When the AccessibleFactoryAccess goes aways, this factory goes aways, to, and the respective
+ library is unloaded.
+
+ This class is not thread-safe.
+ */
+ class AccessibleFactoryAccess
+ {
+ private:
+ bool m_bInitialized;
+
+ public:
+ AccessibleFactoryAccess();
+ ~AccessibleFactoryAccess();
+
+ IAccessibleFactory& getFactory();
+
+ private:
+ void ensureInitialized();
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // SVTOOLS_ACCESSIBLE_FACTORY_ACCESS_HXX
+
diff --git a/svtools/source/inc/unoiface.hxx b/svtools/source/inc/unoiface.hxx
new file mode 100644
index 000000000000..f15cb7c10d4c
--- /dev/null
+++ b/svtools/source/inc/unoiface.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _SVT_UNOIFACE_HXX
+#define _SVT_UNOIFACE_HXX
+
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxwindows.hxx>
+#include <toolkit/helper/listenermultiplexer.hxx>
+
+#include <cppuhelper/typeprovider.hxx>
+
+#include <com/sun/star/awt/XTextArea.hpp>
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/awt/XTextLayoutConstrains.hpp>
+#include <svtools/svmedit.hxx>
+#include <svtools/fmtfield.hxx>
+
+
+#include <comphelper/uno3.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <com/sun/star/awt/XItemEventBroadcaster.hpp>
+
+
+namespace com { namespace sun { namespace star { namespace util {
+ class XNumberFormatsSupplier;
+} } } }
+
+class SvNumberFormatsSupplierObj;
+
+// ----------------------------------------------------
+// class VCLXMultiLineEdit
+// ----------------------------------------------------
+class VCLXMultiLineEdit : public ::com::sun::star::awt::XTextComponent,
+ public ::com::sun::star::awt::XTextArea,
+ public ::com::sun::star::awt::XTextLayoutConstrains,
+ public VCLXWindow
+{
+private:
+ TextListenerMultiplexer maTextListeners;
+ LineEnd meLineEndType;
+
+protected:
+ void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
+
+public:
+ VCLXMultiLineEdit();
+ ~VCLXMultiLineEdit();
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { VCLXWindow::acquire(); }
+ void SAL_CALL release() throw() { VCLXWindow::release(); }
+
+ // ::com::sun::star::lang::XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XTextComponent
+ void SAL_CALL addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener >& l ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener >& l ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL insertText( const ::com::sun::star::awt::Selection& Sel, const ::rtl::OUString& Text ) throw(::com::sun::star::uno::RuntimeException);
+ ::rtl::OUString SAL_CALL getText( ) throw(::com::sun::star::uno::RuntimeException);
+ ::rtl::OUString SAL_CALL getSelectedText( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Selection SAL_CALL getSelection( ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL isEditable( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Int16 SAL_CALL getMaxTextLen( ) throw(::com::sun::star::uno::RuntimeException);
+
+ //XTextArea
+ ::rtl::OUString SAL_CALL getTextLines( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XLayoutConstrains
+ ::com::sun::star::awt::Size SAL_CALL getMinimumSize( ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Size SAL_CALL getPreferredSize( ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Size SAL_CALL calcAdjustedSize( const ::com::sun::star::awt::Size& aNewSize ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XTextLayoutConstrains
+ ::com::sun::star::awt::Size SAL_CALL getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XVclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XWindow
+ void SAL_CALL setFocus( ) throw(::com::sun::star::uno::RuntimeException);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+
+// ----------------------------------------------------
+// class VCLXFileControl
+// ----------------------------------------------------
+class VCLXFileControl : ::com::sun::star::awt::XTextComponent, public ::com::sun::star::awt::XTextLayoutConstrains, public VCLXWindow
+{
+protected:
+ DECL_LINK( ModifyHdl, Edit* );
+ TextListenerMultiplexer maTextListeners;
+
+public:
+ VCLXFileControl();
+ ~VCLXFileControl();
+
+ void SetWindow( Window* pWindow );
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { VCLXWindow::acquire(); }
+ void SAL_CALL release() throw() { VCLXWindow::release(); }
+
+ // ::com::sun::star::lang::XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XTextComponent
+ void SAL_CALL addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener >& l ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener >& l ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL insertText( const ::com::sun::star::awt::Selection& Sel, const ::rtl::OUString& Text ) throw(::com::sun::star::uno::RuntimeException);
+ ::rtl::OUString SAL_CALL getText( ) throw(::com::sun::star::uno::RuntimeException);
+ ::rtl::OUString SAL_CALL getSelectedText( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Selection SAL_CALL getSelection( ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL isEditable( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Int16 SAL_CALL getMaxTextLen( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XLayoutConstrains
+ ::com::sun::star::awt::Size SAL_CALL getMinimumSize( ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Size SAL_CALL getPreferredSize( ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Size SAL_CALL calcAdjustedSize( const ::com::sun::star::awt::Size& aNewSize ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XTextLayoutConstrains
+ ::com::sun::star::awt::Size SAL_CALL getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException);
+
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+// ----------------------------------------------------
+// class SVTXFormattedField
+// ----------------------------------------------------
+
+class SVTXFormattedField : public VCLXSpinField
+{
+protected:
+ SvNumberFormatsSupplierObj* m_pCurrentSupplier;
+ sal_Bool bIsStandardSupplier;
+
+ sal_Int32 nKeyToSetDelayed;
+
+ FormattedField* GetFormattedField() const { return (FormattedField*)GetWindow(); }
+
+public:
+ SVTXFormattedField();
+ ~SVTXFormattedField();
+
+ // ::com::sun::star::awt::XVclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > getFormatsSupplier(void) const;
+ void setFormatsSupplier(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xSupplier);
+ sal_Int32 getFormatKey(void) const;
+ void setFormatKey(sal_Int32 nKey);
+
+ void SetValue(const ::com::sun::star::uno::Any& rValue);
+ ::com::sun::star::uno::Any GetValue();
+
+ void SetTreatAsNumber(sal_Bool bSet);
+ sal_Bool GetTreatAsNumber();
+
+ void SetDefaultValue(const ::com::sun::star::uno::Any& rValue);
+ ::com::sun::star::uno::Any GetDefaultValue();
+
+ void SetMinValue(const ::com::sun::star::uno::Any& rValue);
+ ::com::sun::star::uno::Any GetMinValue();
+
+ void SetMaxValue(const ::com::sun::star::uno::Any& rValue);
+ ::com::sun::star::uno::Any GetMaxValue();
+
+ void NotifyTextListeners();
+ ::com::sun::star::uno::Any convertEffectiveValue(const ::com::sun::star::uno::Any& rValue);
+
+ virtual void SetWindow(Window* _pWindow);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+
+
+// ----------------------------------------------------
+// class SVTXRoadmap
+// ----------------------------------------------------
+
+namespace svt
+{
+ class ORoadmap;
+}
+
+struct RMItemData
+{
+ sal_Bool b_Enabled;
+ sal_Int32 n_ID;
+ ::rtl::OUString Label;
+};
+
+typedef ::cppu::ImplInheritanceHelper3 < VCLXGraphicControl
+ , ::com::sun::star::container::XContainerListener
+ , ::com::sun::star::beans::XPropertyChangeListener
+ , ::com::sun::star::awt::XItemEventBroadcaster
+ > SVTXRoadmap_Base;
+class SVTXRoadmap : public SVTXRoadmap_Base
+
+
+{
+private:
+ ItemListenerMultiplexer maItemListeners;
+
+ RMItemData CurRMItemData;
+ RMItemData GetRMItemData( const ::com::sun::star::container::ContainerEvent& _rEvent );
+
+protected:
+ ::svt::ORoadmap* GetRoadmap() const { return (::svt::ORoadmap*)GetWindow(); }
+ void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
+
+ ~SVTXRoadmap();
+
+public:
+ SVTXRoadmap();
+
+ void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) { VCLXWindow::disposing( Source ); }
+
+ // ::com::sun::star::awt::XVclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XContainerListener
+ void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& rEvent )throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& rEvent )throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& rEvent )throw(::com::sun::star::uno::RuntimeException);
+
+ // XItemEventBroadcaster
+ virtual void SAL_CALL addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+
+ // VCLXGraphicControl overridables
+ virtual void ImplSetNewImage();
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+
+
+// ----------------------------------------------------
+// class SVTXNumericField
+// ----------------------------------------------------
+class SVTXNumericField : public ::com::sun::star::awt::XNumericField, public SVTXFormattedField
+{
+public:
+ SVTXNumericField();
+ ~SVTXNumericField();
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { SVTXFormattedField::acquire(); }
+ void SAL_CALL release() throw() { SVTXFormattedField::release(); }
+
+ // ::com::sun::star::lang::XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XNumericField
+ void SAL_CALL setValue( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getValue( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setMin( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getMin( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setMax( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getMax( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getFirst( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setLast( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getLast( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getSpinSize( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setDecimalDigits( sal_Int16 nDigits ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Int16 SAL_CALL getDecimalDigits( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL isStrictFormat( ) throw(::com::sun::star::uno::RuntimeException);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+ // ----------------------------------------------------
+// class VCLXCurrencyField
+// ----------------------------------------------------
+class SVTXCurrencyField : public ::com::sun::star::awt::XCurrencyField, public SVTXFormattedField
+{
+public:
+ SVTXCurrencyField();
+ ~SVTXCurrencyField();
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { SVTXFormattedField::acquire(); }
+ void SAL_CALL release() throw() { SVTXFormattedField::release(); }
+
+ // ::com::sun::star::lang::XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XVclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XCurrencyField
+ void SAL_CALL setValue( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getValue( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setMin( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getMin( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setMax( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getMax( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getFirst( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setLast( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getLast( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException);
+ double SAL_CALL getSpinSize( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setDecimalDigits( sal_Int16 nDigits ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Int16 SAL_CALL getDecimalDigits( ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL isStrictFormat( ) throw(::com::sun::star::uno::RuntimeException);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+// ----------------------------------------------------
+// class VCLXProgressBar
+// ----------------------------------------------------
+class VCLXProgressBar : public ::com::sun::star::awt::XProgressBar,
+ public VCLXWindow
+{
+private:
+ sal_Int32 m_nValue;
+ sal_Int32 m_nValueMin;
+ sal_Int32 m_nValueMax;
+
+protected:
+ void ImplUpdateValue();
+
+public:
+ VCLXProgressBar();
+ ~VCLXProgressBar();
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { VCLXWindow::acquire(); }
+ void SAL_CALL release() throw() { VCLXWindow::release(); }
+
+ // ::com::sun::star::lang::XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XProgressBar
+ void SAL_CALL setForegroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setBackgroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setValue( sal_Int32 nValue ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setRange( sal_Int32 nMin, sal_Int32 nMax ) throw(::com::sun::star::uno::RuntimeException );
+ sal_Int32 SAL_CALL getValue() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::VclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+// ----------------------------------------------------
+// class SVTXDateField
+// ----------------------------------------------------
+class SVTXDateField : public VCLXDateField
+{
+public:
+ SVTXDateField();
+ ~SVTXDateField();
+
+ // ::com::sun::star::awt::VclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
+};
+
+#endif // _SVT_UNOIFACE_HXX
diff --git a/svtools/source/inc/xbmread.hxx b/svtools/source/inc/xbmread.hxx
new file mode 100644
index 000000000000..aab52eeffa63
--- /dev/null
+++ b/svtools/source/inc/xbmread.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 _XBMREAD_HXX
+#define _XBMREAD_HXX
+
+#ifndef _GRAPH_HXX
+#include <vcl/graph.hxx>
+#endif
+#ifndef _BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+
+#ifdef _XBMPRIVATE
+
+// ---------
+// - Enums -
+// ---------
+
+enum XBMFormat
+{
+ XBM10,
+ XBM11
+};
+
+enum ReadState
+{
+ XBMREAD_OK,
+ XBMREAD_ERROR,
+ XBMREAD_NEED_MORE
+};
+
+// -------------
+// - XBMReader -
+// -------------
+
+class XBMReader : public GraphicReader
+{
+ SvStream& rIStm;
+ Bitmap aBmp1;
+ BitmapWriteAccess* pAcc1;
+ short* pHexTable;
+ BitmapColor aWhite;
+ BitmapColor aBlack;
+ long nLastPos;
+ long nWidth;
+ long nHeight;
+ BOOL bStatus;
+
+ void InitTable();
+ ByteString FindTokenLine( SvStream* pInStm, const char* pTok1,
+ const char* pTok2 = NULL, const char* pTok3 = NULL );
+ long ParseDefine( const sal_Char* pDefine );
+ BOOL ParseData( SvStream* pInStm, const ByteString& aLastLine, XBMFormat eFormat );
+
+
+public:
+
+ XBMReader( SvStream& rStm );
+ virtual ~XBMReader();
+
+ ReadState ReadXBM( Graphic& rGraphic );
+};
+
+#endif // _XBMPRIVATE
+
+// -------------
+// - ImportXBM -
+// -------------
+
+BOOL ImportXBM( SvStream& rStream, Graphic& rGraphic );
+
+#endif // _XBMREAD_HXX
diff --git a/svtools/source/inc/xpmread.hxx b/svtools/source/inc/xpmread.hxx
new file mode 100644
index 000000000000..29edd15a3b1c
--- /dev/null
+++ b/svtools/source/inc/xpmread.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _XPMREAD_HXX
+#define _XPMREAD_HXX
+
+#ifndef _BITMAP_HXX
+#include <vcl/bitmap.hxx>
+#endif
+
+#ifdef _XPMPRIVATE
+
+#define XPMTEMPBUFSIZE 0x00008000
+#define XPMSTRINGBUF 0x00008000
+
+#define XPMIDENTIFIER 0x00000001 // mnIdentifier includes on of the six phases
+#define XPMDEFINITION 0x00000002 // the XPM format consists of
+#define XPMVALUES 0x00000003
+#define XPMCOLORS 0x00000004
+#define XPMPIXELS 0x00000005
+#define XPMEXTENSIONS 0x00000006
+#define XPMENDEXT 0x00000007
+
+
+#define XPMREMARK 0x00000001 // defines used by mnStatus
+#define XPMDOUBLE 0x00000002
+#define XPMSTRING 0x00000004
+#define XPMFINISHED 0x00000008
+
+#define XPMCASESENSITIVE 0x00000001
+#define XPMCASENONSENSITIVE 0x00000002
+
+// ---------
+// - Enums -
+// ---------
+
+enum ReadState
+{
+ XPMREAD_OK,
+ XPMREAD_ERROR,
+ XPMREAD_NEED_MORE
+};
+
+// -------------
+// - XPMReader -
+// -------------
+
+class BitmapWriteAccess;
+class Graphic;
+
+class XPMReader : public GraphicReader
+{
+private:
+
+ SvStream& mrIStm;
+ Bitmap maBmp;
+ BitmapWriteAccess* mpAcc;
+ Bitmap maMaskBmp;
+ BitmapWriteAccess* mpMaskAcc;
+ long mnLastPos;
+
+ ULONG mnWidth;
+ ULONG mnHeight;
+ ULONG mnColors;
+ ULONG mnCpp; // characters per pix
+ BOOL mbTransparent;
+ BOOL mbStatus;
+ ULONG mnStatus;
+ ULONG mnIdentifier;
+ BYTE mcThisByte;
+ BYTE mcLastByte;
+ ULONG mnTempAvail;
+ BYTE* mpTempBuf;
+ BYTE* mpTempPtr;
+ BYTE* mpFastColorTable;
+ BYTE* mpColMap;
+ ULONG mnStringSize;
+ BYTE* mpStringBuf;
+ ULONG mnParaSize;
+ BYTE* mpPara;
+
+ BOOL ImplGetString( void );
+ BOOL ImplGetColor( ULONG );
+ BOOL ImplGetScanLine( ULONG );
+ BOOL ImplGetColSub( BYTE* );
+ BOOL ImplGetColKey( BYTE );
+ void ImplGetRGBHex( BYTE*, ULONG );
+ BOOL ImplGetPara( ULONG numb );
+ BOOL ImplCompare( BYTE*, BYTE*, ULONG, ULONG nmode = XPMCASENONSENSITIVE );
+ ULONG ImplGetULONG( ULONG nPara );
+
+public:
+ XPMReader( SvStream& rStm );
+ virtual ~XPMReader();
+
+ ReadState ReadXPM( Graphic& rGraphic );
+};
+
+#endif // _XPMPRIVATE
+
+// -------------
+// - ImportXPM -
+// -------------
+
+BOOL ImportXPM( SvStream& rStream, Graphic& rGraphic );
+
+#endif // _XPMREAD_HXX
diff --git a/svtools/source/java/javacontext.cxx b/svtools/source/java/javacontext.cxx
new file mode 100644
index 000000000000..7ebd3ea76d1f
--- /dev/null
+++ b/svtools/source/java/javacontext.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_svtools.hxx"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Type.hxx"
+#include <svtools/svtdata.hxx>
+#include <svtools/javacontext.hxx>
+#include <svtools/javainteractionhandler.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::task;
+namespace svt
+{
+
+JavaContext::JavaContext( const Reference< XCurrentContext > & ctx )
+ :
+ m_aRefCount(0),
+ m_xNextContext( ctx ),
+ m_bShowErrorsOnce(false)
+{
+}
+
+JavaContext::JavaContext( const Reference< XCurrentContext > & ctx,
+ bool bShowErrorsOnce)
+ : m_aRefCount(0),
+ m_xNextContext( ctx ),
+ m_bShowErrorsOnce(bShowErrorsOnce)
+{
+}
+
+JavaContext::~JavaContext()
+{
+}
+
+Any SAL_CALL JavaContext::queryInterface(const Type& aType )
+ throw (RuntimeException)
+{
+ if (aType == getCppuType(reinterpret_cast<Reference<XInterface>*>(0)))
+ return Any(Reference<XInterface>(static_cast<XInterface*>(this)));
+ else if (aType == getCppuType(reinterpret_cast<Reference<XCurrentContext>*>(0)))
+ return Any(Reference<XCurrentContext>( static_cast<XCurrentContext*>(this)));
+ return Any();
+}
+
+void SAL_CALL JavaContext::acquire( ) throw ()
+{
+ osl_incrementInterlockedCount( &m_aRefCount );
+}
+
+void SAL_CALL JavaContext::release( ) throw ()
+{
+ if (! osl_decrementInterlockedCount( &m_aRefCount ))
+ delete this;
+}
+
+Any SAL_CALL JavaContext::getValueByName( const ::rtl::OUString& Name) throw (RuntimeException)
+{
+ Any retVal;
+
+ if ( 0 == Name.compareToAscii( JAVA_INTERACTION_HANDLER_NAME ))
+ {
+ {
+ osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex());
+ if (!m_xHandler.is())
+ m_xHandler = Reference< XInteractionHandler >(
+ new JavaInteractionHandler(m_bShowErrorsOnce));
+ }
+ retVal = makeAny(m_xHandler);
+
+ }
+ else if( m_xNextContext.is() )
+ {
+ // Call next context in chain if found
+ retVal = m_xNextContext->getValueByName( Name );
+ }
+ return retVal;
+}
+
+
+}
diff --git a/svtools/source/java/javaerror.src b/svtools/source/java/javaerror.src
new file mode 100644
index 000000000000..d5990c05a663
--- /dev/null
+++ b/svtools/source/java/javaerror.src
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <svtools/svtools.hrc>
+
+WarningBox WARNINGBOX_JAVANOTFOUND
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] ="%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task. Please install a JRE and restart %PRODUCTNAME.";
+};
+
+WarningBox WARNINGBOX_INVALIDJAVASETTINGS
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] ="The %PRODUCTNAME configuration has been changed. Under Tools - Options - %PRODUCTNAME - Java, select the Java runtime environment you want to have used by %PRODUCTNAME.";
+};
+
+QueryBox QBX_JAVADISABLED
+{
+ Buttons = WB_YES_NO_CANCEL ;
+ DefButton = WB_DEF_YES ;
+ Message[ en-US ] = "%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task. However, use of a JRE has been disabled. Do you want to enable the use of a JRE now?";
+};
+
+ErrorBox ERRORBOX_JVMCREATIONFAILED
+{
+ Buttons = WB_OK;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] = "%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task. The selected JRE is defective. Please select another version or install a new JRE and select it under Tools - Options - %PRODUCTNAME - Java.";
+};
+
+ErrorBox ERRORBOX_RESTARTREQUIRED
+{
+ Buttons = WB_OK;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] = "For the selected Java runtime environment to work properly, %PRODUCTNAME must be restarted. Please restart %PRODUCTNAME now.";
+};
+
+
+
+String STR_WARNING_JAVANOTFOUND
+{
+ Text[ en-US ] = "JRE Required" ;
+};
+
+String STR_WARNING_INVALIDJAVASETTINGS
+{
+ Text[ en-US ] = "Select JRE";
+};
+
+String STR_ERROR_RESTARTREQUIRED
+{
+ Text[ en-US ] = "Restart Required";
+};
+
+String STR_QUESTION_JAVADISABLED
+{
+ Text[ en-US ] = "Enable JRE" ;
+};
+
+
+String STR_ERROR_JVMCREATIONFAILED
+{
+ Text[ en-US ] = "JRE is Defective" ;
+};
+
+
diff --git a/svtools/source/java/javainteractionhandler.cxx b/svtools/source/java/javainteractionhandler.cxx
new file mode 100644
index 000000000000..ec34ed07f25d
--- /dev/null
+++ b/svtools/source/java/javainteractionhandler.cxx
@@ -0,0 +1,340 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+
+
+#include <svtools/svtools.hrc>
+#include <tools/resid.hxx>
+#include <com/sun/star/task/XInteractionContinuation.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/task/XInteractionRetry.hpp>
+#include <com/sun/star/java/JavaNotFoundException.hpp>
+#include <com/sun/star/java/InvalidJavaSettingsException.hpp>
+#include <com/sun/star/java/JavaDisabledException.hpp>
+#include <com/sun/star/java/JavaVMCreationFailureException.hpp>
+#include <com/sun/star/java/RestartRequiredException.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vos/mutex.hxx>
+#include <tools/string.hxx>
+#include <tools/rcid.h>
+#include <jvmfwk/framework.h>
+
+#include <svtools/svtdata.hxx>
+#include <svtools/javainteractionhandler.hxx>
+#include <svtools/javacontext.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::task;
+
+namespace svt
+{
+
+JavaInteractionHandler::JavaInteractionHandler():
+ m_aRefCount(0),
+ m_bShowErrorsOnce(false),
+ m_bJavaDisabled_Handled(false),
+ m_bInvalidSettings_Handled(false),
+ m_bJavaNotFound_Handled(false),
+ m_bVMCreationFailure_Handled(false),
+ m_bRestartRequired_Handled(false),
+ m_nResult_JavaDisabled(RET_NO)
+{
+}
+
+JavaInteractionHandler::JavaInteractionHandler(bool bReportErrorOnce) :
+ m_aRefCount(0),
+ m_bShowErrorsOnce(bReportErrorOnce),
+ m_bJavaDisabled_Handled(false),
+ m_bInvalidSettings_Handled(false),
+ m_bJavaNotFound_Handled(false),
+ m_bVMCreationFailure_Handled(false),
+ m_bRestartRequired_Handled(false),
+ m_nResult_JavaDisabled(RET_NO)
+{
+}
+
+JavaInteractionHandler::~JavaInteractionHandler()
+{
+}
+
+Any SAL_CALL JavaInteractionHandler::queryInterface(const Type& aType )
+ throw (RuntimeException)
+{
+ if (aType == getCppuType(reinterpret_cast<Reference<XInterface>*>(0)))
+ return Any( static_cast<XInterface*>(this), aType);
+ else if (aType == getCppuType(reinterpret_cast<Reference<XInteractionHandler>*>(0)))
+ return Any( static_cast<XInteractionHandler*>(this), aType);
+ return Any();
+}
+
+void SAL_CALL JavaInteractionHandler::acquire( ) throw ()
+{
+ osl_incrementInterlockedCount( &m_aRefCount );
+}
+
+void SAL_CALL JavaInteractionHandler::release( ) throw ()
+{
+ if (! osl_decrementInterlockedCount( &m_aRefCount ))
+ delete this;
+}
+
+
+void SAL_CALL JavaInteractionHandler::handle( const Reference< XInteractionRequest >& Request ) throw (RuntimeException)
+{
+ Any anyExc = Request->getRequest();
+ Sequence< Reference< XInteractionContinuation > > aSeqCont = Request->getContinuations();
+
+ Reference< XInteractionAbort > abort;
+ Reference< XInteractionRetry > retry;
+ sal_Int32 i;
+
+ for ( i = 0; i < aSeqCont.getLength(); i++ )
+ {
+ abort = Reference< XInteractionAbort>::query( aSeqCont[i]);
+ if ( abort.is() )
+ break;
+ }
+
+ for ( i= 0; i < aSeqCont.getLength(); i++)
+ {
+ retry= Reference<XInteractionRetry>::query( aSeqCont[i]);
+ if ( retry.is() )
+ break;
+ }
+
+ com::sun::star::java::JavaNotFoundException e1;
+ com::sun::star::java::InvalidJavaSettingsException e2;
+ com::sun::star::java::JavaDisabledException e3;
+ com::sun::star::java::JavaVMCreationFailureException e4;
+ com::sun::star::java::RestartRequiredException e5;
+ // Try to recover the Exception type in the any and
+ // react accordingly.
+ USHORT nResult = RET_CANCEL;
+ ::rtl::OUString aParameter;
+
+ if ( anyExc >>= e1 )
+ {
+ if( ! (m_bShowErrorsOnce && m_bJavaNotFound_Handled))
+ {
+ // No suitable JRE found
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_bJavaNotFound_Handled = true;
+ //We first try to get the patch resource svp680xxx.res
+ //If the resource is not found then svt680xxx.res is used
+ ResId idWBX = SvtResId(WARNINGBOX_JAVANOTFOUND);
+ SvpResId pidPatchWBX(WARNINGBOX_JAVANOTFOUND);
+ pidPatchWBX.SetRT(RSC_WARNINGBOX);
+ ResMgr *pMgrWB = pidPatchWBX.GetResMgr();
+ if (pMgrWB && pMgrWB->IsAvailable(pidPatchWBX))
+ idWBX = pidPatchWBX;
+ WarningBox aWarningBox( NULL, idWBX);
+
+ String aTitle;
+ SvpResId pidString(STR_WARNING_JAVANOTFOUND);
+ pidString.SetRT(RSC_STRING);
+ ResMgr *pmgr = pidString.GetResMgr();
+ if ( pmgr && pmgr->IsAvailable(pidString))
+ aTitle = String(pidString);
+ else
+ aTitle = String( SvtResId( STR_WARNING_JAVANOTFOUND ));
+
+ aWarningBox.SetText( aTitle );
+ nResult = aWarningBox.Execute();
+
+ }
+ else
+ {
+ nResult = RET_OK;
+ }
+ }
+ else if ( anyExc >>= e2 )
+ {
+ if( !(m_bShowErrorsOnce && m_bInvalidSettings_Handled))
+ {
+ // javavendors.xml was updated and Java has not been configured yet
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_bInvalidSettings_Handled = true;
+ //We first try to get the patch resource svp680xxx.res
+ //If the resource is not found then svt680xxx.res is used
+ ResId idWBX = SvtResId(WARNINGBOX_INVALIDJAVASETTINGS);
+ SvpResId pidPatchWBX(WARNINGBOX_INVALIDJAVASETTINGS);
+ pidPatchWBX.SetRT(RSC_WARNINGBOX);
+ ResMgr *pMgrWB = pidPatchWBX.GetResMgr();
+ if (pMgrWB && pMgrWB->IsAvailable(pidPatchWBX))
+ idWBX = pidPatchWBX;
+ WarningBox aWarningBox( NULL, idWBX);
+
+ String aTitle;
+ SvpResId pidString(STR_WARNING_INVALIDJAVASETTINGS);
+ pidString.SetRT(RSC_STRING);
+ ResMgr *pmgr = pidString.GetResMgr();
+ if ( pmgr && pmgr->IsAvailable(pidString))
+ aTitle = String(pidString);
+ else
+ aTitle = String( SvtResId(STR_WARNING_INVALIDJAVASETTINGS));
+
+ aWarningBox.SetText( aTitle );
+ nResult = aWarningBox.Execute();
+ }
+ else
+ {
+ nResult = RET_OK;
+ }
+ }
+ else if ( anyExc >>= e3 )
+ {
+ if( !(m_bShowErrorsOnce && m_bJavaDisabled_Handled))
+ {
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_bJavaDisabled_Handled = true;
+ // Java disabled. Give user a chance to enable Java inside Office.
+ //We first try to get the patch resource svp680xxx.res
+ //If the resource is not found then svt680xxx.res is used
+ ResId idQBX = SvtResId( QBX_JAVADISABLED );
+ SvpResId pidPatchQBX(QBX_JAVADISABLED);
+ pidPatchQBX.SetRT(RSC_QUERYBOX);
+ ResMgr *pMgrQB = pidPatchQBX.GetResMgr();
+
+ if (pMgrQB && pMgrQB->IsAvailable(pidPatchQBX))
+ idQBX = pidPatchQBX;
+
+ QueryBox aQueryBox(NULL, idQBX);
+
+ String aTitle;
+
+ SvpResId pidString(STR_QUESTION_JAVADISABLED);
+ pidString.SetRT(RSC_STRING);
+ ResMgr *pmgr = pidString.GetResMgr();
+ if ( pmgr && pmgr->IsAvailable(pidString))
+ aTitle = String(pidString);
+ else
+ aTitle = String( SvtResId( STR_QUESTION_JAVADISABLED ));
+
+ aQueryBox.SetText( aTitle );
+ nResult = aQueryBox.Execute();
+ if ( nResult == RET_YES )
+ {
+ jfw_setEnabled(sal_True);
+ }
+
+ m_nResult_JavaDisabled = nResult;
+
+ }
+ else
+ {
+ nResult = m_nResult_JavaDisabled;
+ }
+ }
+ else if ( anyExc >>= e4 )
+ {
+ if( !(m_bShowErrorsOnce && m_bVMCreationFailure_Handled))
+ {
+ // Java not correctly installed, or damaged
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_bVMCreationFailure_Handled = true;
+ //We first try to get the patch resource svp680xxx.res
+ //If the resource is not found then svt680xxx.res is used
+ ResId idEBX = SvtResId(ERRORBOX_JVMCREATIONFAILED);
+ SvpResId pidPatchEBX(ERRORBOX_JVMCREATIONFAILED);
+ pidPatchEBX.SetRT(RSC_ERRORBOX);
+ ResMgr *pMgrEB = pidPatchEBX.GetResMgr();
+ if (pMgrEB && pMgrEB->IsAvailable(pidPatchEBX))
+ idEBX = pidPatchEBX;
+ ErrorBox aErrorBox( NULL, idEBX);
+
+ String aTitle;
+ SvpResId pidString(STR_ERROR_JVMCREATIONFAILED);
+ pidString.SetRT(RSC_STRING);
+ ResMgr *pmgr = pidString.GetResMgr();
+ if ( pmgr && pmgr->IsAvailable(pidString))
+ aTitle = String(pidString);
+ else
+ aTitle = String( SvtResId(STR_ERROR_JVMCREATIONFAILED));
+
+ aErrorBox.SetText( aTitle );
+ nResult = aErrorBox.Execute();
+ }
+ else
+ {
+ nResult = RET_OK;
+ }
+ }
+ else if ( anyExc >>= e5 )
+ {
+ if( !(m_bShowErrorsOnce && m_bRestartRequired_Handled))
+ {
+ // a new JRE was selected, but office needs to be restarted
+ //before it can be used.
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_bRestartRequired_Handled = true;
+ //We first try to get the patch resource svp680xxx.res
+ //If the resource is not found then svt680xxx.res is used
+ ResId idEBX = SvtResId(ERRORBOX_RESTARTREQUIRED);
+ SvpResId pidPatchEBX(ERRORBOX_RESTARTREQUIRED);
+ pidPatchEBX.SetRT(RSC_ERRORBOX);
+ ResMgr *pMgrEB = pidPatchEBX.GetResMgr();
+ if (pMgrEB && pMgrEB->IsAvailable(pidPatchEBX))
+ idEBX = pidPatchEBX;
+ ErrorBox aErrorBox(NULL, idEBX);
+
+ String aTitle;
+ SvpResId pidString(STR_ERROR_RESTARTREQUIRED);
+ pidString.SetRT(RSC_STRING);
+ ResMgr *pmgr = pidString.GetResMgr();
+ if ( pmgr && pmgr->IsAvailable(pidString))
+ aTitle = String(pidString);
+ else
+ aTitle = String( SvtResId(STR_ERROR_RESTARTREQUIRED));
+
+ aErrorBox.SetText( aTitle );
+ nResult = aErrorBox.Execute();
+ }
+ else
+ {
+ nResult = RET_OK;
+ }
+ }
+
+ if ( nResult == RET_CANCEL || nResult == RET_NO)
+ {
+ // Unknown exception type or user wants to cancel
+ if ( abort.is() )
+ abort->select();
+ }
+ else // nResult == RET_OK
+ {
+ // User selected OK => retry Java usage
+ if ( retry.is() )
+ retry->select();
+ }
+}
+
+}
diff --git a/svtools/source/java/makefile.mk b/svtools/source/java/makefile.mk
new file mode 100644
index 000000000000..6db57388dca0
--- /dev/null
+++ b/svtools/source/java/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=svtools
+TARGET=java
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME= javaerror
+SRC1FILES= javaerror.src
+
+SRS2NAME= patchjavaerror
+SRC2FILES= patchjavaerror.src
+
+
+SLOFILES= \
+ $(SLO)$/javainteractionhandler.obj \
+ $(SLO)$/javacontext.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/java/patchjavaerror.src b/svtools/source/java/patchjavaerror.src
new file mode 100644
index 000000000000..d5990c05a663
--- /dev/null
+++ b/svtools/source/java/patchjavaerror.src
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <svtools/svtools.hrc>
+
+WarningBox WARNINGBOX_JAVANOTFOUND
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] ="%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task. Please install a JRE and restart %PRODUCTNAME.";
+};
+
+WarningBox WARNINGBOX_INVALIDJAVASETTINGS
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] ="The %PRODUCTNAME configuration has been changed. Under Tools - Options - %PRODUCTNAME - Java, select the Java runtime environment you want to have used by %PRODUCTNAME.";
+};
+
+QueryBox QBX_JAVADISABLED
+{
+ Buttons = WB_YES_NO_CANCEL ;
+ DefButton = WB_DEF_YES ;
+ Message[ en-US ] = "%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task. However, use of a JRE has been disabled. Do you want to enable the use of a JRE now?";
+};
+
+ErrorBox ERRORBOX_JVMCREATIONFAILED
+{
+ Buttons = WB_OK;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] = "%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task. The selected JRE is defective. Please select another version or install a new JRE and select it under Tools - Options - %PRODUCTNAME - Java.";
+};
+
+ErrorBox ERRORBOX_RESTARTREQUIRED
+{
+ Buttons = WB_OK;
+ DefButton = WB_DEF_OK ;
+ Message[ en-US ] = "For the selected Java runtime environment to work properly, %PRODUCTNAME must be restarted. Please restart %PRODUCTNAME now.";
+};
+
+
+
+String STR_WARNING_JAVANOTFOUND
+{
+ Text[ en-US ] = "JRE Required" ;
+};
+
+String STR_WARNING_INVALIDJAVASETTINGS
+{
+ Text[ en-US ] = "Select JRE";
+};
+
+String STR_ERROR_RESTARTREQUIRED
+{
+ Text[ en-US ] = "Restart Required";
+};
+
+String STR_QUESTION_JAVADISABLED
+{
+ Text[ en-US ] = "Enable JRE" ;
+};
+
+
+String STR_ERROR_JVMCREATIONFAILED
+{
+ Text[ en-US ] = "JRE is Defective" ;
+};
+
+
diff --git a/svtools/source/misc/acceleratorexecute.cxx b/svtools/source/misc/acceleratorexecute.cxx
new file mode 100644
index 000000000000..6458e359a49c
--- /dev/null
+++ b/svtools/source/misc/acceleratorexecute.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_svtools.hxx"
+#include "acceleratorexecute.hxx"
+
+//===============================================
+// includes
+
+#ifndef __COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
+#include <com/sun/star/frame/XModuleManager.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_FRAME_XDESKTOP_HPP_
+#include <com/sun/star/frame/XDesktop.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPPLIER_HPP_
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
+#include <com/sun/star/awt/XTopWindow.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_
+#include <com/sun/star/awt/KeyModifier.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_
+#include <com/sun/star/uno/Sequence.hxx>
+#endif
+
+#ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
+#include <com/sun/star/beans/PropertyValue.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+//===============================================
+// namespace
+
+namespace css = ::com::sun::star;
+
+namespace svt
+{
+
+//===============================================
+// definitions
+
+//-----------------------------------------------
+class SVT_DLLPRIVATE AsyncAccelExec
+{
+ public:
+
+ //---------------------------------------
+ /** creates a new instance of this class, which can be used
+ one times only!
+
+ This instance can be forced to execute it's internal set request
+ asynchronous. After that it deletes itself !
+ */
+ static AsyncAccelExec* createOnShotInstance(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
+ const css::util::URL& aURL );
+
+ void execAsync();
+
+ private:
+
+ //---------------------------------------
+ /** @short allow creation of instances of this class
+ by using our factory only!
+ */
+ SVT_DLLPRIVATE AsyncAccelExec(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
+ const css::util::URL& aURL );
+
+ DECL_DLLPRIVATE_LINK(impl_ts_asyncCallback, void*);
+
+ private:
+
+ ::vcl::EventPoster m_aAsyncCallback;
+ css::uno::Reference< css::frame::XDispatch > m_xDispatch;
+ css::util::URL m_aURL;
+};
+
+//-----------------------------------------------
+AcceleratorExecute::AcceleratorExecute()
+ : TMutexInit ( )
+ , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
+{
+}
+
+//-----------------------------------------------
+AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute&)
+ : TMutexInit ( )
+ , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
+{
+ // copy construction sint supported in real ...
+ // but we need this ctor to init our async callback ...
+}
+
+//-----------------------------------------------
+AcceleratorExecute::~AcceleratorExecute()
+{
+ // does nothing real
+}
+
+//-----------------------------------------------
+AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper()
+{
+ AcceleratorExecute* pNew = new AcceleratorExecute();
+ return pNew;
+}
+
+//-----------------------------------------------
+void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR,
+ const css::uno::Reference< css::frame::XFrame >& xEnv )
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // take over the uno service manager
+ m_xSMGR = xSMGR;
+
+ // specify our internal dispatch provider
+ // frame or desktop?! => document or global config.
+ sal_Bool bDesktopIsUsed = sal_False;
+ m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY);
+ if (!m_xDispatcher.is())
+ {
+ aLock.clear();
+ // <- SAFE ------------------------------
+
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatcher(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE -> ------------------------------
+ aLock.reset();
+
+ m_xDispatcher = xDispatcher;
+ bDesktopIsUsed = sal_True;
+ }
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ // open all needed configuration objects
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ;
+
+ // global cfg
+ xGlobalCfg = AcceleratorExecute::st_openGlobalConfig(xSMGR);
+ if (!bDesktopIsUsed)
+ {
+ // module cfg
+ xModuleCfg = AcceleratorExecute::st_openModuleConfig(xSMGR, xEnv);
+
+ // doc cfg
+ css::uno::Reference< css::frame::XController > xController;
+ css::uno::Reference< css::frame::XModel > xModel;
+ xController = xEnv->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+ if (xModel.is())
+ xDocCfg = AcceleratorExecute::st_openDocConfig(xModel);
+ }
+
+ // SAFE -> ------------------------------
+ aLock.reset();
+
+ m_xGlobalCfg = xGlobalCfg;
+ m_xModuleCfg = xModuleCfg;
+ m_xDocCfg = xDocCfg ;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+sal_Bool AcceleratorExecute::execute(const KeyCode& aVCLKey)
+{
+ css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey);
+ return execute(aAWTKey);
+}
+
+//-----------------------------------------------
+sal_Bool AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey)
+{
+ ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey);
+
+ // No Command found? Do nothing! User isnt interested on any error handling .-)
+ if (!sCommand.getLength())
+ return sal_False;
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ // convert command in URL structure
+ css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser();
+ css::util::URL aURL;
+ aURL.Complete = sCommand;
+ xParser->parseStrict(aURL);
+
+ // ask for dispatch object
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0);
+ sal_Bool bRet = xDispatch.is();
+ if ( bRet )
+ {
+ // Note: Such instance can be used one times only and destroy itself afterwards .-)
+ AsyncAccelExec* pExec = AsyncAccelExec::createOnShotInstance(xDispatch, aURL);
+ pExec->execAsync();
+ }
+
+ return bRet;
+}
+
+//-----------------------------------------------
+css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey)
+{
+ css::awt::KeyEvent aAWTKey;
+ aAWTKey.Modifiers = 0;
+ aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode();
+
+ if (aVCLKey.IsShift())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
+ if (aVCLKey.IsMod1())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
+ if (aVCLKey.IsMod2())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
+ if (aVCLKey.IsMod3())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
+ return aAWTKey;
+}
+
+//-----------------------------------------------
+KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
+{
+ sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
+ sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 );
+ sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 );
+ sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 );
+ USHORT nKey = (USHORT)aAWTKey.KeyCode;
+
+ return KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
+}
+//-----------------------------------------------
+::rtl::OUString AcceleratorExecute::findCommand(const css::awt::KeyEvent& aKey)
+{
+ return impl_ts_findCommand(aKey);
+}
+//-----------------------------------------------
+::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey)
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ ::rtl::OUString sCommand;
+
+ try
+ {
+ if (xDocCfg.is())
+ sCommand = xDocCfg->getCommandByKeyEvent(aKey);
+ if (sCommand.getLength())
+ return sCommand;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+
+ try
+ {
+ if (xModuleCfg.is())
+ sCommand = xModuleCfg->getCommandByKeyEvent(aKey);
+ if (sCommand.getLength())
+ return sCommand;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+
+ try
+ {
+ if (xGlobalCfg.is())
+ sCommand = xGlobalCfg->getCommandByKeyEvent(aKey);
+ if (sCommand.getLength())
+ return sCommand;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+
+ // fall back to functional key codes
+ if( aKey.Modifiers == 0 )
+ {
+ switch( aKey.KeyCode )
+ {
+ case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfLine" ) );
+
+ case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfLine" ) );
+
+ case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfPara" ) );
+
+ case com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfPara" ) );
+
+ case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfWord" ) );
+
+ case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfWord" ) );
+
+ case com::sun::star::awt::Key::INSERT_LINEBREAK:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertLinebreak" ) );
+
+ case com::sun::star::awt::Key::INSERT_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPara" ) );
+
+ case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToPrevWord" ) );
+
+ case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToNextWord" ) );
+
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfLine" ) );
+
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfLine" ) );
+
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfPara" ) );
+
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfPara" ) );
+
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfDoc" ) );
+
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfDoc" ) );
+
+ case com::sun::star::awt::Key::SELECT_BACKWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharLeftSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_FORWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharRightSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:WordLeftSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:WordRightSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_WORD:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectWord" ) );
+
+ case com::sun::star::awt::Key::SELECT_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" ) );
+
+ case com::sun::star::awt::Key::SELECT_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectText" ) );
+
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfLineSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfLineSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfParaSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfParaSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfDocumentSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfDocumentSel" ) );
+
+ case com::sun::star::awt::Key::SELECT_ALL:
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectAll" ) );
+ default:
+ break;
+ }
+ }
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.GlobalAcceleratorConfiguration")),
+ css::uno::UNO_QUERY_THROW);
+ return xAccCfg;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XModuleManager > xModuleDetection(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager")),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sModule;
+ try
+ {
+ sModule = xModuleDetection->identify(xFrame);
+ }
+ catch(const css::uno::RuntimeException&rEx)
+ { (void) rEx; throw; }
+ catch(const css::uno::Exception&)
+ { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); }
+
+ css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg;
+ try
+ {
+ css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule);
+ xAccCfg = css::uno::Reference< css::ui::XAcceleratorConfiguration >(xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+ return xAccCfg;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg;
+ css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY);
+ if (xUISupplier.is())
+ {
+ css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager();
+ xAccCfg.set(xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
+ }
+ return xAccCfg;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser()
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ if (m_xURLParser.is())
+ return m_xURLParser;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE -> ----------------------------------
+ aLock.reset();
+ m_xURLParser = xParser;
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ return xParser;
+}
+
+//-----------------------------------------------
+IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, EMPTYARG)
+{
+ // replaced by AsyncAccelExec!
+ return 0;
+}
+
+//-----------------------------------------------
+AsyncAccelExec::AsyncAccelExec(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
+ const css::util::URL& aURL )
+ : m_aAsyncCallback(LINK(this, AsyncAccelExec, impl_ts_asyncCallback))
+ , m_xDispatch (xDispatch )
+ , m_aURL (aURL )
+{
+}
+
+//-----------------------------------------------
+AsyncAccelExec* AsyncAccelExec::createOnShotInstance(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
+ const css::util::URL& aURL )
+{
+ AsyncAccelExec* pExec = new AsyncAccelExec(xDispatch, aURL);
+ return pExec;
+}
+
+//-----------------------------------------------
+void AsyncAccelExec::execAsync()
+{
+ m_aAsyncCallback.Post(0);
+}
+
+//-----------------------------------------------
+IMPL_LINK(AsyncAccelExec, impl_ts_asyncCallback, void*,)
+{
+ if (! m_xDispatch.is())
+ return 0;
+
+ try
+ {
+ m_xDispatch->dispatch(m_aURL, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ catch(const css::lang::DisposedException&)
+ {}
+ catch(const css::uno::RuntimeException& )
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+
+ delete this;
+
+ return 0;
+}
+
+} // namespace svt
diff --git a/svtools/source/misc/chartprettypainter.cxx b/svtools/source/misc/chartprettypainter.cxx
new file mode 100644
index 000000000000..bc2d02384816
--- /dev/null
+++ b/svtools/source/misc/chartprettypainter.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_svtools.hxx"
+
+#include <svtools/chartprettypainter.hxx>
+
+#include <tools/globname.hxx>
+#include <sot/clsids.hxx>
+// header for function rtl_createUuid
+#include <rtl/uuid.h>
+#include <vcl/pdfextoutdevdata.hxx>
+
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <svtools/embedhlp.hxx>
+
+using namespace ::com::sun::star;
+
+ChartPrettyPainter::ChartPrettyPainter()
+{
+}
+
+ChartPrettyPainter::~ChartPrettyPainter()
+{
+}
+
+bool ChartPrettyPainter::DoPaint(OutputDevice* /*pOutDev*/, const Rectangle& /*rLogicObjectRect*/) const
+{
+ return false;
+}
+
+//static
+const uno::Sequence<sal_Int8>& ChartPrettyPainter::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;
+}
+
+bool ChartPrettyPainter::IsChart( const svt::EmbeddedObjectRef& xObjRef )
+{
+ if ( !xObjRef.is() )
+ return false;
+
+ SvGlobalName aObjClsId( xObjRef->getClassID() );
+ if(
+ SvGlobalName(SO3_SCH_CLASSID_30) == aObjClsId
+ || SvGlobalName(SO3_SCH_CLASSID_40) == aObjClsId
+ || SvGlobalName(SO3_SCH_CLASSID_50) == aObjClsId
+ || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool ChartPrettyPainter::ShouldPrettyPaintChartOnThisDevice( OutputDevice* pOutDev )
+{
+ if( !pOutDev )
+ return false;
+ //at least the print preview in calc has a paint loop due to too much invalidate calls deep in sdr
+ //to avoid the paint loop we use the metafile replacement in this case instead of direct rendering
+ if( OUTDEV_WINDOW == pOutDev->GetOutDevType() )
+ return false;
+ if( OUTDEV_PRINTER == pOutDev->GetOutDevType() )
+ return true;
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pOutDev->GetExtOutDevData() );
+ if( pPDFData )
+ return true;
+ return false;
+}
+
+bool ChartPrettyPainter::DoPrettyPaintChart( uno::Reference< frame::XModel > xChartModel, OutputDevice* pOutDev, const Rectangle& rLogicObjectRect )
+{
+ //charts must be painted resolution dependent!! #i82893#, #i75867#
+ if( !xChartModel.is() || !ShouldPrettyPaintChartOnThisDevice( pOutDev ) )
+ return false;
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFact( xChartModel, uno::UNO_QUERY );
+ OSL_ENSURE( xFact.is(), "Chart cannot be painted pretty!\n" );
+ if( xFact.is() )
+ {
+ uno::Reference< lang::XUnoTunnel > xChartRenderer( xFact->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.ChartRenderer" ) ) ), uno::UNO_QUERY );
+ OSL_ENSURE( xChartRenderer.is(), "Chart cannot be painted pretty!\n" );
+ if( xChartRenderer.is() )
+ {
+ ChartPrettyPainter* pPrettyPainter = reinterpret_cast<ChartPrettyPainter*>(
+ xChartRenderer->getSomething( ChartPrettyPainter::getUnoTunnelId() ));
+ if( pPrettyPainter )
+ return pPrettyPainter->DoPaint(pOutDev, rLogicObjectRect);
+ }
+ }
+ }
+ catch( uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "Chart cannot be painted pretty!" );
+ }
+ return false;
+}
+
diff --git a/svtools/source/misc/cliplistener.cxx b/svtools/source/misc/cliplistener.cxx
new file mode 100644
index 000000000000..8fb61a5a1cb9
--- /dev/null
+++ b/svtools/source/misc/cliplistener.cxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
+
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vos/mutex.hxx>
+
+#include "cliplistener.hxx"
+#include <svtools/transfer.hxx>
+
+using namespace ::com::sun::star;
+
+// -----------------------------------------------------------------------------
+
+TransferableClipboardListener::TransferableClipboardListener( const Link& rCallback ) :
+ aLink( rCallback )
+{
+}
+
+TransferableClipboardListener::~TransferableClipboardListener()
+{
+}
+
+void SAL_CALL TransferableClipboardListener::disposing( const lang::EventObject& )
+ throw(uno::RuntimeException)
+{
+}
+
+void SAL_CALL TransferableClipboardListener::changedContents(
+ const datatransfer::clipboard::ClipboardEvent& rEventObject )
+ throw(uno::RuntimeException)
+{
+ if ( aLink.IsSet() )
+ {
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ TransferableDataHelper aDataHelper( rEventObject.Contents );
+ aLink.Call( &aDataHelper );
+ }
+}
+
+void TransferableClipboardListener::AddRemoveListener( Window* pWin, BOOL bAdd )
+{
+ try
+ {
+ if ( pWin )
+ {
+ uno::Reference<datatransfer::clipboard::XClipboard> xClipboard = pWin->GetClipboard();
+ uno::Reference<datatransfer::clipboard::XClipboardNotifier> xClpbrdNtfr( xClipboard, uno::UNO_QUERY );
+ if( xClpbrdNtfr.is() )
+ {
+ uno::Reference<datatransfer::clipboard::XClipboardListener> xClipEvtLstnr( this );
+ if( bAdd )
+ xClpbrdNtfr->addClipboardListener( xClipEvtLstnr );
+ else
+ xClpbrdNtfr->removeClipboardListener( xClipEvtLstnr );
+ }
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+void TransferableClipboardListener::ClearCallbackLink()
+{
+ aLink = Link();
+}
+
diff --git a/svtools/source/misc/dialogclosedlistener.cxx b/svtools/source/misc/dialogclosedlistener.cxx
new file mode 100644
index 000000000000..a08c8a3b6dd5
--- /dev/null
+++ b/svtools/source/misc/dialogclosedlistener.cxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+#include "dialogclosedlistener.hxx"
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ui::dialogs;
+
+ //=====================================================================
+ //= DialogClosedListener
+ //=====================================================================
+ //---------------------------------------------------------------------
+ DialogClosedListener::DialogClosedListener()
+ {
+ }
+
+ DialogClosedListener::DialogClosedListener( const Link& rLink ) :
+
+ m_aDialogClosedLink( rLink )
+
+ {
+ }
+
+ // XDialogClosedListener methods
+ void SAL_CALL DialogClosedListener::dialogClosed( const DialogClosedEvent& aEvent ) throw (RuntimeException)
+ {
+ if ( m_aDialogClosedLink.IsSet() )
+ {
+ ::com::sun::star::ui::dialogs::DialogClosedEvent aEvt( aEvent );
+ m_aDialogClosedLink.Call( &aEvt );
+ }
+ }
+
+ // XEventListener methods
+ void SAL_CALL DialogClosedListener::disposing( const EventObject& ) throw(RuntimeException)
+ {
+ m_aDialogClosedLink = Link();
+ }
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
+
+
diff --git a/svtools/source/misc/dialogcontrolling.cxx b/svtools/source/misc/dialogcontrolling.cxx
new file mode 100644
index 000000000000..7565dad731f7
--- /dev/null
+++ b/svtools/source/misc/dialogcontrolling.cxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "dialogcontrolling.hxx"
+#include <vcl/window.hxx>
+
+#include <algorithm>
+#include <functional>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //=====================================================================
+ //= IWindowOperator
+ //=====================================================================
+ //---------------------------------------------------------------------
+ IWindowOperator::~IWindowOperator()
+ {
+ }
+
+ //=====================================================================
+ //= IWindowEventFilter
+ //=====================================================================
+ //---------------------------------------------------------------------
+ IWindowEventFilter::~IWindowEventFilter()
+ {
+ }
+
+ //=====================================================================
+ //= DialogController_Data
+ //=====================================================================
+ struct DialogController_Data
+ {
+ Window& rInstigator;
+ ::std::vector< Window* > aConcernedWindows;
+ PWindowEventFilter pEventFilter;
+ PWindowOperator pOperator;
+
+ DialogController_Data( Window& _rInstigator, const PWindowEventFilter _pEventFilter, const PWindowOperator _pOperator )
+ :rInstigator( _rInstigator )
+ ,pEventFilter( _pEventFilter )
+ ,pOperator( _pOperator )
+ {
+ }
+ };
+
+ //=====================================================================
+ //= DialogController
+ //=====================================================================
+ //---------------------------------------------------------------------
+ DialogController::DialogController( Window& _rInstigator, const PWindowEventFilter& _pEventFilter,
+ const PWindowOperator& _pOperator )
+ :m_pImpl( new DialogController_Data( _rInstigator, _pEventFilter, _pOperator ) )
+ {
+ DBG_ASSERT( m_pImpl->pEventFilter.get() && m_pImpl->pOperator.get(),
+ "DialogController::DialogController: invalid filter and/or operator!" );
+
+ m_pImpl->rInstigator.AddEventListener( LINK( this, DialogController, OnWindowEvent ) );
+ }
+
+ //---------------------------------------------------------------------
+ DialogController::~DialogController()
+ {
+ reset();
+ }
+
+ //---------------------------------------------------------------------
+ void DialogController::reset()
+ {
+ m_pImpl->rInstigator.RemoveEventListener( LINK( this, DialogController, OnWindowEvent ) );
+ m_pImpl->aConcernedWindows.clear();
+ m_pImpl->pEventFilter.reset();
+ m_pImpl->pOperator.reset();
+ }
+
+ //---------------------------------------------------------------------
+ void DialogController::addDependentWindow( Window& _rWindow )
+ {
+ m_pImpl->aConcernedWindows.push_back( &_rWindow );
+
+ VclWindowEvent aEvent( &_rWindow, 0, NULL );
+ impl_update( aEvent, _rWindow );
+ }
+
+ //---------------------------------------------------------------------
+ IMPL_LINK( DialogController, OnWindowEvent, const VclWindowEvent*, _pEvent )
+ {
+ if ( m_pImpl->pEventFilter->payAttentionTo( *_pEvent ) )
+ impl_updateAll( *_pEvent );
+ return 0L;
+ }
+
+ //---------------------------------------------------------------------
+ void DialogController::impl_updateAll( const VclWindowEvent& _rTriggerEvent )
+ {
+ for ( ::std::vector< Window* >::iterator loop = m_pImpl->aConcernedWindows.begin();
+ loop != m_pImpl->aConcernedWindows.end();
+ ++loop
+ )
+ impl_update( _rTriggerEvent, *(*loop) );
+ }
+
+ //---------------------------------------------------------------------
+ void DialogController::impl_update( const VclWindowEvent& _rTriggerEvent, Window& _rWindow )
+ {
+ m_pImpl->pOperator->operateOn( _rTriggerEvent, _rWindow );
+ }
+
+ //=====================================================================
+ //= ControlDependencyManager_Data
+ //=====================================================================
+ struct ControlDependencyManager_Data
+ {
+ ::std::vector< PDialogController > aControllers;
+ };
+
+ //=====================================================================
+ //= ControlDependencyManager
+ //=====================================================================
+ //---------------------------------------------------------------------
+ ControlDependencyManager::ControlDependencyManager()
+ :m_pImpl( new ControlDependencyManager_Data )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ ControlDependencyManager::~ControlDependencyManager()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ namespace
+ {
+ struct ResetDialogController : public ::std::unary_function< const PDialogController&, void >
+ {
+ void operator()( const PDialogController& _pController )
+ {
+ _pController->reset();
+ }
+ };
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::clear()
+ {
+ ::std::for_each( m_pImpl->aControllers.begin(), m_pImpl->aControllers.end(), ResetDialogController() );
+ m_pImpl->aControllers.clear();
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::addController( const PDialogController& _pController )
+ {
+ OSL_ENSURE( _pController.get() != NULL, "ControlDependencyManager::addController: invalid controller, this will crash, sooner or later!" );
+ m_pImpl->aControllers.push_back( _pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rRadio ) );
+ pController->addDependentWindow( _rDependentWindow );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rRadio ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rRadio ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rRadio ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ pController->addDependentWindow( _rDependentWindow4 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rRadio ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ pController->addDependentWindow( _rDependentWindow4 );
+ pController->addDependentWindow( _rDependentWindow5 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5, Window& _rDependentWindow6 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rRadio ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ pController->addDependentWindow( _rDependentWindow4 );
+ pController->addDependentWindow( _rDependentWindow5 );
+ pController->addDependentWindow( _rDependentWindow6 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rBox ) );
+ pController->addDependentWindow( _rDependentWindow );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rBox ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rBox ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rBox ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ pController->addDependentWindow( _rDependentWindow4 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rBox ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ pController->addDependentWindow( _rDependentWindow4 );
+ pController->addDependentWindow( _rDependentWindow5 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+ //---------------------------------------------------------------------
+ void ControlDependencyManager::enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5, Window& _rDependentWindow6 )
+ {
+ PDialogController pController( new RadioDependentEnabler( _rBox ) );
+ pController->addDependentWindow( _rDependentWindow1 );
+ pController->addDependentWindow( _rDependentWindow2 );
+ pController->addDependentWindow( _rDependentWindow3 );
+ pController->addDependentWindow( _rDependentWindow4 );
+ pController->addDependentWindow( _rDependentWindow5 );
+ pController->addDependentWindow( _rDependentWindow6 );
+ m_pImpl->aControllers.push_back( pController );
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
diff --git a/svtools/source/misc/ehdl.cxx b/svtools/source/misc/ehdl.cxx
new file mode 100644
index 000000000000..bf9e87d33a74
--- /dev/null
+++ b/svtools/source/misc/ehdl.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <vos/mutex.hxx>
+#include <tools/debug.hxx>
+#include <tools/rcid.h>
+#include <vcl/wintypes.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#if defined(OS2)
+#include <vcl/sound.hxx>
+#endif
+
+#ifndef GCC
+#endif
+
+#include <svtools/ehdl.hxx>
+#include <svtools/svtdata.hxx>
+#include <svtools/svtools.hrc>
+#include "sfxecode.hxx"
+
+//=========================================================================
+
+static USHORT aWndFunc(
+ Window *pWin, // Parent des Dialoges
+ USHORT nFlags,
+ const String &rErr, // Fehlertext
+ const String &rAction) // Actiontext
+
+/* [Beschreibung]
+
+ Bringt eine Fehlerbox auf den Schirm. Je nach nFlags werden
+ Error/ Info usw. Boxen mit den gewuenschten Buttons angezeigt
+
+ Rueckgabewert ist der gedrueckte Button
+
+ */
+
+
+{
+ NAMESPACE_VOS( OGuard ) aGuard( Application::GetSolarMutex() );
+
+ // aus den Flags die benoetigten WinBits ermitteln
+ WinBits eBits=0;
+ if ( (ERRCODE_BUTTON_CANCEL|ERRCODE_BUTTON_RETRY) == (nFlags & (ERRCODE_BUTTON_CANCEL|ERRCODE_BUTTON_RETRY)) )
+ eBits = WB_RETRY_CANCEL;
+ else if ( ERRCODE_BUTTON_OK_CANCEL == (nFlags & ERRCODE_BUTTON_OK_CANCEL) )
+ eBits = WB_OK_CANCEL;
+ else if ( ERRCODE_BUTTON_OK == (nFlags & ERRCODE_BUTTON_OK) )
+ eBits = WB_OK;
+ else if ( ERRCODE_BUTTON_YES_NO_CANCEL == (nFlags & ERRCODE_BUTTON_YES_NO_CANCEL) )
+ eBits = WB_YES_NO_CANCEL;
+ else if ( ERRCODE_BUTTON_YES_NO == (nFlags & ERRCODE_BUTTON_YES_NO) )
+ eBits = WB_YES_NO;
+
+ switch(nFlags & 0x0f00)
+ {
+ case ERRCODE_BUTTON_DEF_OK:
+ eBits |= WB_DEF_OK;
+ break;
+
+ case ERRCODE_BUTTON_DEF_CANCEL:
+ eBits |= WB_DEF_CANCEL;
+ break;
+
+ case ERRCODE_BUTTON_DEF_YES:
+ eBits |= WB_DEF_YES;
+ break;
+
+ case ERRCODE_BUTTON_DEF_NO:
+ eBits |= WB_DEF_NO;
+ break;
+ }
+
+ String aErr(SvtResId(STR_ERR_HDLMESS));
+ String aAction(rAction);
+ if ( aAction.Len() )
+ aAction += String::CreateFromAscii( ":\n" );
+ aErr.SearchAndReplace(String::CreateFromAscii( "$(ACTION)" ), aAction);
+ aErr.SearchAndReplace(String::CreateFromAscii( "$(ERROR)" ), rErr);
+
+ MessBox* pBox;
+ switch ( nFlags & 0xf000 )
+ {
+ case ERRCODE_MSG_ERROR:
+ pBox = new ErrorBox(pWin, eBits, aErr);
+ break;
+
+ case ERRCODE_MSG_WARNING:
+ pBox = new WarningBox(pWin, eBits, aErr);
+ break;
+
+ case ERRCODE_MSG_INFO:
+ pBox = new InfoBox(pWin, aErr);
+ break;
+
+ case ERRCODE_MSG_QUERY:
+ pBox = new QueryBox(pWin, eBits, aErr);
+ break;
+
+ default:
+ {
+ DBG_ERRORFILE( "no MessBox type");
+ pBox = NULL;
+ return ERRCODE_BUTTON_OK;
+ }
+ }
+
+ USHORT nRet = RET_CANCEL;
+ switch ( pBox->Execute() )
+ {
+ case RET_OK:
+ nRet = ERRCODE_BUTTON_OK;
+ break;
+ case RET_CANCEL:
+ nRet = ERRCODE_BUTTON_CANCEL;
+ break;
+ case RET_RETRY:
+ nRet = ERRCODE_BUTTON_RETRY;
+ break;
+ case RET_YES:
+ nRet = ERRCODE_BUTTON_YES;
+ break;
+ case RET_NO:
+ nRet = ERRCODE_BUTTON_NO;
+ break;
+ default:
+ DBG_ERRORFILE( "Unknown MessBox return value" );
+ break;
+ }
+ delete pBox;
+ return nRet;
+}
+
+//-------------------------------------------------------------------------
+
+SfxErrorHandler::SfxErrorHandler(USHORT nIdP, ULONG lStartP, ULONG lEndP, ResMgr *pMgrP) :
+
+ lStart(lStartP), lEnd(lEndP), nId(nIdP), pMgr(pMgrP), pFreeMgr( NULL )
+
+{
+ RegisterDisplay(&aWndFunc);
+ if( ! pMgr )
+ {
+ com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+ pFreeMgr = pMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+SfxErrorHandler::~SfxErrorHandler()
+{
+ if( pFreeMgr )
+ delete pFreeMgr;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxErrorHandler::CreateString(
+ const ErrorInfo *pErr, String &rStr, USHORT& nFlags) const
+
+/* [Beschreibung]
+
+ Der Fehlerstring fuer die ErrorInfo pErr wird zusammengesetzt.
+
+ */
+
+{
+ ULONG nErrCode = pErr->GetErrorCode() & ERRCODE_ERROR_MASK;
+ if( nErrCode>=lEnd || nErrCode<=lStart )
+ return FALSE;
+ MessageInfo *pMsgInfo=PTR_CAST(MessageInfo,pErr);
+ if(pMsgInfo)
+ {
+ if(GetMessageString(nErrCode, rStr, nFlags))
+ {
+ for (xub_StrLen i = 0; i < rStr.Len();)
+ {
+ i = rStr.SearchAndReplace(String::CreateFromAscii( "$(ARG1)" ),
+ pMsgInfo->GetMessageArg(), i);
+ if (i == STRING_NOTFOUND)
+ break;
+ i = i + pMsgInfo->GetMessageArg().Len();
+ }
+ return TRUE;
+ }
+ }
+ else if(GetErrorString(nErrCode, rStr, nFlags))
+ {
+ StringErrorInfo *pStringInfo=PTR_CAST(StringErrorInfo,pErr);
+ if(pStringInfo)
+ for (xub_StrLen i = 0; i < rStr.Len();)
+ {
+ i = rStr.SearchAndReplace(String::CreateFromAscii( "$(ARG1)" ),
+ pStringInfo->GetErrorString(), i);
+ if (i == STRING_NOTFOUND)
+ break;
+ i = i + pStringInfo->GetErrorString().Len();
+ }
+ else
+ {
+ TwoStringErrorInfo * pTwoStringInfo = PTR_CAST(TwoStringErrorInfo,
+ pErr);
+ if (pTwoStringInfo)
+ for (USHORT i = 0; i < rStr.Len();)
+ {
+ USHORT nArg1Pos = rStr.Search(String::CreateFromAscii( "$(ARG1)" ), i);
+ USHORT nArg2Pos = rStr.Search(String::CreateFromAscii( "$(ARG2)" ), i);
+ if (nArg1Pos < nArg2Pos)
+ {
+ rStr.Replace(nArg1Pos, 7, pTwoStringInfo->GetArg1());
+ i = nArg1Pos + pTwoStringInfo->GetArg1().Len();
+ }
+ else if (nArg2Pos < nArg1Pos)
+ {
+ rStr.Replace(nArg2Pos, 7, pTwoStringInfo->GetArg2());
+ i = nArg2Pos + pTwoStringInfo->GetArg2().Len();
+ }
+ else break;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//-------------------------------------------------------------------------
+
+class ResString: public String
+
+/* [Beschreibung]
+
+ Hilfsklasse zum Auslesen eines Strings und optionaler ExtraData aus
+ einer String Resource.
+
+ */
+
+{
+ USHORT nFlags;
+ public:
+ USHORT GetFlags() const {return nFlags;}
+ const String & GetString() const {return *this;}
+ ResString( ResId &rId);
+};
+
+//-------------------------------------------------------------------------
+
+ResString::ResString(ResId & rId):
+ String(rId.SetAutoRelease(FALSE)),
+ nFlags(0)
+{
+ ResMgr * pResMgr = rId.GetResMgr();
+ // String ctor temporarily sets global ResManager
+ if (pResMgr->GetRemainSize())
+ nFlags = USHORT(pResMgr->ReadShort());
+ rId.SetAutoRelease(TRUE);
+ pResMgr->PopContext();
+}
+
+//-------------------------------------------------------------------------
+
+struct ErrorResource_Impl : private Resource
+
+/* [Beschreibung]
+
+ Hilfsklasse zum Zugriff auf String SubResourcen einer Resource
+ */
+
+{
+
+ ResId aResId;
+
+ ErrorResource_Impl(ResId& rErrIdP, USHORT nId)
+ : Resource(rErrIdP),aResId(nId,*rErrIdP.GetResMgr()){}
+
+ ~ErrorResource_Impl() { FreeResource(); }
+
+ operator ResString(){ return ResString( aResId ); }
+ operator BOOL(){return IsAvailableRes(aResId.SetRT(RSC_STRING));}
+
+};
+
+
+BOOL SfxErrorHandler::GetClassString(ULONG lClassId, String &rStr) const
+
+/* [Beschreibung]
+
+ Erzeugt den String fuer die Klasse des Fehlers. Wird immer aus der
+ Resource des Sfx gelesen
+
+ */
+
+{
+ BOOL bRet = FALSE;
+ com::sun::star::lang::Locale aLocale( Application::GetSettings().GetUILocale() );
+ ResMgr* pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
+ if( pResMgr )
+ {
+ ResId aId(RID_ERRHDL, *pResMgr );
+ ErrorResource_Impl aEr(aId, (USHORT)lClassId);
+ if(aEr)
+ {
+ rStr=((ResString)aEr).GetString();
+ bRet = TRUE;
+ }
+ }
+ delete pResMgr;
+ return bRet;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxErrorHandler::GetMessageString(
+ ULONG lErrId, String &rStr, USHORT &nFlags) const
+
+/* [Beschreibung]
+
+ Erzeugt den String fuer die Ausgabe in einer MessageBox
+
+ */
+
+{
+ BOOL bRet = FALSE;
+ ResId *pResId= new ResId(nId, *pMgr);
+
+ ErrorResource_Impl aEr(*pResId, (USHORT)lErrId);
+ if(aEr)
+ {
+ ResString aErrorString(aEr);
+ USHORT nResFlags = aErrorString.GetFlags();
+ if( nResFlags )
+ nFlags=aErrorString.GetFlags();
+ rStr = aErrorString.GetString();
+ bRet = TRUE;
+ }
+
+ delete pResId;
+ return bRet;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxErrorHandler::GetErrorString(
+ ULONG lErrId, String &rStr, USHORT &nFlags) const
+
+/* [Beschreibung]
+ Erzeugt den Fehlerstring fuer den eigentlichen Fehler ohne
+ dessen Klasse
+
+ */
+
+{
+ NAMESPACE_VOS( OGuard ) aGuard( Application::GetSolarMutex() );
+
+ BOOL bRet = FALSE;
+ rStr=String(SvtResId(RID_ERRHDL_CLASS));
+ ResId aResId(nId, *pMgr);
+
+ {
+ ErrorResource_Impl aEr(aResId, (USHORT)lErrId);
+ if(aEr)
+ {
+ ResString aErrorString(aEr);
+
+ USHORT nResFlags = aErrorString.GetFlags();
+ if ( nResFlags )
+ nFlags = nResFlags;
+ rStr.SearchAndReplace(
+ String::CreateFromAscii("$(ERROR)"), aErrorString.GetString());
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+ }
+
+ if( bRet )
+ {
+ String aErrStr;
+ GetClassString(lErrId & ERRCODE_CLASS_MASK,
+ aErrStr);
+ if(aErrStr.Len())
+ aErrStr+=String::CreateFromAscii( ".\n" );
+ rStr.SearchAndReplace(String::CreateFromAscii( "$(CLASS)" ),aErrStr);
+ }
+
+ return bRet;
+}
+
+//-------------------------------------------------------------------------
+
+SfxErrorContext::SfxErrorContext(
+ USHORT nCtxIdP, Window *pWindow, USHORT nResIdP, ResMgr *pMgrP)
+: ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP)
+{
+ if( nResId==USHRT_MAX )
+ nResId=RID_ERRCTX;
+}
+
+//-------------------------------------------------------------------------
+
+SfxErrorContext::SfxErrorContext(
+ USHORT nCtxIdP, const String &aArg1P, Window *pWindow,
+ USHORT nResIdP, ResMgr *pMgrP)
+: ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP),
+ aArg1(aArg1P)
+{
+ if( nResId==USHRT_MAX )
+ nResId=RID_ERRCTX;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxErrorContext::GetString(ULONG nErrId, String &rStr)
+
+/* [Beschreibung]
+
+ Baut die Beschreibung eines ErrorContextes auf
+ */
+
+{
+ bool bRet = false;
+ ResMgr* pFreeMgr = NULL;
+ if( ! pMgr )
+ {
+ com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+ pFreeMgr = pMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
+ }
+ if( pMgr )
+ {
+ NAMESPACE_VOS( OGuard ) aGuard( Application::GetSolarMutex() );
+
+ ResId aResId( nResId, *pMgr );
+
+ ErrorResource_Impl aTestEr( aResId, nCtxId );
+ if ( aTestEr )
+ {
+ rStr = ( (ResString)aTestEr ).GetString();
+ rStr.SearchAndReplace( String::CreateFromAscii( "$(ARG1)" ), aArg1 );
+ bRet = true;
+ }
+ else
+ {
+ DBG_ERRORFILE( "ErrorContext cannot find the resource" );
+ bRet = false;
+ }
+
+ if ( bRet )
+ {
+ USHORT nId = ( nErrId & ERRCODE_WARNING_MASK ) ? ERRCTX_WARNING : ERRCTX_ERROR;
+ ResId aSfxResId( RID_ERRCTX, *pMgr );
+ ErrorResource_Impl aEr( aSfxResId, nId );
+ rStr.SearchAndReplace( String::CreateFromAscii( "$(ERR)" ), ( (ResString)aEr ).GetString() );
+ }
+ }
+
+ if( pFreeMgr )
+ {
+ delete pFreeMgr;
+ pMgr = NULL;
+ }
+ return bRet;
+}
diff --git a/svtools/source/misc/ehdl.src b/svtools/source/misc/ehdl.src
new file mode 100644
index 000000000000..436e06b7f3c5
--- /dev/null
+++ b/svtools/source/misc/ehdl.src
@@ -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.
+ *
+ ************************************************************************/
+
+#define __RSC
+#include <svtools/svtools.hrc>
+#include "sfxecode.hxx"
+ // pragma ----------------------------------------------------------------
+
+String STR_ERR_HDLMESS
+{
+ Text = "$(ACTION)$(ERROR)" ;
+};
+String RID_ERRHDL_CLASS
+{
+ Text = "$(CLASS)$(ERROR)" ;
+};
diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
new file mode 100644
index 000000000000..3aa0016c225e
--- /dev/null
+++ b/svtools/source/misc/embedhlp.cxx
@@ -0,0 +1,955 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <svtools/embedhlp.hxx>
+#include <svtools/filter.hxx>
+#include <svtools/svtools.hrc>
+#include <svtools/svtdata.hxx>
+
+#include <comphelper/embeddedobjectcontainer.hxx>
+#include <comphelper/seqstream.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/streamwrap.hxx>
+
+#include <tools/globname.hxx>
+#include <sot/clsids.hxx>
+#include <com/sun/star/util/XModifyListener.hpp>
+#ifndef _COM_SUN_STAR_UTIL_XMODIFYiBLE_HPP_
+#include <com/sun/star/util/XModifiable.hpp>
+#endif
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/XStateChangeListener.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
+#include <cppuhelper/implbase4.hxx>
+#include "vcl/svapp.hxx"
+#include <rtl/logfile.hxx>
+#include <vos/mutex.hxx>
+
+using namespace com::sun::star;
+
+namespace svt
+{
+
+class EmbedEventListener_Impl : public ::cppu::WeakImplHelper4 < embed::XStateChangeListener,
+ document::XEventListener,
+ util::XModifyListener,
+ util::XCloseListener >
+{
+public:
+ EmbeddedObjectRef* pObject;
+ sal_Int32 nState;
+
+ EmbedEventListener_Impl( EmbeddedObjectRef* p ) :
+ pObject(p)
+ , nState(-1)
+ {}
+
+ static EmbedEventListener_Impl* Create( EmbeddedObjectRef* );
+
+ virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
+ throw (embed::WrongStateException, uno::RuntimeException);
+ virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
+ throw (uno::RuntimeException);
+ 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);
+ virtual void SAL_CALL notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException );
+ virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException );
+ virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+EmbedEventListener_Impl* EmbedEventListener_Impl::Create( EmbeddedObjectRef* p )
+{
+ EmbedEventListener_Impl* xRet = new EmbedEventListener_Impl( p );
+ xRet->acquire();
+
+ if ( p->GetObject().is() )
+ {
+ p->GetObject()->addStateChangeListener( xRet );
+
+ uno::Reference < util::XCloseable > xClose( p->GetObject(), uno::UNO_QUERY );
+ DBG_ASSERT( xClose.is(), "Object does not support XCloseable!" );
+ if ( xClose.is() )
+ xClose->addCloseListener( xRet );
+
+ uno::Reference < document::XEventBroadcaster > xBrd( p->GetObject(), uno::UNO_QUERY );
+ if ( xBrd.is() )
+ xBrd->addEventListener( xRet );
+
+ xRet->nState = p->GetObject()->getCurrentState();
+ if ( xRet->nState == embed::EmbedStates::RUNNING )
+ {
+ uno::Reference < util::XModifiable > xMod( p->GetObject()->getComponent(), uno::UNO_QUERY );
+ if ( xMod.is() )
+ // listen for changes in running state (update replacements in case of changes)
+ xMod->addModifyListener( xRet );
+ }
+ }
+
+ return xRet;
+}
+
+void SAL_CALL EmbedEventListener_Impl::changingState( const lang::EventObject&,
+ ::sal_Int32,
+ ::sal_Int32 )
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+}
+
+void SAL_CALL EmbedEventListener_Impl::stateChanged( const lang::EventObject&,
+ ::sal_Int32 nOldState,
+ ::sal_Int32 nNewState )
+ throw ( uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ nState = nNewState;
+ if ( !pObject )
+ return;
+
+ uno::Reference < util::XModifiable > xMod( pObject->GetObject()->getComponent(), uno::UNO_QUERY );
+ if ( nNewState == embed::EmbedStates::RUNNING )
+ {
+ // TODO/LATER: container must be set before!
+ // When is this event created? Who sets the new container when it changed?
+ if( ( pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON ) && nOldState != embed::EmbedStates::LOADED && !pObject->IsChart() )
+ // get new replacement after deactivation
+ pObject->UpdateReplacement();
+
+ if( pObject->IsChart() && nOldState == embed::EmbedStates::UI_ACTIVE )
+ {
+ //create a new metafile replacement when leaving the edit mode
+ //for buggy documents where the old image looks different from the correct one
+ if( xMod.is() && !xMod->isModified() )//in case of modification a new replacement will be requested anyhow
+ pObject->UpdateReplacementOnDemand();
+ }
+
+ if ( xMod.is() && nOldState == embed::EmbedStates::LOADED )
+ // listen for changes (update replacements in case of changes)
+ xMod->addModifyListener( this );
+ }
+ else if ( nNewState == embed::EmbedStates::LOADED )
+ {
+ // in loaded state we can't listen
+ if ( xMod.is() )
+ xMod->removeModifyListener( this );
+ }
+}
+
+void SAL_CALL EmbedEventListener_Impl::modified( const lang::EventObject& ) throw (uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( pObject && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON )
+ {
+ if ( nState == embed::EmbedStates::RUNNING )
+ {
+ // updates only necessary in non-active states
+ if( pObject->IsChart() )
+ pObject->UpdateReplacementOnDemand();
+ else
+ pObject->UpdateReplacement();
+ }
+ else if ( nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::INPLACE_ACTIVE )
+ {
+ // in case the object is inplace or UI active the replacement image should be updated on demand
+ pObject->UpdateReplacementOnDemand();
+ }
+ }
+}
+
+void SAL_CALL EmbedEventListener_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+#if 0
+ if ( pObject && aEvent.EventName.equalsAscii("OnSaveDone") || aEvent.EventName.equalsAscii("OnSaveAsDone") )
+ {
+ // TODO/LATER: container must be set before!
+ // When is this event created? Who sets the new container when it changed?
+ pObject->UpdateReplacement();
+ }
+ else
+#endif
+ if ( pObject && aEvent.EventName.equalsAscii("OnVisAreaChanged") && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON && !pObject->IsChart() )
+ {
+ pObject->UpdateReplacement();
+ }
+}
+
+void SAL_CALL EmbedEventListener_Impl::queryClosing( const lang::EventObject& Source, ::sal_Bool )
+ throw ( util::CloseVetoException, uno::RuntimeException)
+{
+ // An embedded object can be shared between several objects (f.e. for undo purposes)
+ // the object will not be closed before the last "customer" is destroyed
+ // Now the EmbeddedObjectRef helper class works like a "lock" on the object
+ if ( pObject && pObject->IsLocked() && Source.Source == pObject->GetObject() )
+ throw util::CloseVetoException();
+}
+
+void SAL_CALL EmbedEventListener_Impl::notifyClosing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( pObject && Source.Source == pObject->GetObject() )
+ {
+ pObject->Clear();
+ pObject = 0;
+ }
+}
+
+void SAL_CALL EmbedEventListener_Impl::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ if ( pObject && aEvent.Source == pObject->GetObject() )
+ {
+ pObject->Clear();
+ pObject = 0;
+ }
+}
+
+struct EmbeddedObjectRef_Impl
+{
+ EmbedEventListener_Impl* xListener;
+ ::rtl::OUString aPersistName;
+ ::rtl::OUString aMediaType;
+ comphelper::EmbeddedObjectContainer* pContainer;
+ Graphic* pGraphic;
+ Graphic* pHCGraphic;
+ sal_Int64 nViewAspect;
+ BOOL bIsLocked;
+ sal_Bool bNeedUpdate;
+
+ // #i104867#
+ sal_uInt32 mnGraphicVersion;
+ awt::Size aDefaultSizeForChart_In_100TH_MM;//#i103460# charts do not necessaryly have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this member
+};
+
+void EmbeddedObjectRef::Construct_Impl()
+{
+ mpImp = new EmbeddedObjectRef_Impl;
+ mpImp->pContainer = 0;
+ mpImp->pGraphic = 0;
+ mpImp->pHCGraphic = 0;
+ mpImp->nViewAspect = embed::Aspects::MSOLE_CONTENT;
+ mpImp->bIsLocked = FALSE;
+ mpImp->bNeedUpdate = sal_False;
+ mpImp->mnGraphicVersion = 0;
+ mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size(8000,7000);
+}
+
+EmbeddedObjectRef::EmbeddedObjectRef()
+{
+ Construct_Impl();
+}
+
+EmbeddedObjectRef::EmbeddedObjectRef( const NS_UNO::Reference < NS_EMBED::XEmbeddedObject >& xObj, sal_Int64 nAspect )
+{
+ Construct_Impl();
+ mpImp->nViewAspect = nAspect;
+ mxObj = xObj;
+ mpImp->xListener = EmbedEventListener_Impl::Create( this );
+}
+
+EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef& rObj )
+{
+ mpImp = new EmbeddedObjectRef_Impl;
+ mpImp->pContainer = rObj.mpImp->pContainer;
+ mpImp->nViewAspect = rObj.mpImp->nViewAspect;
+ mpImp->bIsLocked = rObj.mpImp->bIsLocked;
+ mxObj = rObj.mxObj;
+ mpImp->xListener = EmbedEventListener_Impl::Create( this );
+ mpImp->aPersistName = rObj.mpImp->aPersistName;
+ mpImp->aMediaType = rObj.mpImp->aMediaType;
+ mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
+ mpImp->aDefaultSizeForChart_In_100TH_MM = rObj.mpImp->aDefaultSizeForChart_In_100TH_MM;
+
+ if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
+ mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
+ else
+ mpImp->pGraphic = 0;
+
+ mpImp->pHCGraphic = 0;
+ mpImp->mnGraphicVersion = 0;
+}
+
+EmbeddedObjectRef::~EmbeddedObjectRef()
+{
+ delete mpImp->pGraphic;
+ if ( mpImp->pHCGraphic )
+ DELETEZ( mpImp->pHCGraphic );
+ Clear();
+}
+/*
+EmbeddedObjectRef& EmbeddedObjectRef::operator = ( const EmbeddedObjectRef& rObj )
+{
+ DBG_ASSERT( !mxObj.is(), "Never assign an already assigned object!" );
+
+ delete mpImp->pGraphic;
+ if ( mpImp->pHCGraphic ) DELETEZ( mpImp->pHCGraphic );
+ Clear();
+
+ mpImp->nViewAspect = rObj.mpImp->nViewAspect;
+ mpImp->bIsLocked = rObj.mpImp->bIsLocked;
+ mxObj = rObj.mxObj;
+ mpImp->xListener = EmbedEventListener_Impl::Create( this );
+ mpImp->pContainer = rObj.mpImp->pContainer;
+ mpImp->aPersistName = rObj.mpImp->aPersistName;
+ mpImp->aMediaType = rObj.mpImp->aMediaType;
+ mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
+
+ if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
+ mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
+ else
+ mpImp->pGraphic = 0;
+ return *this;
+}
+*/
+void EmbeddedObjectRef::Assign( const NS_UNO::Reference < NS_EMBED::XEmbeddedObject >& xObj, sal_Int64 nAspect )
+{
+ DBG_ASSERT( !mxObj.is(), "Never assign an already assigned object!" );
+
+ Clear();
+ mpImp->nViewAspect = nAspect;
+ mxObj = xObj;
+ mpImp->xListener = EmbedEventListener_Impl::Create( this );
+
+ //#i103460#
+ {
+ ::com::sun::star::uno::Reference < ::com::sun::star::chart2::XDefaultSizeTransmitter > xSizeTransmitter( xObj, uno::UNO_QUERY );
+ DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
+ if( xSizeTransmitter.is() )
+ xSizeTransmitter->setDefaultSize( mpImp->aDefaultSizeForChart_In_100TH_MM );
+ }
+}
+
+void EmbeddedObjectRef::Clear()
+{
+ if ( mxObj.is() && mpImp->xListener )
+ {
+ mxObj->removeStateChangeListener( mpImp->xListener );
+
+ uno::Reference < util::XCloseable > xClose( mxObj, uno::UNO_QUERY );
+ if ( xClose.is() )
+ xClose->removeCloseListener( mpImp->xListener );
+
+ uno::Reference < document::XEventBroadcaster > xBrd( mxObj, uno::UNO_QUERY );
+ if ( xBrd.is() )
+ xBrd->removeEventListener( mpImp->xListener );
+
+ if ( mpImp->bIsLocked )
+ {
+ if ( xClose.is() )
+ {
+ try
+ {
+ mxObj->changeState( embed::EmbedStates::LOADED );
+ xClose->close( sal_True );
+ }
+ catch ( util::CloseVetoException& )
+ {
+ // there's still someone who needs the object!
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Error on switching of the object to loaded state and closing!\n" );
+ }
+ }
+ }
+
+ if ( mpImp->xListener )
+ {
+ mpImp->xListener->pObject = 0;
+ mpImp->xListener->release();
+ mpImp->xListener = 0;
+ }
+
+ mxObj = 0;
+ mpImp->bNeedUpdate = sal_False;
+ }
+
+ mpImp->pContainer = 0;
+ mpImp->bIsLocked = FALSE;
+ mpImp->bNeedUpdate = sal_False;
+}
+
+void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer* pContainer, const ::rtl::OUString& rPersistName )
+{
+ mpImp->pContainer = pContainer;
+ mpImp->aPersistName = rPersistName;
+
+ if ( mpImp->pGraphic && !mpImp->bNeedUpdate && pContainer )
+ SetGraphicToContainer( *mpImp->pGraphic, *pContainer, mpImp->aPersistName, ::rtl::OUString() );
+}
+
+comphelper::EmbeddedObjectContainer* EmbeddedObjectRef::GetContainer() const
+{
+ return mpImp->pContainer;
+}
+
+::rtl::OUString EmbeddedObjectRef::GetPersistName() const
+{
+ return mpImp->aPersistName;
+}
+
+MapUnit EmbeddedObjectRef::GetMapUnit() const
+{
+ if ( mpImp->nViewAspect == embed::Aspects::MSOLE_CONTENT )
+ return VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj->getMapUnit( mpImp->nViewAspect ) );
+ else
+ // TODO/LATER: currently only CONTENT aspect requires communication with the object
+ return MAP_100TH_MM;
+}
+
+sal_Int64 EmbeddedObjectRef::GetViewAspect() const
+{
+ return mpImp->nViewAspect;
+}
+
+void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect )
+{
+ mpImp->nViewAspect = nAspect;
+}
+
+void EmbeddedObjectRef::Lock( BOOL bLock )
+{
+ mpImp->bIsLocked = bLock;
+}
+
+BOOL EmbeddedObjectRef::IsLocked() const
+{
+ return mpImp->bIsLocked;
+}
+
+void EmbeddedObjectRef::GetReplacement( BOOL bUpdate )
+{
+ if ( bUpdate )
+ {
+ DELETEZ( mpImp->pGraphic );
+ mpImp->aMediaType = ::rtl::OUString();
+ mpImp->pGraphic = new Graphic;
+ if ( mpImp->pHCGraphic )
+ DELETEZ( mpImp->pHCGraphic );
+ mpImp->mnGraphicVersion++;
+ }
+ else if ( !mpImp->pGraphic )
+ {
+ mpImp->pGraphic = new Graphic;
+ mpImp->mnGraphicVersion++;
+ }
+ else
+ {
+ DBG_ERROR("No update, but replacement exists already!");
+ return;
+ }
+
+ SvStream* pGraphicStream = GetGraphicStream( bUpdate );
+ if ( pGraphicStream )
+ {
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ if( mpImp->pGraphic )
+ pGF->ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
+ mpImp->mnGraphicVersion++;
+ delete pGraphicStream;
+ }
+}
+
+Graphic* EmbeddedObjectRef::GetGraphic( ::rtl::OUString* pMediaType ) const
+{
+ if ( mpImp->bNeedUpdate )
+ // bNeedUpdate will be set to false while retrieving new replacement
+ const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_True );
+ else if ( !mpImp->pGraphic )
+ const_cast < EmbeddedObjectRef* >(this)->GetReplacement( FALSE );
+
+ if ( mpImp->pGraphic && pMediaType )
+ *pMediaType = mpImp->aMediaType;
+ return mpImp->pGraphic;
+}
+
+Size EmbeddedObjectRef::GetSize( MapMode* pTargetMapMode ) const
+{
+ MapMode aSourceMapMode( MAP_100TH_MM );
+ Size aResult;
+
+ if ( mpImp->nViewAspect == embed::Aspects::MSOLE_ICON )
+ {
+ Graphic* pGraphic = GetGraphic();
+ if ( pGraphic )
+ {
+ aSourceMapMode = pGraphic->GetPrefMapMode();
+ aResult = pGraphic->GetPrefSize();
+ }
+ else
+ aResult = Size( 2500, 2500 );
+ }
+ else
+ {
+ awt::Size aSize;
+
+ if ( mxObj.is() )
+ {
+ try
+ {
+ aSize = mxObj->getVisualAreaSize( mpImp->nViewAspect );
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Something went wrong on getting of the size of the object!" );
+ }
+
+ try
+ {
+ aSourceMapMode = VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj->getMapUnit( mpImp->nViewAspect ) );
+ }
+ catch( uno::Exception )
+ {
+ OSL_ENSURE( sal_False, "Can not get the map mode!" );
+ }
+ }
+
+ if ( !aSize.Height && !aSize.Width )
+ {
+ aSize.Width = 5000;
+ aSize.Height = 5000;
+ }
+
+ aResult = Size( aSize.Width, aSize.Height );
+ }
+
+ if ( pTargetMapMode )
+ aResult = OutputDevice::LogicToLogic( aResult, aSourceMapMode, *pTargetMapMode );
+
+ return aResult;
+}
+
+Graphic* EmbeddedObjectRef::GetHCGraphic() const
+{
+ if ( !mpImp->pHCGraphic )
+ {
+ uno::Reference< io::XInputStream > xInStream;
+ try
+ {
+ // if the object needs size on load, that means that it is not our object
+ // currently the HC mode is supported only for OOo own objects so the following
+ // check is used as an optimization
+ // TODO/LATER: shouldn't there be a special status flag to detect alien implementation?
+ if ( mpImp->nViewAspect == embed::Aspects::MSOLE_CONTENT
+ && mxObj.is() && !( mxObj->getStatus( mpImp->nViewAspect ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD ) )
+ {
+ // TODO/LATER: optimization, it makes no sence to do it for OLE objects
+ if ( mxObj->getCurrentState() == embed::EmbedStates::LOADED )
+ mxObj->changeState( embed::EmbedStates::RUNNING );
+
+ // TODO: return for the aspect of the document
+ embed::VisualRepresentation aVisualRepresentation;
+ uno::Reference< datatransfer::XTransferable > xTransferable( mxObj->getComponent(), uno::UNO_QUERY );
+ if ( !xTransferable.is() )
+ throw uno::RuntimeException();
+
+ datatransfer::DataFlavor aDataFlavor(
+ ::rtl::OUString::createFromAscii(
+ "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ),
+ ::rtl::OUString::createFromAscii( "GDIMetaFile" ),
+ ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
+
+ uno::Sequence < sal_Int8 > aSeq;
+ if ( ( xTransferable->getTransferData( aDataFlavor ) >>= aSeq ) && aSeq.getLength() )
+ xInStream = new ::comphelper::SequenceInputStream( aSeq );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ if ( xInStream.is() )
+ {
+ SvStream* pStream = NULL;
+ pStream = ::utl::UcbStreamHelper::CreateStream( xInStream );
+ if ( pStream )
+ {
+ if ( !pStream->GetError() )
+ {
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ Graphic* pGraphic = new Graphic();
+ if ( pGF->ImportGraphic( *pGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW ) == 0 )
+ mpImp->pHCGraphic = pGraphic;
+ else
+ delete pGraphic;
+ mpImp->mnGraphicVersion++;
+ }
+
+ delete pStream;
+ }
+ }
+ }
+
+ return mpImp->pHCGraphic;
+}
+
+void EmbeddedObjectRef::SetGraphicStream( const uno::Reference< io::XInputStream >& xInGrStream,
+ const ::rtl::OUString& rMediaType )
+{
+ if ( mpImp->pGraphic )
+ delete mpImp->pGraphic;
+ mpImp->pGraphic = new Graphic();
+ mpImp->aMediaType = rMediaType;
+ if ( mpImp->pHCGraphic )
+ DELETEZ( mpImp->pHCGraphic );
+ mpImp->mnGraphicVersion++;
+
+ SvStream* pGraphicStream = ::utl::UcbStreamHelper::CreateStream( xInGrStream );
+
+ if ( pGraphicStream )
+ {
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ pGF->ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
+ mpImp->mnGraphicVersion++;
+
+ if ( mpImp->pContainer )
+ {
+ pGraphicStream->Seek( 0 );
+ uno::Reference< io::XInputStream > xInSeekGrStream = new ::utl::OSeekableInputStreamWrapper( pGraphicStream );
+
+ mpImp->pContainer->InsertGraphicStream( xInSeekGrStream, mpImp->aPersistName, rMediaType );
+ }
+
+ delete pGraphicStream;
+ }
+
+ mpImp->bNeedUpdate = sal_False;
+
+}
+
+void EmbeddedObjectRef::SetGraphic( const Graphic& rGraphic, const ::rtl::OUString& rMediaType )
+{
+ if ( mpImp->pGraphic )
+ delete mpImp->pGraphic;
+ mpImp->pGraphic = new Graphic( rGraphic );
+ mpImp->aMediaType = rMediaType;
+ if ( mpImp->pHCGraphic )
+ DELETEZ( mpImp->pHCGraphic );
+ mpImp->mnGraphicVersion++;
+
+ if ( mpImp->pContainer )
+ SetGraphicToContainer( rGraphic, *mpImp->pContainer, mpImp->aPersistName, rMediaType );
+
+ mpImp->bNeedUpdate = sal_False;
+}
+
+SvStream* EmbeddedObjectRef::GetGraphicStream( BOOL bUpdate ) const
+{
+ RTL_LOGFILE_CONTEXT( aLog, "svtools (mv76033) svt::EmbeddedObjectRef::GetGraphicStream" );
+ DBG_ASSERT( bUpdate || mpImp->pContainer, "Can't retrieve current graphic!" );
+ uno::Reference < io::XInputStream > xStream;
+ if ( mpImp->pContainer && !bUpdate )
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "getting stream from container" );
+ // try to get graphic stream from container storage
+ xStream = mpImp->pContainer->GetGraphicStream( mxObj, &mpImp->aMediaType );
+ if ( xStream.is() )
+ {
+ const sal_Int32 nConstBufferSize = 32000;
+ SvStream *pStream = new SvMemoryStream( 32000, 32000 );
+ sal_Int32 nRead=0;
+ uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
+ do
+ {
+ nRead = xStream->readBytes ( aSequence, nConstBufferSize );
+ pStream->Write( aSequence.getConstArray(), nRead );
+ }
+ while ( nRead == nConstBufferSize );
+ pStream->Seek(0);
+ return pStream;
+ }
+ }
+
+ if ( !xStream.is() )
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "getting stream from object" );
+ // update wanted or no stream in container storage available
+ xStream = GetGraphicReplacementStream( mpImp->nViewAspect, mxObj, &mpImp->aMediaType );
+
+ if ( xStream.is() )
+ {
+ if ( mpImp->pContainer )
+ mpImp->pContainer->InsertGraphicStream( xStream, mpImp->aPersistName, mpImp->aMediaType );
+
+ SvStream* pResult = ::utl::UcbStreamHelper::CreateStream( xStream );
+ if ( pResult && bUpdate )
+ mpImp->bNeedUpdate = sal_False;
+
+ return pResult;
+ }
+ }
+
+ return NULL;
+}
+
+void EmbeddedObjectRef::DrawPaintReplacement( const Rectangle &rRect, const String &rText, OutputDevice *pOut )
+{
+ MapMode aMM( MAP_APPFONT );
+ Size aAppFontSz = pOut->LogicToLogic( Size( 0, 8 ), &aMM, NULL );
+ Font aFnt( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica" ) ), aAppFontSz );
+ aFnt.SetTransparent( TRUE );
+ aFnt.SetColor( Color( COL_LIGHTRED ) );
+ aFnt.SetWeight( WEIGHT_BOLD );
+ aFnt.SetFamily( FAMILY_SWISS );
+
+ pOut->Push();
+ pOut->SetBackground();
+ pOut->SetFont( aFnt );
+
+ Point aPt;
+ // Nun den Text so skalieren, dass er in das Rect passt.
+ // Wir fangen mit der Defaultsize an und gehen 1-AppFont runter
+ for( USHORT i = 8; i > 2; i-- )
+ {
+ aPt.X() = (rRect.GetWidth() - pOut->GetTextWidth( rText )) / 2;
+ aPt.Y() = (rRect.GetHeight() - pOut->GetTextHeight()) / 2;
+
+ BOOL bTiny = FALSE;
+ if( aPt.X() < 0 ) bTiny = TRUE, aPt.X() = 0;
+ if( aPt.Y() < 0 ) bTiny = TRUE, aPt.Y() = 0;
+ if( bTiny )
+ {
+ // heruntergehen bei kleinen Bildern
+ aFnt.SetSize( Size( 0, aAppFontSz.Height() * i / 8 ) );
+ pOut->SetFont( aFnt );
+ }
+ else
+ break;
+ }
+
+ Bitmap aBmp( SvtResId( BMP_PLUGIN ) );
+ long nHeight = rRect.GetHeight() - pOut->GetTextHeight();
+ long nWidth = rRect.GetWidth();
+ if( nHeight > 0 )
+ {
+ aPt.Y() = nHeight;
+ Point aP = rRect.TopLeft();
+ Size aBmpSize = aBmp.GetSizePixel();
+ // Bitmap einpassen
+ if( nHeight * 10 / nWidth
+ > aBmpSize.Height() * 10 / aBmpSize.Width() )
+ {
+ // nach der Breite ausrichten
+ // Proportion beibehalten
+ long nH = nWidth * aBmpSize.Height() / aBmpSize.Width();
+ // zentrieren
+ aP.Y() += (nHeight - nH) / 2;
+ nHeight = nH;
+ }
+ else
+ {
+ // nach der H"ohe ausrichten
+ // Proportion beibehalten
+ long nW = nHeight * aBmpSize.Width() / aBmpSize.Height();
+ // zentrieren
+ aP.X() += (nWidth - nW) / 2;
+ nWidth = nW;
+ }
+
+ pOut->DrawBitmap( aP, Size( nWidth, nHeight ), aBmp );
+ }
+
+ pOut->IntersectClipRegion( rRect );
+ aPt += rRect.TopLeft();
+ pOut->DrawText( aPt, rText );
+ pOut->Pop();
+}
+
+void EmbeddedObjectRef::DrawShading( const Rectangle &rRect, OutputDevice *pOut )
+{
+ GDIMetaFile * pMtf = pOut->GetConnectMetaFile();
+ if( pMtf && pMtf->IsRecord() )
+ return;
+
+ pOut->Push();
+ pOut->SetLineColor( Color( COL_BLACK ) );
+
+ Size aPixSize = pOut->LogicToPixel( rRect.GetSize() );
+ aPixSize.Width() -= 1;
+ aPixSize.Height() -= 1;
+ Point aPixViewPos = pOut->LogicToPixel( rRect.TopLeft() );
+ INT32 nMax = aPixSize.Width() + aPixSize.Height();
+ for( INT32 i = 5; i < nMax; i += 5 )
+ {
+ Point a1( aPixViewPos ), a2( aPixViewPos );
+ if( i > aPixSize.Width() )
+ a1 += Point( aPixSize.Width(), i - aPixSize.Width() );
+ else
+ a1 += Point( i, 0 );
+ if( i > aPixSize.Height() )
+ a2 += Point( i - aPixSize.Height(), aPixSize.Height() );
+ else
+ a2 += Point( 0, i );
+
+ pOut->DrawLine( pOut->PixelToLogic( a1 ), pOut->PixelToLogic( a2 ) );
+ }
+
+ pOut->Pop();
+
+}
+
+BOOL EmbeddedObjectRef::TryRunningState()
+{
+ return TryRunningState( mxObj );
+}
+
+BOOL EmbeddedObjectRef::TryRunningState( const uno::Reference < embed::XEmbeddedObject >& xEmbObj )
+{
+ if ( !xEmbObj.is() )
+ return FALSE;
+
+ try
+ {
+ if ( xEmbObj->getCurrentState() == embed::EmbedStates::LOADED )
+ xEmbObj->changeState( embed::EmbedStates::RUNNING );
+ }
+ catch ( uno::Exception& )
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void EmbeddedObjectRef::SetGraphicToContainer( const Graphic& rGraphic,
+ comphelper::EmbeddedObjectContainer& aContainer,
+ const ::rtl::OUString& aName,
+ const ::rtl::OUString& aMediaType )
+{
+ SvMemoryStream aStream;
+ aStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+ if ( rGraphic.ExportNative( aStream ) )
+ {
+ aStream.Seek( 0 );
+
+ uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( aStream );
+ aContainer.InsertGraphicStream( xStream, aName, aMediaType );
+ }
+ else
+ OSL_ENSURE( sal_False, "Export of graphic is failed!\n" );
+}
+
+sal_Bool EmbeddedObjectRef::ObjectIsModified( const uno::Reference< embed::XEmbeddedObject >& xObj )
+ throw( uno::Exception )
+{
+ sal_Bool bResult = sal_False;
+
+ sal_Int32 nState = xObj->getCurrentState();
+ if ( nState != embed::EmbedStates::LOADED && nState != embed::EmbedStates::RUNNING )
+ {
+ // the object is active so if the model is modified the replacement
+ // should be retrieved from the object
+ uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
+ if ( xModifiable.is() )
+ bResult = xModifiable->isModified();
+ }
+
+ return bResult;
+}
+
+uno::Reference< io::XInputStream > EmbeddedObjectRef::GetGraphicReplacementStream(
+ sal_Int64 nViewAspect,
+ const uno::Reference< embed::XEmbeddedObject >& xObj,
+ ::rtl::OUString* pMediaType )
+ throw()
+{
+ return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect,xObj,pMediaType);
+}
+
+void EmbeddedObjectRef::UpdateReplacementOnDemand()
+{
+ DELETEZ( mpImp->pGraphic );
+ mpImp->bNeedUpdate = sal_True;
+ if ( mpImp->pHCGraphic )
+ DELETEZ( mpImp->pHCGraphic );
+ mpImp->mnGraphicVersion++;
+
+ if( mpImp->pContainer )
+ {
+ //remove graphic from container thus a new up to date one is requested on save
+ mpImp->pContainer->RemoveGraphicStream( mpImp->aPersistName );
+ }
+}
+
+BOOL EmbeddedObjectRef::IsChart() const
+{
+ //todo maybe for 3.0:
+ //if the changes work good for chart
+ //we should apply them for all own ole objects
+
+ //#i83708# #i81857# #i79578# request an ole replacement image only if really necessary
+ //as this call can be very expensive and does block the user interface as long at it takes
+
+ if ( !mxObj.is() )
+ return false;
+
+ SvGlobalName aObjClsId( mxObj->getClassID() );
+ if(
+ SvGlobalName(SO3_SCH_CLASSID_30) == aObjClsId
+ || SvGlobalName(SO3_SCH_CLASSID_40) == aObjClsId
+ || SvGlobalName(SO3_SCH_CLASSID_50) == aObjClsId
+ || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId)
+ {
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+// #i104867#
+sal_uInt32 EmbeddedObjectRef::getGraphicVersion() const
+{
+ return mpImp->mnGraphicVersion;
+}
+
+void EmbeddedObjectRef::SetDefaultSizeForChart( const Size& rSizeIn_100TH_MM )
+{
+ //#i103460# charts do not necessaryly have an own size within ODF files,
+ //for this case they need to use the size settings from the surrounding frame,
+ //which is made available with this method
+
+ mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size( rSizeIn_100TH_MM.getWidth(), rSizeIn_100TH_MM.getHeight() );
+
+ ::com::sun::star::uno::Reference < ::com::sun::star::chart2::XDefaultSizeTransmitter > xSizeTransmitter( mxObj, uno::UNO_QUERY );
+ DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
+ if( xSizeTransmitter.is() )
+ xSizeTransmitter->setDefaultSize( mpImp->aDefaultSizeForChart_In_100TH_MM );
+}
+
+} // namespace svt
+
diff --git a/svtools/source/misc/embedtransfer.cxx b/svtools/source/misc/embedtransfer.cxx
new file mode 100644
index 000000000000..cbf87f40b7fc
--- /dev/null
+++ b/svtools/source/misc/embedtransfer.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_svtools.hxx"
+#include <com/sun/star/embed/XComponentSupplier.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+
+#include <svtools/embedtransfer.hxx>
+#include <vcl/mapunit.hxx>
+#include <vcl/outdev.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/tempfile.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <svtools/embedhlp.hxx>
+
+using namespace ::com::sun::star;
+
+SvEmbedTransferHelper::SvEmbedTransferHelper( const uno::Reference< embed::XEmbeddedObject >& xObj,
+ Graphic* pGraphic,
+ sal_Int64 nAspect )
+: m_xObj( xObj )
+, m_pGraphic( pGraphic ? new Graphic( *pGraphic ) : NULL )
+, m_nAspect( nAspect )
+{
+ if( xObj.is() )
+ {
+ TransferableObjectDescriptor aObjDesc;
+
+ FillTransferableObjectDescriptor( aObjDesc, m_xObj, NULL, m_nAspect );
+ PrepareOLE( aObjDesc );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+SvEmbedTransferHelper::~SvEmbedTransferHelper()
+{
+ if ( m_pGraphic )
+ {
+ delete m_pGraphic;
+ m_pGraphic = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SvEmbedTransferHelper::AddSupportedFormats()
+{
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( FORMAT_GDIMETAFILE );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvEmbedTransferHelper::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ sal_Bool bRet = sal_False;
+
+ if( m_xObj.is() )
+ {
+ try
+ {
+ sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
+ if( HasFormat( nFormat ) )
+ {
+ if( nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
+ {
+ TransferableObjectDescriptor aDesc;
+ FillTransferableObjectDescriptor( aDesc, m_xObj, m_pGraphic, m_nAspect );
+ bRet = SetTransferableObjectDescriptor( aDesc, rFlavor );
+ }
+ else if( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ {
+ try
+ {
+ // TODO/LATER: Propbably the graphic should be copied here as well
+ // currently it is handled by the applications
+ utl::TempFile aTmp;
+ aTmp.EnableKillingFile( TRUE );
+ uno::Reference < embed::XEmbedPersist > xPers( m_xObj, uno::UNO_QUERY );
+ if ( xPers.is() )
+ {
+ uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetTemporaryStorage();
+ ::rtl::OUString aName = ::rtl::OUString::createFromAscii("Dummy");
+ SvStream* pStream = NULL;
+ BOOL bDeleteStream = FALSE;
+ uno::Sequence < beans::PropertyValue > aEmpty;
+ xPers->storeToEntry( xStg, aName, aEmpty, aEmpty );
+ if ( xStg->isStreamElement( aName ) )
+ {
+ uno::Reference < io::XStream > xStm = xStg->cloneStreamElement( aName );
+ pStream = utl::UcbStreamHelper::CreateStream( xStm );
+ bDeleteStream = TRUE;
+ }
+ else
+ {
+ pStream = aTmp.GetStream( STREAM_STD_READWRITE );
+ uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper( *pStream ) );
+ xStg->openStorageElement( aName, embed::ElementModes::READ )->copyToStorage( xStor );
+ }
+
+ ::com::sun::star::uno::Any aAny;
+ const sal_uInt32 nLen = pStream->Seek( STREAM_SEEK_TO_END );
+ ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen );
+
+ pStream->Seek( STREAM_SEEK_TO_BEGIN );
+ pStream->Read( aSeq.getArray(), nLen );
+ if ( bDeleteStream )
+ delete pStream;
+
+ if( ( bRet = ( aSeq.getLength() > 0 ) ) == sal_True )
+ {
+ aAny <<= aSeq;
+ SetAny( aAny, rFlavor );
+ }
+ }
+ else
+ {
+ //TODO/LATER: how to handle objects without persistance?!
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ else if ( nFormat == FORMAT_GDIMETAFILE && m_pGraphic )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+
+ const GDIMetaFile& aMetaFile = m_pGraphic->GetGDIMetaFile();
+ ((GDIMetaFile*)(&aMetaFile))->Write( aMemStm );
+ uno::Any aAny;
+ aAny <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) );
+ SetAny( aAny, rFlavor );
+ bRet = sal_True;
+ }
+ else if ( m_xObj.is() && :: svt::EmbeddedObjectRef::TryRunningState( m_xObj ) )
+ {
+ uno::Reference< datatransfer::XTransferable > xTransferable( m_xObj->getComponent(), uno::UNO_QUERY );
+ if ( xTransferable.is() )
+ {
+ uno::Any aAny = xTransferable->getTransferData( rFlavor );
+ SetAny( aAny, rFlavor );
+ bRet = sal_True;
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // Error handling?
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SvEmbedTransferHelper::ObjectReleased()
+{
+ m_xObj = uno::Reference< embed::XEmbeddedObject >();
+}
+
+void SvEmbedTransferHelper::FillTransferableObjectDescriptor( TransferableObjectDescriptor& rDesc,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XEmbeddedObject >& xObj,
+ Graphic* pGraphic,
+ sal_Int64 nAspect )
+{
+ //TODO/LATER: need TypeName to fill it into the Descriptor (will be shown in listbox)
+ ::com::sun::star::datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aFlavor );
+
+ rDesc.maClassName = SvGlobalName( xObj->getClassID() );
+ rDesc.maTypeName = aFlavor.HumanPresentableName;
+
+ //TODO/LATER: the aspect size in the descriptor is wrong, unfortunately the stream
+ // representation of the descriptor allows only 4 bytes for the aspect
+ // so for internal transport something different should be found
+ rDesc.mnViewAspect = sal::static_int_cast<sal_uInt16>( nAspect );
+
+ //TODO/LATER: status needs to become sal_Int64
+ rDesc.mnOle2Misc = sal::static_int_cast<sal_Int32>(xObj->getStatus( rDesc.mnViewAspect ));
+
+ Size aSize;
+ MapMode aMapMode( MAP_100TH_MM );
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ {
+ if ( pGraphic )
+ {
+ aMapMode = pGraphic->GetPrefMapMode();
+ aSize = pGraphic->GetPrefSize();
+ }
+ else
+ aSize = Size( 2500, 2500 );
+ }
+ else
+ {
+ try
+ {
+ awt::Size aSz;
+ aSz = xObj->getVisualAreaSize( rDesc.mnViewAspect );
+ aSize = Size( aSz.Width, aSz.Height );
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {
+ OSL_ENSURE( sal_False, "Can not get visual area size!\n" );
+ aSize = Size( 5000, 5000 );
+ }
+
+ // TODO/LEAN: getMapUnit can switch object to running state
+ aMapMode = MapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( rDesc.mnViewAspect ) ) );
+ }
+
+ rDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapMode, MapMode( MAP_100TH_MM ) );
+ rDesc.maDragStartPos = Point();
+ rDesc.maDisplayName = String();
+ rDesc.mbCanLink = FALSE;
+}
+
diff --git a/svtools/source/misc/errtxt.src b/svtools/source/misc/errtxt.src
new file mode 100644
index 000000000000..f33896e20003
--- /dev/null
+++ b/svtools/source/misc/errtxt.src
@@ -0,0 +1,514 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svtools/svtools.hrc>
+#include "sfxecode.hxx"
+ // pragma ----------------------------------------------------------------
+Resource RID_ERRCTX
+{
+ String ERRCTX_ERROR
+ {
+ Text [ en-US ] = "Error" ;
+ };
+ String ERRCTX_WARNING
+ {
+ Text [ en-US ] = "Warning" ;
+ };
+ String ERRCTX_SFX_LOADTEMPLATE
+ {
+ Text [ en-US ] = "$(ERR) loading the template $(ARG1)" ;
+ };
+ String ERRCTX_SFX_SAVEDOC
+ {
+ Text [ en-US ] = "$(ERR) saving the document $(ARG1)";
+ };
+ String ERRCTX_SFX_SAVEASDOC
+ {
+ Text [ en-US ] = "$(ERR) saving the document $(ARG1)";
+ };
+ String ERRCTX_SFX_DOCINFO
+ {
+ Text [ en-US ] = "$(ERR) displaying doc. information for document $(ARG1)" ;
+ };
+ String ERRCTX_SFX_DOCTEMPLATE
+ {
+ Text [ en-US ] = "$(ERR) writing document $(ARG1) as template" ;
+ };
+ String ERRCTX_SFX_MOVEORCOPYCONTENTS
+ {
+ Text [ en-US ] = "$(ERR) copying or moving document contents" ;
+ };
+ String ERRCTX_SFX_DOCMANAGER
+ {
+ Text [ en-US ] = "$(ERR) starting the Document Manager" ;
+ };
+ String ERRCTX_SFX_OPENDOC
+ {
+ Text [ en-US ] = "$(ERR) loading document $(ARG1)" ;
+ };
+ String ERRCTX_SFX_NEWDOCDIRECT
+ {
+ Text [ en-US ] = "$(ERR) creating a new document" ;
+ };
+ String ERRCTX_SFX_NEWDOC
+ {
+ Text [ en-US ] = "$(ERR) creating a new document" ;
+ };
+ String ERRCTX_SFX_CREATEOBJSH
+ {
+ Text [ en-US ] = "$(ERR) expanding entry" ;
+ };
+ String ERRCTX_SFX_LOADBASIC
+ {
+ Text [ en-US ] = "$(ERR) loading BASIC of document $(ARG1)" ;
+ };
+ String ERRCTX_SFX_SEARCHADDRESS
+ {
+ Text [ en-US ] = "$(ERR) searching for an address";
+ };
+};
+Resource RID_ERRHDL
+{
+ String ERRCODE_CLASS_ABORT
+ {
+ Text [ en-US ] = "Abort" ;
+ };
+ String ERRCODE_CLASS_NOTEXISTS
+ {
+ Text [ en-US ] = "Nonexistent object" ;
+ };
+ String ERRCODE_CLASS_ALREADYEXISTS
+ {
+ Text [ en-US ] = "Object already exists" ;
+ };
+ String ERRCODE_CLASS_ACCESS
+ {
+ Text [ en-US ] = "Object not accessible" ;
+ };
+ String ERRCODE_CLASS_PATH
+ {
+ Text [ en-US ] = "Inadmissible path" ;
+ };
+ String ERRCODE_CLASS_LOCKING
+ {
+ Text [ en-US ] = "Locking problem" ;
+ };
+ String ERRCODE_CLASS_PARAMETER
+ {
+ Text [ en-US ] = "Wrong parameter" ;
+ };
+ String ERRCODE_CLASS_SPACE
+ {
+ Text [ en-US ] = "Resource exhausted" ;
+ };
+ String ERRCODE_CLASS_NOTSUPPORTED
+ {
+ Text [ en-US ] = "Action not supported" ;
+ };
+ String ERRCODE_CLASS_READ
+ {
+ Text [ en-US ] = "Read-Error" ;
+ };
+ String ERRCODE_CLASS_WRITE
+ {
+ Text [ en-US ] = "Write Error" ;
+ };
+ String ERRCODE_CLASS_UNKNOWN
+ {
+ Text [ en-US ] = "unknown" ;
+ };
+ String ERRCODE_CLASS_VERSION
+ {
+ Text [ en-US ] = "Version Incompatibility" ;
+ };
+ String ERRCODE_CLASS_GENERAL
+ {
+ Text [ en-US ] = "General Error" ;
+ };
+ String ERRCODE_CLASS_FORMAT
+ {
+ Text [ en-US ] = "Incorrect format" ;
+ };
+ String ERRCODE_CLASS_CREATE
+ {
+ Text [ en-US ] = "Error creating object" ;
+ };
+ String ERRCODE_CLASS_SBX
+ {
+ Text [ en-US ] = "Inadmissible value or data type" ;
+ };
+ String ERRCODE_CLASS_RUNTIME
+ {
+ Text [ en-US ] = "BASIC runtime error" ;
+ };
+ String ERRCODE_CLASS_COMPILER
+ {
+ Text [ en-US ] = "BASIC syntax error" ;
+ };
+ String 1
+ {
+ Text [ en-US ] = "General Error" ;
+ };
+ String ERRCODE_IO_GENERAL
+ {
+ Text [ en-US ] = "General input/output error." ;
+ };
+ String ERRCODE_IO_MISPLACEDCHAR
+ {
+ Text [ en-US ] = "Invalid file name." ;
+ };
+ String ERRCODE_IO_NOTEXISTS
+ {
+ Text [ en-US ] = "Nonexistent file." ;
+ };
+ String ERRCODE_IO_ALREADYEXISTS
+ {
+ Text [ en-US ] = "File already exists." ;
+ };
+ String ERRCODE_IO_NOTADIRECTORY
+ {
+ Text [ en-US ] = "The object is not a directory." ;
+ };
+ String ERRCODE_IO_NOTAFILE
+ {
+ Text [ en-US ] = "The object is not a file." ;
+ };
+ String ERRCODE_IO_INVALIDDEVICE
+ {
+ Text [ en-US ] = "The specified device is invalid." ;
+ };
+ String ERRCODE_IO_ACCESSDENIED
+ {
+ Text [ en-US ] = "The object cannot be accessed\ndue to insufficient user rights." ;
+ };
+ String ERRCODE_IO_LOCKVIOLATION
+ {
+ Text [ en-US ] = "Sharing violation while accessing the object." ;
+ };
+ String ERRCODE_IO_OUTOFSPACE
+ {
+ Text [ en-US ] = "No more space on device." ;
+ };
+ String ERRCODE_IO_ISWILDCARD
+ {
+ Text [ en-US ] = "This operation cannot be run on\nfiles containing wildcards." ;
+ };
+ String ERRCODE_IO_NOTSUPPORTED
+ {
+ Text [ en-US ] = "This operation is not supported on this operating system." ;
+ };
+ String ERRCODE_IO_TOOMANYOPENFILES
+ {
+ Text [ en-US ] = "There are too many files open." ;
+ };
+ String ERRCODE_IO_CANTREAD
+ {
+ Text [ en-US ] = "Data could not be read from the file." ;
+ };
+ String ERRCODE_IO_CANTWRITE
+ {
+ Text [ en-US ] = "The file could not be written." ;
+ };
+ String ERRCODE_IO_OUTOFMEMORY
+ {
+ Text [ en-US ] = "The operation could not be run due to insufficient memory." ;
+ };
+ String ERRCODE_IO_CANTSEEK
+ {
+ Text [ en-US ] = "The seek operation could not be run." ;
+ };
+ String ERRCODE_IO_CANTTELL
+ {
+ Text [ en-US ] = "The tell operation could not be run." ;
+ };
+ String ERRCODE_IO_WRONGVERSION
+ {
+ Text [ en-US ] = "Incorrect file version." ;
+ };
+ String ERRCODE_IO_WRONGFORMAT
+ {
+ Text [ en-US ] = "Incorrect file format." ;
+ };
+ String ERRCODE_IO_INVALIDCHAR
+ {
+ Text [ en-US ] = "The file name contains invalid characters." ;
+ };
+ String ERRCODE_IO_UNKNOWN
+ {
+ Text [ en-US ] = "An unknown I/O error has occurred." ;
+ };
+ String ERRCODE_IO_INVALIDACCESS
+ {
+ Text [ en-US ] = "An invalid attempt was made to access the file." ;
+ };
+ String ERRCODE_IO_CANTCREATE
+ {
+ Text [ en-US ] = "The file could not be created." ;
+ };
+ String ERRCODE_IO_INVALIDPARAMETER
+ {
+ Text [ en-US ] = "The operation was started under an invalid parameter." ;
+ };
+ String ERRCODE_IO_ABORT
+ {
+ Text [ en-US ] = "The operation on the file was aborted." ;
+ };
+ String ERRCODE_IO_NOTEXISTSPATH
+ {
+ Text [ en-US ] = "Path to the file does not exist." ;
+ };
+ String ERRCODE_IO_RECURSIVE
+ {
+ Text [ en-US ] = "An object cannot be copied into itself." ;
+ };
+ String ERRCODE_SFX_NOSTDTEMPLATE
+ {
+ Text [ en-US ] = "The default template could not be opened." ;
+ };
+ String ERRCODE_SFX_TEMPLATENOTFOUND
+ {
+ Text [ en-US ] = "The specified template could not be found." ;
+ };
+ String ERRCODE_SFX_NOTATEMPLATE
+ {
+ Text [ en-US ] = "The file cannot be used as template." ;
+ };
+ String ERRCODE_SFX_CANTREADDOCINFO
+ {
+ Text [ en-US ] = "Document information could not be read from the file because\nthe document information format is unknown or because document information does not\nexist." ;
+ };
+ String ERRCODE_SFX_ALREADYOPEN
+ {
+ Text [ en-US ] = "This document has already been opened for editing." ;
+ };
+ String ERRCODE_SFX_WRONGPASSWORD
+ {
+ Text [ en-US ] = "The wrong password has been entered." ;
+ };
+ String ERRCODE_SFX_DOLOADFAILED
+ {
+ Text [ en-US ] = "Error reading file." ;
+ };
+ String ERRCODE_SFX_DOCUMENTREADONLY
+ {
+ Text [ en-US ] = "The document was opened as read-only." ;
+ };
+ String ERRCODE_SFX_OLEGENERAL
+ {
+ Text [ en-US ] = "General OLE Error." ;
+ };
+ String ERRCODE_INET_NAME_RESOLVE
+ {
+ Text [ en-US ] = "The host name $(ARG1) could not be resolved." ;
+ };
+ String ERRCODE_INET_CONNECT
+ {
+ Text [ en-US ] = "Could not establish network connection to $(ARG1)." ;
+ };
+ String ERRCODE_INET_READ
+ {
+ Text [ en-US ] = "Error reading data from the network.\nServer error message: $(ARG1)." ;
+ };
+ String ERRCODE_INET_WRITE
+ {
+ Text [ en-US ] = "Error transferring data to the network.\nServer error message: $(ARG1)." ;
+ };
+ String ERRCODE_INET_GENERAL
+ {
+ Text [ en-US ] = "General network error has occurred." ;
+ };
+ String ERRCODE_INET_OFFLINE
+ {
+ Text [ en-US ] = "The requested network data is not available in the cache and cannot be transmitted as the Online mode has not be activated." ;
+ };
+ String ERRCODE_SFXMSG_STYLEREPLACE
+ {
+ ExtraData = ERRCODE_MSG_ERROR | ERRCODE_BUTTON_OK_CANCEL ;
+ Text [ en-US ] = "Should the $(ARG1) Style be replaced?" ;
+ };
+ String ERRCODE_SFX_NOFILTER
+ {
+ Text [ en-US ] = "A filter has not been found." ;
+ };
+ String ERRCODE_SFX_CANTFINDORIGINAL
+ {
+ Text [ en-US ] = "The original could not be determined." ;
+ };
+ String ERRCODE_SFX_CANTCREATECONTENT
+ {
+ Text [ en-US ] = "The contents could not be created." ;
+ };
+ String ERRCODE_SFX_CANTCREATELINK
+ {
+ Text [ en-US ] = "The link could not be created." ;
+ };
+ String ERRCODE_SFX_WRONGBMKFORMAT
+ {
+ Text [ en-US ] = "The link format is invalid." ;
+ };
+ String ERRCODE_SFX_WRONGICONFILE
+ {
+ Text [ en-US ] = "The configuration of the icon display is invalid." ;
+ };
+ String ERRCODE_SFX_CANTWRITEICONFILE
+ {
+ Text [ en-US ] = "The configuration of the icon display can not be saved." ;
+ };
+ String ERRCODE_SFX_CANTDELICONFILE
+ {
+ Text [ en-US ] = "The configuration of the icon display could not be deleted." ;
+ };
+ String ERRCODE_SFX_CANTRENAMECONTENT
+ {
+ Text [ en-US ] = "Contents cannot be renamed." ;
+ };
+ String ERRCODE_SFX_INVALIDBMKPATH
+ {
+ Text [ en-US ] = "The bookmark folder is invalid." ;
+ };
+ String ERRCODE_SFX_CANTWRITEURLCFGFILE
+ {
+ Text [ en-US ] = "The configuration of the URLs to be saved locally could not be saved." ;
+ };
+ String ERRCODE_SFX_WRONGURLCFGFORMAT
+ {
+ Text [ en-US ] = "The configuration format of the URLs to be saved locally is invalid." ;
+ };
+ String ERRCODE_SFX_NODOCUMENT
+ {
+ Text [ en-US ] = "This action cannot be applied to a document that does not exist." ;
+ };
+ String ERRCODE_SFX_INVALIDLINK
+ {
+ Text [ en-US ] = "The link refers to an invalid target." ;
+ };
+ String ERRCODE_SFX_INVALIDTRASHPATH
+ {
+ Text [ en-US ] = "The Recycle Bin path is invalid." ;
+ };
+ String ERRCODE_SFX_NOTRESTORABLE
+ {
+ Text [ en-US ] = "The entry could not be restored." ;
+ };
+ String ERRCODE_IO_NAMETOOLONG
+ {
+ Text [ en-US ] = "The file name is too long for the target file system." ;
+ };
+ String ERRCODE_SFX_CONSULTUSER
+ {
+ Text [ en-US ] = "The details for running the function are incomplete." ;
+ };
+ String ERRCODE_SFX_INVALIDSYNTAX
+ {
+ Text [ en-US ] = "The input syntax is invalid." ;
+ };
+ String ERRCODE_SFX_CANTCREATEFOLDER
+ {
+ Text [ en-US ] = "The input syntax is invalid." ;
+ };
+ String ERRCODE_SFX_CANTRENAMEFOLDER
+ {
+ Text [ en-US ] = "The input syntax is invalid." ;
+ };
+ String ERRCODE_SFX_WRONG_CDF_FORMAT
+ {
+ Text [ en-US ] = "The channel document has an invalid format." ;
+ };
+ String ERRCODE_SFX_EMPTY_SERVER
+ {
+ Text [ en-US ] = "The server must not be empty." ;
+ };
+ String ERRCODE_SFX_NO_ABOBOX
+ {
+ Text [ en-US ] = "A subscription folder is required to install a Channel." ;
+ };
+ String ERRCODE_IO_NOTSTORABLEINBINARYFORMAT
+ {
+ Text [ en-US ] = "This document contains attributes that cannot be saved in the selected format.\nPlease save the document in a %PRODUCTNAME %PRODUCTVERSION file format.";
+ };
+ String ERRCODE_SFX_TARGETFILECORRUPTED
+ {
+ Text [ en-US ] = "The file $(FILENAME) cannot be saved. Please check your system settings. You can find an automatically generated backup copy of this file in folder $(PATH) named $(BACKUPNAME).";
+ };
+ String ERRCODE_SFX_NOMOREDOCUMENTSALLOWED
+ {
+ Text [ en-US ] = "The maximum number of documents that can be opened at the same time has been reached. You need to close one or more documents before you can open a new document.";
+ };
+ String ERRCODE_SFX_CANTCREATEBACKUP
+ {
+ Text [ en-US ] = "Could not create backup copy." ;
+ };
+ String ERRCODE_SFX_MACROS_SUPPORT_DISABLED
+ {
+ Text [ en-US ] = "An attempt was made to execute a macro.\nFor security reasons, macro support is disabled.";
+ };
+ String ERRCODE_SFX_DOCUMENT_MACRO_DISABLED
+ {
+ Text [ en-US ] = "This document contains macros.\n\nMacros may contain viruses. Execution of macros is disabled due to the current macro security setting in Tools - Options - %PRODUCTNAME - Security.\n\nTherefore, some functionality may not be available." ;
+ };
+ String ERRCODE_SFX_BROKENSIGNATURE
+ {
+ Text [ en-US ] = "The digitally signed document content and/or macros do not match the current document signature.\n\nThis could be the result of document manipulation or of structural document damage due to data transmission.\n\nWe recommend that you do not trust the content of the current document.\nExecution of macros is disabled for this document.\n " ;
+ };
+ String ERRCODE_SFX_INCOMPLETE_ENCRYPTION
+ {
+ Text [ en-US ] = "The encrypted document contains unexpected non-encrypted streams.\n\nThis could be the result of document manipulation.\n\nWe recommend that you do not trust the content of the current document.\nExecution of macros is disabled for this document.\n " ;
+ };
+
+ String ERRCODE_IO_INVALIDLENGTH
+ {
+ Text [ en-US ] = "Invalid data length." ;
+ };
+ String ERRCODE_IO_CURRENTDIR
+ {
+ Text [ en-US ] = "Function not possible: path contains current directory." ;
+ };
+ String ERRCODE_IO_NOTSAMEDEVICE
+ {
+ Text [ en-US ] = "Function not possible: device (drive) not identical." ;
+ };
+ String ERRCODE_IO_DEVICENOTREADY
+ {
+ Text [ en-US ] = "Device (drive) not ready." ;
+ };
+ String ERRCODE_IO_BADCRC
+ {
+ Text [ en-US ] = "Wrong check amount." ;
+ };
+ String ERRCODE_IO_WRITEPROTECTED
+ {
+ Text [ en-US ] = "Function not possible: write protected." ;
+ };
+ String ERRCODE_SFX_SHARED_NOPASSWORDCHANGE
+ {
+ Text [ en-US ] = "The password of a shared spreadsheet cannot be set or changed.\nDeactivate sharing mode first.";
+ };
+};
+
+// eof ------------------------------------------------------------------------
+
diff --git a/svtools/source/misc/helpagent.src b/svtools/source/misc/helpagent.src
new file mode 100644
index 000000000000..1f2eaaa291a3
--- /dev/null
+++ b/svtools/source/misc/helpagent.src
@@ -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 _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+Bitmap BMP_HELP_AGENT_IMAGE
+{
+ File = "helpagent.bmp";
+};
+
+Bitmap BMP_HELP_AGENT_CLOSER
+{
+ File = "closer.bmp";
+};
+
diff --git a/svtools/source/misc/helpagentwindow.cxx b/svtools/source/misc/helpagentwindow.cxx
new file mode 100644
index 000000000000..1d407bbdb611
--- /dev/null
+++ b/svtools/source/misc/helpagentwindow.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_svtools.hxx"
+#include "helpagentwindow.hxx"
+#include <osl/diagnose.h>
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/bitmap.hxx>
+#include <svtools/svtdata.hxx>
+
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#ifndef _SVT_HELPID_HRC
+#include <svtools/helpid.hrc>
+#endif
+
+#define WB_AGENT_STYLE 0
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+
+ //====================================================================
+ //= CloserButton_Impl
+ //= overload of ImageButton, because sometimes vcl doesn't call the click handler
+ //====================================================================
+ //--------------------------------------------------------------------
+ class CloserButton_Impl : public ImageButton
+ {
+ public:
+ CloserButton_Impl( Window* pParent, WinBits nBits ) : ImageButton( pParent, nBits ) {}
+
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ };
+
+ //--------------------------------------------------------------------
+ void CloserButton_Impl::MouseButtonUp( const MouseEvent& rMEvt )
+ {
+ ImageButton::MouseButtonUp( rMEvt );
+ GetClickHdl().Call( this );
+ }
+
+ //====================================================================
+ //= HelpAgentWindow
+ //====================================================================
+ //--------------------------------------------------------------------
+ HelpAgentWindow::HelpAgentWindow( Window* _pParent )
+ :FloatingWindow( _pParent, WB_AGENT_STYLE)
+ ,m_pCloser(NULL)
+ ,m_pCallback(NULL)
+ {
+ // -----------------
+ // the closer button
+ Bitmap aCloserBitmap(SvtResId(BMP_HELP_AGENT_CLOSER));
+ Image aCloserImage( aCloserBitmap, Color(COL_LIGHTMAGENTA) );
+ m_pCloser = new CloserButton_Impl( this, WB_NOTABSTOP | WB_NOPOINTERFOCUS );
+ static_cast<CloserButton_Impl*>(m_pCloser)->SetModeImage( aCloserImage );
+ static_cast<CloserButton_Impl*>(m_pCloser)->SetClickHdl( LINK(this, HelpAgentWindow, OnButtonClicked) );
+ m_pCloser->SetSizePixel( implOptimalButtonSize(aCloserImage) );
+ m_pCloser->Show();
+ m_pCloser->SetZOrder( NULL, WINDOW_ZORDER_LAST );
+
+ // ----------------------------
+ // calculate our preferred size
+ Bitmap aHelpAgentBitmap(SvtResId(BMP_HELP_AGENT_IMAGE));
+ m_aPicture = Image( aHelpAgentBitmap );
+ m_aPreferredSize = m_aPicture.GetSizePixel();
+ m_aPreferredSize.Width() += 2;
+ m_aPreferredSize.Height() += 2;
+
+ Size aSize = GetSizePixel();
+ Size aOutputSize = GetOutputSizePixel();
+ m_aPreferredSize.Width() += aSize.Width() - aOutputSize.Width();
+ m_aPreferredSize.Height() += aSize.Height() - aOutputSize.Height();
+
+ SetPointer(Pointer(POINTER_REFHAND));
+ AlwaysEnableInput( TRUE, TRUE );
+
+ // unique id for the testtool
+ SetUniqueId( HID_HELPAGENT_WINDOW );
+ }
+
+ //--------------------------------------------------------------------
+ HelpAgentWindow::~HelpAgentWindow()
+ {
+ if (m_pCloser && m_pCloser->IsTracking())
+ m_pCloser->EndTracking();
+ if (m_pCloser && m_pCloser->IsMouseCaptured())
+ m_pCloser->ReleaseMouse();
+
+ delete m_pCloser;
+ }
+
+ //--------------------------------------------------------------------
+ void HelpAgentWindow::Paint( const Rectangle& rRect )
+ {
+ FloatingWindow::Paint(rRect);
+
+ Size aOutputSize( GetOutputSizePixel() );
+ Point aPoint=Point();
+ Rectangle aOutputRect( aPoint, aOutputSize );
+ Rectangle aInnerRect( aOutputRect );
+
+ // paint the background
+ SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() );
+ SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
+ DrawRect( aOutputRect );
+
+ // paint the image
+ Size aPictureSize( m_aPicture.GetSizePixel() );
+ Point aPicturePos(
+ aOutputRect.Left() + (aInnerRect.GetWidth() - aPictureSize.Width()) / 2,
+ aOutputRect.Top() + (aInnerRect.GetHeight() - aPictureSize.Height()) / 2 );
+
+ DrawImage( aPicturePos, m_aPicture, 0 );
+ }
+
+ //--------------------------------------------------------------------
+ void HelpAgentWindow::MouseButtonUp( const MouseEvent& rMEvt )
+ {
+ FloatingWindow::MouseButtonUp(rMEvt);
+
+ if (m_pCallback)
+ m_pCallback->helpRequested();
+ }
+
+ //--------------------------------------------------------------------
+ Size HelpAgentWindow::implOptimalButtonSize( const Image& _rButtonImage )
+ {
+ Size aPreferredSize = _rButtonImage.GetSizePixel();
+ // add a small frame, needed by the button
+ aPreferredSize.Width() += 5;
+ aPreferredSize.Height() += 5;
+ return aPreferredSize;
+ }
+
+ //--------------------------------------------------------------------
+ void HelpAgentWindow::Resize()
+ {
+ FloatingWindow::Resize();
+
+ Size aOutputSize = GetOutputSizePixel();
+ Size aCloserSize = m_pCloser->GetSizePixel();
+ if (m_pCloser)
+ m_pCloser->SetPosPixel( Point(aOutputSize.Width() - aCloserSize.Width() - 3, 4) );
+ }
+
+ //--------------------------------------------------------------------
+ IMPL_LINK( HelpAgentWindow, OnButtonClicked, Window*, _pWhichOne )
+ {
+ if (m_pCloser == _pWhichOne)
+ if (m_pCallback)
+ m_pCallback->closeAgent();
+ return 0L;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
diff --git a/svtools/source/misc/imagemgr.cxx b/svtools/source/misc/imagemgr.cxx
new file mode 100644
index 000000000000..c02ebc4477c6
--- /dev/null
+++ b/svtools/source/misc/imagemgr.cxx
@@ -0,0 +1,881 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+// includes --------------------------------------------------------------
+
+#include "imagemgr.hxx"
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include "vcl/image.hxx"
+#include <sot/storage.hxx>
+#include <sot/clsids.hxx>
+#include <unotools/ucbhelper.hxx>
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <ucbhelper/content.hxx>
+#include <tools/rcid.h>
+#include <rtl/logfile.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <svtools/svtools.hrc>
+#include "imagemgr.hrc"
+#include <svtools/svtdata.hxx>
+#include <vos/mutex.hxx>
+
+// globals *******************************************************************
+
+#define NO_INDEX ((USHORT)0xFFFF)
+#define CONTENT_HELPER ::utl::UCBContentHelper
+#define ASCII_STRING(s) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) )
+
+struct SvtExtensionResIdMapping_Impl
+{
+ const char* _pExt;
+ BOOL _bExt;
+ USHORT _nStrId;
+ USHORT _nImgId;
+};
+
+static SvtExtensionResIdMapping_Impl __READONLY_DATA ExtensionMap_Impl[] =
+{
+ { "awk", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "bas", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "bat", TRUE, STR_DESCRIPTION_BATCHFILE, 0 },
+ { "bmk", FALSE, STR_DESCRIPTION_BOOKMARKFILE, 0 },
+ { "bmp", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_BITMAP },
+ { "c", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "cfg", FALSE, STR_DESCRIPTION_CFGFILE, 0 },
+ { "cmd", TRUE, STR_DESCRIPTION_BATCHFILE, 0 },
+ { "cob", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "com", TRUE, STR_DESCRIPTION_APPLICATION, 0 },
+ { "cxx", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "dbf", TRUE, STR_DESCRIPTION_DATABASE_TABLE, IMG_TABLE },
+ { "def", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "dll", TRUE, STR_DESCRIPTION_SYSFILE, 0 },
+ { "doc", FALSE, STR_DESCRIPTION_WORD_DOC, IMG_WRITER },
+ { "dot", FALSE, STR_DESCRIPTION_WORD_DOC, IMG_WRITERTEMPLATE },
+ { "docx", FALSE, STR_DESCRIPTION_WORD_DOC, IMG_WRITER },
+ { "dxf", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_DXF },
+ { "exe", TRUE, STR_DESCRIPTION_APPLICATION, 0 },
+ { "gif", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_GIF },
+ { "h", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "hlp", FALSE, STR_DESCRIPTION_HELP_DOC, 0 },
+ { "hrc", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "htm", FALSE, STR_DESCRIPTION_HTMLFILE, IMG_HTML },
+ { "html", FALSE, STR_DESCRIPTION_HTMLFILE, IMG_HTML },
+ { "asp", FALSE, STR_DESCRIPTION_HTMLFILE, IMG_HTML },
+ { "hxx", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "ini", FALSE, STR_DESCRIPTION_CFGFILE, 0 },
+ { "java", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "jpeg", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_JPG },
+ { "jpg", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_JPG },
+ { "lha", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+#ifdef WNT
+ { "lnk", FALSE, 0, 0 },
+#endif
+ { "log", TRUE, STR_DESCRIPTION_LOGFILE, 0 },
+ { "lst", TRUE, STR_DESCRIPTION_LOGFILE, 0 },
+ { "met", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_MET },
+ { "mml", FALSE, STR_DESCRIPTION_MATHML_DOC, IMG_MATH },
+ { "mod", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "odb", FALSE, STR_DESCRIPTION_OO_DATABASE_DOC, IMG_OO_DATABASE_DOC },
+ { "odg", FALSE, STR_DESCRIPTION_OO_DRAW_DOC, IMG_OO_DRAW_DOC },
+ { "odf", FALSE, STR_DESCRIPTION_OO_MATH_DOC, IMG_OO_MATH_DOC },
+ { "odm", FALSE, STR_DESCRIPTION_OO_GLOBAL_DOC, IMG_OO_GLOBAL_DOC },
+ { "odp", FALSE, STR_DESCRIPTION_OO_IMPRESS_DOC, IMG_OO_IMPRESS_DOC },
+ { "ods", FALSE, STR_DESCRIPTION_OO_CALC_DOC, IMG_OO_CALC_DOC },
+ { "odt", FALSE, STR_DESCRIPTION_OO_WRITER_DOC, IMG_OO_WRITER_DOC },
+ { "otg", FALSE, STR_DESCRIPTION_OO_DRAW_TEMPLATE, IMG_OO_DRAW_TEMPLATE },
+ { "otp", FALSE, STR_DESCRIPTION_OO_IMPRESS_TEMPLATE, IMG_OO_IMPRESS_TEMPLATE },
+ { "ots", FALSE, STR_DESCRIPTION_OO_CALC_TEMPLATE, IMG_OO_CALC_TEMPLATE },
+ { "ott", FALSE, STR_DESCRIPTION_OO_WRITER_TEMPLATE, IMG_OO_WRITER_TEMPLATE },
+ { "pas", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "pcd", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_PCD },
+ { "pct", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_PCT },
+ { "pcx", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_PCX },
+ { "pl", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "png", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_PNG },
+ { "rar", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "rtf", FALSE, STR_DESCRIPTION_WORD_DOC, IMG_WRITER },
+ { "sbl", FALSE, 0, 0 },
+ { "sch", FALSE, 0, 0 },
+ { "sda", FALSE, STR_DESCRIPTION_SDRAW_DOC, IMG_DRAW },
+ { "sdb", FALSE, STR_DESCRIPTION_SDATABASE_DOC, IMG_DATABASE },
+ { "sdc", FALSE, STR_DESCRIPTION_SCALC_DOC, IMG_CALC },
+ { "sdd", FALSE, STR_DESCRIPTION_SIMPRESS_DOC, IMG_IMPRESS },
+ { "sdp", FALSE, STR_DESCRIPTION_SIMPRESS_DOC, 0 },
+ { "sds", FALSE, STR_DESCRIPTION_SCHART_DOC, 0 },
+ { "sdw", FALSE, STR_DESCRIPTION_SWRITER_DOC, IMG_WRITER },
+ { "sga", FALSE, 0, 0 },
+ { "sgf", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_SGF },
+ { "sgl", FALSE, STR_DESCRIPTION_GLOBALDOC, IMG_GLOBAL_DOC },
+ { "sgv", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_SGV },
+ { "shtml", FALSE, STR_DESCRIPTION_HTMLFILE, IMG_HTML },
+ { "sim", FALSE, STR_DESCRIPTION_SIMAGE_DOC, IMG_SIM },
+ { "smf", FALSE, STR_DESCRIPTION_SMATH_DOC, IMG_MATH },
+ { "src", TRUE, STR_DESCRIPTION_SOURCEFILE, 0 },
+ { "svh", FALSE, STR_DESCRIPTION_HELP_DOC, 0 },
+ { "svm", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_SVM },
+ { "stc", FALSE, STR_DESCRIPTION_CALC_TEMPLATE, IMG_CALCTEMPLATE },
+ { "std", FALSE, STR_DESCRIPTION_DRAW_TEMPLATE, IMG_DRAWTEMPLATE },
+ { "sti", FALSE, STR_DESCRIPTION_IMPRESS_TEMPLATE, IMG_IMPRESSTEMPLATE },
+ { "stw", FALSE, STR_DESCRIPTION_WRITER_TEMPLATE, IMG_WRITERTEMPLATE },
+ { "sxc", FALSE, STR_DESCRIPTION_SXCALC_DOC, IMG_CALC },
+ { "sxd", FALSE, STR_DESCRIPTION_SXDRAW_DOC, IMG_DRAW },
+ { "sxg", FALSE, STR_DESCRIPTION_SXGLOBAL_DOC, IMG_GLOBAL_DOC },
+ { "sxi", FALSE, STR_DESCRIPTION_SXIMPRESS_DOC, IMG_IMPRESS },
+ { "sxm", FALSE, STR_DESCRIPTION_SXMATH_DOC, IMG_MATH },
+ { "sxs", FALSE, STR_DESCRIPTION_SXCHART_DOC, 0 },
+ { "sxw", FALSE, STR_DESCRIPTION_SXWRITER_DOC, IMG_WRITER },
+ { "sys", TRUE, STR_DESCRIPTION_SYSFILE, 0 },
+ { "tif", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_TIFF },
+ { "tiff", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_TIFF },
+ { "txt", FALSE, STR_DESCRIPTION_TEXTFILE, IMG_TEXTFILE },
+ { "url", FALSE, STR_DESCRIPTION_LINK, 0 },
+ { "vor", FALSE, STR_DESCRIPTION_SOFFICE_TEMPLATE_DOC, IMG_WRITERTEMPLATE },
+ { "vxd", TRUE, STR_DESCRIPTION_SYSFILE, 0 },
+ { "wmf", TRUE, STR_DESCRIPTION_GRAPHIC_DOC, IMG_WMF },
+ { "xls", FALSE, STR_DESCRIPTION_EXCEL_DOC, IMG_CALC },
+ { "xlt", FALSE, STR_DESCRIPTION_EXCEL_TEMPLATE_DOC, IMG_CALCTEMPLATE },
+ { "xlsx", FALSE, STR_DESCRIPTION_EXCEL_DOC, IMG_CALC },
+ { "uu", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "uue", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "z", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "zip", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "zoo", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "gz", TRUE, STR_DESCRIPTION_ARCHIVFILE, 0 },
+ { "ppt", FALSE, STR_DESCRIPTION_POWERPOINT, IMG_IMPRESS },
+ { "pot", FALSE, STR_DESCRIPTION_POWERPOINT_TEMPLATE, IMG_IMPRESSTEMPLATE },
+ { "pps", FALSE, STR_DESCRIPTION_POWERPOINT_SHOW, IMG_IMPRESS },
+ { "pptx", FALSE, STR_DESCRIPTION_POWERPOINT, IMG_IMPRESS },
+ { "oxt", FALSE, STR_DESCRIPTION_EXTENSION, IMG_EXTENSION },
+ { 0, FALSE, 0, 0 }
+};
+
+#ifdef OS2
+ SvtExtensionResIdMapping_Impl Mappings[] =
+ {
+ {"StarWriter 4.0", FALSE,STR_DESCRIPTION_SWRITER_DOC, IMG_WRITER},
+ {"StarWriter 3.0", FALSE,STR_DESCRIPTION_SWRITER_DOC, IMG_WRITER},
+ {"StarCalc 4.0", FALSE,STR_DESCRIPTION_SCALC_DOC, IMG_CALC},
+ {"StarCalc 3.0", FALSE,STR_DESCRIPTION_SCALC_DOC, IMG_CALC},
+ {"StarImpress 4.0", FALSE,STR_DESCRIPTION_SIMPRESS_DOC,IMG_IMPRESS},
+ {"StarDraw 4.0", FALSE,STR_DESCRIPTION_SDRAW_DOC, IMG_DRAW},
+ {"StarDraw 3.0", FALSE,STR_DESCRIPTION_SDRAW_DOC, IMG_DRAW},
+ {"StarChart 3.0", FALSE,STR_DESCRIPTION_SCHART_DOC, IMG_CHART},
+ {"StarChart 4.0", FALSE,STR_DESCRIPTION_SCHART_DOC, IMG_CHART},
+ {"Bitmap", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_BITMAP},
+ {"AutoCAD", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_SIM},
+ {"Gif-File", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_GIF},
+ {"JPEG-File", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_JPG},
+ {"Metafile ", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_SIM},
+ {"Photo-CD ", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_PCD},
+ {"Mac Pict", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_PCT},
+ {"PCX-File ", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_PCX},
+ {"PNG-File", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_SIM},
+ {"SV-Metafile", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_SIM},
+ {"TIFF-File", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_TIFF},
+ {"MS-Metafile", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_WMF},
+ {"XBM-File", FALSE,STR_DESCRIPTION_GRAPHIC_DOC, IMG_BITMAP},
+ {"UniformResourceLocator", FALSE,STR_DESCRIPTION_LINK, IMG_URL},
+ {NULL, 0}
+ };
+#endif
+
+struct SvtFactory2ExtensionMapping_Impl
+{
+ const char* _pFactory;
+ const char* _pExtension;
+};
+
+// mapping from "private:factory" url to extension
+
+static SvtFactory2ExtensionMapping_Impl __READONLY_DATA Fac2ExtMap_Impl[] =
+{
+ { "swriter", "odt" },
+ { "swriter/web", "html" },
+ { "swriter/GlobalDocument", "odm" },
+ { "scalc", "ods" },
+ { "simpress", "odp" },
+ { "sdraw", "odg" },
+ { "smath", "odf" },
+ { "sdatabase", "odb" },
+ { NULL, NULL }
+};
+
+//****************************************************************************
+
+static String GetImageExtensionByFactory_Impl( const String& rURL )
+{
+ INetURLObject aObj( rURL );
+ String aPath = aObj.GetURLPath( INetURLObject::NO_DECODE );
+ String aExtension;
+
+ if ( aPath.Len() )
+ {
+ USHORT nIndex = 0;
+ while ( Fac2ExtMap_Impl[ nIndex ]._pFactory )
+ {
+ if ( aPath.EqualsAscii( Fac2ExtMap_Impl[ nIndex ]._pFactory ) )
+ {
+ // extension found
+ aExtension = String::CreateFromAscii( Fac2ExtMap_Impl[ nIndex ]._pExtension );
+ // and return it
+ return aExtension;
+ }
+ ++nIndex;
+ }
+ }
+
+ // no extension found, so use the type detection (performance brake)
+
+ try
+ {
+ // get the TypeDetection service to access all registered types
+ ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > xFac = ::comphelper::getProcessServiceFactory();
+ ::com::sun::star::uno::Reference < ::com::sun::star::document::XTypeDetection > xTypeDetector(
+ xFac->createInstance( ASCII_STRING("com.sun.star.document.TypeDetection") ), ::com::sun::star::uno::UNO_QUERY );
+
+ ::rtl::OUString aInternalType = xTypeDetector->queryTypeByURL( rURL );
+ ::com::sun::star::uno::Reference < ::com::sun::star::container::XNameAccess > xAccess( xTypeDetector, ::com::sun::star::uno::UNO_QUERY );
+ ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > aTypeProps;
+ if ( aInternalType.getLength() > 0 && xAccess->hasByName( aInternalType ) )
+ {
+ xAccess->getByName( aInternalType ) >>= aTypeProps;
+ sal_Int32 nProps = aTypeProps.getLength();
+ for ( sal_Int32 i = 0; i < nProps; ++i )
+ {
+ const ::com::sun::star::beans::PropertyValue& rProp = aTypeProps[i];
+ if ( rProp.Name.compareToAscii("Extensions") == COMPARE_EQUAL )
+ {
+ ::com::sun::star::uno::Sequence < ::rtl::OUString > aExtensions;
+ if ( ( rProp.Value >>= aExtensions ) && aExtensions.getLength() > 0 )
+ {
+ const ::rtl::OUString* pExtensions = aExtensions.getConstArray();
+ aExtension = String( pExtensions[0] );
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch( const ::com::sun::star::uno::RuntimeException& )
+ {
+ throw; // dont hide it!
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ // type detection failed -> no extension
+ }
+
+ return aExtension;
+}
+
+static USHORT GetIndexOfExtension_Impl( const String& rExtension )
+{
+ USHORT nRet = NO_INDEX;
+ if ( rExtension.Len() )
+ {
+ USHORT nIndex = 0;
+ String aExt = rExtension;
+ aExt.ToLowerAscii();
+ while ( ExtensionMap_Impl[ nIndex ]._pExt )
+ {
+ if ( aExt.EqualsAscii( ExtensionMap_Impl[ nIndex ]._pExt ) )
+ {
+ nRet = nIndex;
+ break;
+ }
+ ++nIndex;
+ }
+ }
+
+ return nRet;
+}
+
+static USHORT GetImageId_Impl( const String& rExtension )
+{
+ USHORT nImage = IMG_FILE;
+ if ( rExtension.Len() != NO_INDEX )
+ {
+ USHORT nIndex = GetIndexOfExtension_Impl( rExtension );
+ if ( nIndex != NO_INDEX )
+ {
+ nImage = ExtensionMap_Impl[ nIndex ]._nImgId;
+ if ( !nImage )
+ nImage = IMG_FILE;
+ }
+ }
+
+ return nImage;
+}
+
+static sal_Bool GetVolumeProperties_Impl( ::ucbhelper::Content& rContent, svtools::VolumeInfo& rVolumeInfo )
+{
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ bRet = ( ( rContent.getPropertyValue( ASCII_STRING("IsVolume") ) >>= rVolumeInfo.m_bIsVolume ) &&
+ ( rContent.getPropertyValue( ASCII_STRING("IsRemote") ) >>= rVolumeInfo.m_bIsRemote ) &&
+ ( rContent.getPropertyValue( ASCII_STRING("IsRemoveable") ) >>= rVolumeInfo.m_bIsRemoveable ) &&
+ ( rContent.getPropertyValue( ASCII_STRING("IsFloppy") ) >>= rVolumeInfo.m_bIsFloppy ) &&
+ ( rContent.getPropertyValue( ASCII_STRING("IsCompactDisc") ) >>= rVolumeInfo.m_bIsCompactDisc ) );
+ }
+ catch( const ::com::sun::star::uno::RuntimeException& )
+ {
+ throw; // dont hide it!
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ // type detection failed -> no extension
+ }
+
+ return bRet;
+}
+
+static USHORT GetFolderImageId_Impl( const String& rURL )
+{
+ USHORT nRet = IMG_FOLDER;
+ ::svtools::VolumeInfo aVolumeInfo;
+ try
+ {
+ ::ucbhelper::Content aCnt( rURL, ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ if ( GetVolumeProperties_Impl( aCnt, aVolumeInfo ) )
+ {
+ if ( aVolumeInfo.m_bIsRemote )
+ nRet = IMG_NETWORKDEV;
+ else if ( aVolumeInfo.m_bIsCompactDisc )
+ nRet = IMG_CDROMDEV;
+ else if ( aVolumeInfo.m_bIsRemoveable )
+ nRet = IMG_REMOVEABLEDEV;
+ else if ( aVolumeInfo.m_bIsVolume )
+ nRet = IMG_FIXEDDEV;
+ }
+ }
+ catch( const ::com::sun::star::uno::RuntimeException& )
+ {
+ throw; // dont hide it!
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ // ...
+ }
+ return nRet;
+}
+
+static USHORT GetImageId_Impl( const INetURLObject& rObject, sal_Bool bDetectFolder )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aTimeLog, "svtools", "hb93813", "SvFileInformationManager::GetImageId_Impl()" );
+
+ String aExt, sURL = rObject.GetMainURL( INetURLObject::NO_DECODE );
+ USHORT nImage = IMG_FILE;
+
+ if ( rObject.GetProtocol() == INET_PROT_PRIVATE )
+ {
+ String aURLPath = sURL.Copy( URL_PREFIX_PRIV_SOFFICE_LEN );
+ String aType = aURLPath.GetToken( 0, INET_PATH_TOKEN );
+ if ( aType == String( RTL_CONSTASCII_STRINGPARAM("factory") ) )
+ {
+ // detect an image id for our "private:factory" urls
+ aExt = GetImageExtensionByFactory_Impl( sURL );
+ if ( aExt.Len() > 0 )
+ nImage = GetImageId_Impl( aExt );
+ return nImage;
+ }
+ else if ( aType == String( RTL_CONSTASCII_STRINGPARAM("image") ) )
+ nImage = (USHORT)aURLPath.GetToken( 1, INET_PATH_TOKEN ).ToInt32();
+ }
+ else
+ {
+ aExt = rObject.getExtension();
+ if ( aExt.EqualsAscii( "vor" ) )
+ {
+ SotStorageRef aStorage = new SotStorage( sURL, STREAM_STD_READ );
+ USHORT nId = IMG_WRITERTEMPLATE;
+ if ( !aStorage->GetError() )
+ {
+ SvGlobalName aGlobalName = aStorage->GetClassName();
+ if ( aGlobalName == SvGlobalName(SO3_SC_CLASSID_50) || aGlobalName == SvGlobalName(SO3_SC_CLASSID_40) || aGlobalName == SvGlobalName(SO3_SC_CLASSID_30) )
+ nId = IMG_CALCTEMPLATE;
+ else if ( aGlobalName == SvGlobalName(SO3_SDRAW_CLASSID_50) )
+ nId = IMG_DRAWTEMPLATE;
+ else if ( aGlobalName == SvGlobalName(SO3_SIMPRESS_CLASSID_50) ||
+ aGlobalName == SvGlobalName(SO3_SIMPRESS_CLASSID_40) || aGlobalName == SvGlobalName(SO3_SIMPRESS_CLASSID_30) )
+ nId = IMG_IMPRESSTEMPLATE;
+ else if ( aGlobalName == SvGlobalName(SO3_SM_CLASSID_50) || aGlobalName == SvGlobalName(SO3_SM_CLASSID_40) || aGlobalName == SvGlobalName(SO3_SM_CLASSID_30) )
+ nId = IMG_MATHTEMPLATE;
+ }
+
+ return nId;
+ }
+ }
+
+ if ( nImage == IMG_FILE && sURL.Len() )
+ {
+ if ( bDetectFolder && CONTENT_HELPER::IsFolder( sURL ) )
+ nImage = GetFolderImageId_Impl( sURL );
+ else if ( aExt.Len() > 0 )
+ nImage = GetImageId_Impl( aExt );
+ }
+ return nImage;
+}
+
+static USHORT GetDescriptionId_Impl( const String& rExtension, sal_Bool& rbShowExt )
+{
+ USHORT nId = 0;
+
+ if ( rExtension.Len() != NO_INDEX )
+ {
+ USHORT nIndex = GetIndexOfExtension_Impl( rExtension );
+ if ( nIndex != NO_INDEX )
+ {
+ nId = ExtensionMap_Impl[ nIndex ]._nStrId;
+ rbShowExt = ExtensionMap_Impl[ nIndex ]._bExt;
+ }
+ }
+
+ return nId;
+}
+
+static String GetDescriptionByFactory_Impl( const String& rFactory )
+{
+ USHORT nResId = 0;
+ if ( rFactory.EqualsIgnoreCaseAscii( "swriter", 0, 7 ) )
+ nResId = STR_DESCRIPTION_FACTORY_WRITER;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "scalc", 0, 5 ) )
+ nResId = STR_DESCRIPTION_FACTORY_CALC;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "simpress", 0, 8 ) )
+ nResId = STR_DESCRIPTION_FACTORY_IMPRESS;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "sdraw", 0, 5 ) )
+ nResId = STR_DESCRIPTION_FACTORY_DRAW;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "swriter/web", 0, 11 ) )
+ nResId = STR_DESCRIPTION_FACTORY_WRITERWEB;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "swriter/globaldocument", 0, 22 ) )
+ nResId = STR_DESCRIPTION_FACTORY_GLOBALDOC;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "smath", 0, 5 ) )
+ nResId = STR_DESCRIPTION_FACTORY_MATH;
+ else if ( rFactory.EqualsIgnoreCaseAscii( "sdatabase", 0, 9 ) )
+ nResId = STR_DESCRIPTION_FACTORY_DATABASE;
+
+ String aRet;
+ if ( nResId )
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ aRet = String( SvtResId( nResId ) );
+ }
+ return aRet;
+}
+
+static USHORT GetFolderDescriptionId_Impl( const String& rURL )
+{
+ USHORT nRet = STR_DESCRIPTION_FOLDER;
+ svtools::VolumeInfo aVolumeInfo;
+ try
+ {
+ ::ucbhelper::Content aCnt( rURL, ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ if ( GetVolumeProperties_Impl( aCnt, aVolumeInfo ) )
+ {
+ if ( aVolumeInfo.m_bIsRemote )
+ nRet = STR_DESCRIPTION_REMOTE_VOLUME;
+ else if ( aVolumeInfo.m_bIsFloppy )
+ nRet = STR_DESCRIPTION_FLOPPY_VOLUME;
+ else if ( aVolumeInfo.m_bIsCompactDisc )
+ nRet = STR_DESCRIPTION_CDROM_VOLUME;
+ else if ( aVolumeInfo.m_bIsRemoveable || aVolumeInfo.m_bIsVolume )
+ nRet = STR_DESCRIPTION_LOCALE_VOLUME;
+ }
+ }
+ catch( const ::com::sun::star::uno::RuntimeException& )
+ {
+ throw; // dont hide it!
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ // ...
+ }
+ return nRet;
+}
+
+static ResMgr* GetIsoResMgr_Impl()
+{
+ static ResMgr* pIsoResMgr = NULL;
+
+ if ( !pIsoResMgr )
+ {
+ ByteString aResMgrName( "iso" );
+ pIsoResMgr = ResMgr::CreateResMgr(
+ aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+ if ( !pIsoResMgr )
+ {
+ // no "iso" resource -> search for "ooo" resource
+ aResMgrName = ByteString( "ooo" );
+ pIsoResMgr = ResMgr::CreateResMgr(
+ aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+ }
+ }
+
+ return pIsoResMgr;
+}
+
+static ImageList* CreateImageList_Impl( USHORT nResId )
+{
+ ImageList* pList = NULL;
+ ResMgr* pResMgr = GetIsoResMgr_Impl();
+ DBG_ASSERT( pResMgr, "SvFileInformationManager::CreateImageList_Impl(): no resmgr" );
+ ResId aResId( nResId, *pResMgr );
+ aResId.SetRT( RSC_IMAGELIST );
+ if ( pResMgr->IsAvailable( aResId ) )
+ pList = new ImageList( aResId );
+ else
+ pList = new ImageList();
+ return pList;
+}
+
+static Image GetOfficeImageFromList_Impl( USHORT nImageId, BOOL bBig, BOOL bHighContrast )
+{
+ ImageList* pList = NULL;
+
+ static ImageList* _pSmallOfficeImgList = NULL;
+ static ImageList* _pBigOfficeImgList = NULL;
+ static ImageList* _pSmallHCOfficeImgList = NULL;
+ static ImageList* _pBigHCOfficeImgList = NULL;
+ static ULONG nStyle = Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+
+ // If the style has been changed, throw away our cache of the older images
+ if ( nStyle != Application::GetSettings().GetStyleSettings().GetSymbolsStyle() )
+ {
+ delete _pSmallOfficeImgList, _pSmallOfficeImgList = NULL;
+ delete _pBigOfficeImgList, _pBigOfficeImgList = NULL;
+ delete _pSmallHCOfficeImgList, _pSmallHCOfficeImgList = NULL;
+ delete _pBigHCOfficeImgList, _pBigHCOfficeImgList = NULL;
+ nStyle = Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+ }
+
+ // #i21242# MT: For B&W we need the HC Image and must transform.
+ // bHiContrast is TRUE for all dark backgrounds, but we need HC Images for HC White also,
+ // so we can't rely on bHighContrast.
+ BOOL bBlackAndWhite = Application::GetSettings().GetStyleSettings().IsHighContrastBlackAndWhite();
+ if ( bBlackAndWhite )
+ bHighContrast = TRUE;
+
+
+ if ( bBig )
+ {
+ if ( bHighContrast )
+ {
+ if ( !_pBigHCOfficeImgList )
+ _pBigHCOfficeImgList = CreateImageList_Impl( RID_SVTOOLS_IMAGELIST_BIG_HIGHCONTRAST );
+ pList = _pBigHCOfficeImgList;
+ }
+ else
+ {
+ if ( !_pBigOfficeImgList )
+ _pBigOfficeImgList = CreateImageList_Impl( RID_SVTOOLS_IMAGELIST_BIG );
+ pList = _pBigOfficeImgList;
+ }
+ }
+ else
+ {
+ if ( bHighContrast )
+ {
+ if ( !_pSmallHCOfficeImgList )
+ _pSmallHCOfficeImgList = CreateImageList_Impl( RID_SVTOOLS_IMAGELIST_SMALL_HIGHCONTRAST );
+ pList = _pSmallHCOfficeImgList;
+ }
+ else
+ {
+ if ( !_pSmallOfficeImgList )
+ _pSmallOfficeImgList = CreateImageList_Impl( RID_SVTOOLS_IMAGELIST_SMALL );
+ pList = _pSmallOfficeImgList;
+ }
+ }
+
+ Image aImage = pList->GetImage( nImageId );
+
+ if ( bBlackAndWhite )
+ {
+ // First invert the Image, because it's designed for black background, structures are bright
+ aImage.Invert();
+ // Now make monochrome...
+ ImageColorTransform eTrans = IMAGECOLORTRANSFORM_MONOCHROME_WHITE;
+ if ( Application::GetSettings().GetStyleSettings().GetFaceColor().GetColor() == COL_WHITE )
+ eTrans = IMAGECOLORTRANSFORM_MONOCHROME_BLACK;
+ aImage = aImage.GetColorTransformedImage( eTrans );
+ }
+
+ return aImage;
+}
+
+static Image GetImageFromList_Impl( USHORT nImageId, BOOL bBig, BOOL bHighContrast )
+{
+ if ( !bBig && IMG_FOLDER == nImageId && !bHighContrast )
+ // return our new small folder image (256 colors)
+ return Image( SvtResId( IMG_SVT_FOLDER ) );
+
+ ImageList* pList = NULL;
+
+ static ImageList* _pSmallImageList = NULL;
+ static ImageList* _pBigImageList = NULL;
+ static ImageList* _pSmallHCImageList = NULL;
+ static ImageList* _pBigHCImageList = NULL;
+ static ULONG nStyle = Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+
+ // If the style has been changed, throw away our cache of the older images
+ if ( nStyle != Application::GetSettings().GetStyleSettings().GetSymbolsStyle() )
+ {
+ delete _pSmallImageList, _pSmallImageList = NULL;
+ delete _pBigImageList, _pBigImageList = NULL;
+ delete _pSmallHCImageList, _pSmallHCImageList = NULL;
+ delete _pBigHCImageList, _pBigHCImageList = NULL;
+ nStyle = Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+ }
+
+ if ( bBig )
+ {
+ if ( bHighContrast )
+ {
+ if ( !_pBigHCImageList )
+ _pBigHCImageList = new ImageList( SvtResId( RID_SVTOOLS_IMAGELIST_BIG_HIGHCONTRAST ) );
+ pList = _pBigHCImageList;
+ }
+ else
+ {
+ if ( !_pBigImageList )
+ _pBigImageList = new ImageList( SvtResId( RID_SVTOOLS_IMAGELIST_BIG ) );
+ pList = _pBigImageList;
+ }
+ }
+ else
+ {
+ if ( bHighContrast )
+ {
+ if ( !_pSmallHCImageList )
+ _pSmallHCImageList = new ImageList( SvtResId( RID_SVTOOLS_IMAGELIST_SMALL_HIGHCONTRAST ) );
+ pList = _pSmallHCImageList;
+ }
+ else
+ {
+ if ( !_pSmallImageList )
+ _pSmallImageList = new ImageList( SvtResId( RID_SVTOOLS_IMAGELIST_SMALL ) );
+ pList = _pSmallImageList;
+ }
+ }
+
+ if ( pList->HasImageAtPos( nImageId ) )
+ return pList->GetImage( nImageId );
+ else
+ return GetOfficeImageFromList_Impl( nImageId, bBig, bHighContrast );
+}
+
+//****************************************************************************
+
+void ReplaceStarOfficeVar( String& _rDescription )
+{
+ static String sVariable( RTL_CONSTASCII_STRINGPARAM( "%STAROFFICE" ) );
+ static String sProductName;
+ if ( sProductName.Len() == 0 )
+ {
+ ::rtl::OUString sTemp;
+ ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ) >>= sTemp;
+ if ( sTemp.equalsAscii( "StarSuite" ) == sal_False )
+ sProductName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "StarOffice" ) );
+ else
+ sProductName = String( sTemp );
+ }
+ _rDescription.SearchAndReplace( sVariable, sProductName );
+}
+
+String SvFileInformationManager::GetDescription_Impl( const INetURLObject& rObject, sal_Bool bDetectFolder )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aTimeLog, "svtools", "hb93813", "SvFileInformationManager::GetDescription_Impl()" );
+
+ String sDescription;
+ String sExtension( rObject.getExtension() ), sURL( rObject.GetMainURL( INetURLObject::NO_DECODE ) );
+ USHORT nResId = 0;
+ sal_Bool bShowExt = sal_False, bDetected = sal_False, bOnlyFile = sal_False;
+ sal_Bool bFolder = bDetectFolder ? CONTENT_HELPER::IsFolder( sURL ) : sal_False;
+ if ( !bFolder )
+ {
+ if ( !bDetected )
+ {
+ if ( rObject.GetProtocol() == INET_PROT_PRIVATE )
+ {
+ String aURLPath = sURL.Copy( URL_PREFIX_PRIV_SOFFICE_LEN );
+ String aType = aURLPath.GetToken( 0, INET_PATH_TOKEN );
+ if ( aType == String( RTL_CONSTASCII_STRINGPARAM("factory") ) )
+ {
+ sDescription = GetDescriptionByFactory_Impl( aURLPath.Copy( aURLPath.Search( INET_PATH_TOKEN ) + 1 ) );
+ bDetected = sal_True;
+ }
+ }
+
+ if ( !bDetected )
+ {
+ // search a description by extension
+ sal_Bool bExt = ( sExtension.Len() > 0 );
+ if ( bExt )
+ {
+ sExtension.ToLowerAscii();
+ nResId = GetDescriptionId_Impl( sExtension, bShowExt );
+ }
+ if ( !nResId )
+ {
+ nResId = STR_DESCRIPTION_FILE;
+ bOnlyFile = bExt;
+ }
+ }
+ }
+ }
+ else
+ nResId = GetFolderDescriptionId_Impl( sURL );
+
+ if ( nResId > 0 )
+ {
+ if ( bOnlyFile )
+ {
+ bShowExt = sal_False;
+ sExtension.ToUpperAscii();
+ sDescription = sExtension;
+ sDescription += '-';
+ }
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ sDescription += String( SvtResId( nResId ) );
+ }
+
+ DBG_ASSERT( sDescription.Len() > 0, "file without description" );
+
+ if ( bShowExt )
+ {
+ sDescription += String( RTL_CONSTASCII_STRINGPARAM(" (") );
+ sDescription += sExtension;
+ sDescription += ')';
+ }
+
+ ReplaceStarOfficeVar( sDescription );
+ return sDescription;
+}
+
+Image SvFileInformationManager::GetImage( const INetURLObject& rObject, sal_Bool bBig )
+{
+ return GetImage( rObject, bBig, FALSE );
+}
+
+Image SvFileInformationManager::GetFileImage( const INetURLObject& rObject, sal_Bool bBig )
+{
+ return GetFileImage( rObject, bBig, FALSE );
+}
+
+Image SvFileInformationManager::GetImageNoDefault( const INetURLObject& rObject, sal_Bool bBig )
+{
+ return GetImageNoDefault( rObject, bBig, FALSE );
+}
+
+Image SvFileInformationManager::GetFolderImage( const svtools::VolumeInfo& rInfo, sal_Bool bBig )
+{
+ return GetFolderImage( rInfo, bBig, FALSE );
+}
+
+Image SvFileInformationManager::GetImage( const INetURLObject& rObject, sal_Bool bBig, sal_Bool bHighContrast )
+{
+ USHORT nImage = GetImageId_Impl( rObject, sal_True );
+ DBG_ASSERT( nImage, "invalid ImageId" );
+ return GetImageFromList_Impl( nImage, bBig, bHighContrast );
+}
+
+Image SvFileInformationManager::GetFileImage( const INetURLObject& rObject, sal_Bool bBig, sal_Bool bHighContrast )
+{
+ USHORT nImage = GetImageId_Impl( rObject, sal_False );
+ DBG_ASSERT( nImage, "invalid ImageId" );
+ return GetImageFromList_Impl( nImage, bBig, bHighContrast );
+}
+
+Image SvFileInformationManager::GetImageNoDefault( const INetURLObject& rObject, sal_Bool bBig, sal_Bool bHighContrast )
+{
+ USHORT nImage = GetImageId_Impl( rObject, sal_True );
+ DBG_ASSERT( nImage, "invalid ImageId" );
+
+ if ( nImage == IMG_FILE )
+ return Image();
+
+ return GetImageFromList_Impl( nImage, bBig, bHighContrast );
+}
+
+Image SvFileInformationManager::GetFolderImage( const svtools::VolumeInfo& rInfo, sal_Bool bBig, sal_Bool bHighContrast )
+{
+ USHORT nImage = IMG_FOLDER;
+ DBG_ASSERT( nImage, "invalid ImageId" );
+
+ if ( rInfo.m_bIsRemote )
+ nImage = IMG_NETWORKDEV;
+ else if ( rInfo.m_bIsCompactDisc )
+ nImage = IMG_CDROMDEV;
+ else if ( rInfo.m_bIsRemoveable || rInfo.m_bIsFloppy )
+ nImage = IMG_REMOVEABLEDEV;
+ else if ( rInfo.m_bIsVolume )
+ nImage = IMG_FIXEDDEV;
+
+ return GetImageFromList_Impl( nImage, bBig, bHighContrast );
+}
+
+String SvFileInformationManager::GetDescription( const INetURLObject& rObject )
+{
+ return SvFileInformationManager::GetDescription_Impl( rObject, sal_True );
+}
+
+String SvFileInformationManager::GetFileDescription( const INetURLObject& rObject )
+{
+ return SvFileInformationManager::GetDescription_Impl( rObject, sal_False );
+}
+
+String SvFileInformationManager::GetFolderDescription( const svtools::VolumeInfo& rInfo )
+{
+ USHORT nResId = STR_DESCRIPTION_FOLDER;
+ if ( rInfo.m_bIsRemote )
+ nResId = STR_DESCRIPTION_REMOTE_VOLUME;
+ else if ( rInfo.m_bIsFloppy )
+ nResId = STR_DESCRIPTION_FLOPPY_VOLUME;
+ else if ( rInfo.m_bIsCompactDisc )
+ nResId = STR_DESCRIPTION_CDROM_VOLUME;
+ else if ( rInfo.m_bIsRemoveable || rInfo.m_bIsVolume )
+ nResId = STR_DESCRIPTION_LOCALE_VOLUME;
+
+ String sDescription = String( SvtResId( nResId ) );
+ return sDescription;
+}
+
diff --git a/svtools/source/misc/imagemgr.src b/svtools/source/misc/imagemgr.src
new file mode 100644
index 000000000000..cdc9f8da1c87
--- /dev/null
+++ b/svtools/source/misc/imagemgr.src
@@ -0,0 +1,452 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+ // includes ******************************************************************
+
+#include <svtools/svtools.hrc>
+#include "imagemgr.hrc"
+
+ // images ********************************************************************
+
+#define X_IMAGE_LIST \
+ IMG_WORKPLACE ; \
+ IMG_BITMAP ; \
+ IMG_EXCEL ; \
+ IMG_EXCELTEMPLATE ; \
+ IMG_FTPSERVER ; \
+ IMG_GALLERY ; \
+ IMG_GALLERYTHEME ; \
+ IMG_GIF ; \
+ IMG_HELP ; \
+ IMG_HTML ; \
+ IMG_JPG ; \
+ IMG_LINK ; \
+ IMG_LOTUS ; \
+ IMG_MATHTEMPLATE ; \
+ IMG_FILE ; \
+ IMG_APP ; \
+ IMG_PCD ; \
+ IMG_PCT ; \
+ IMG_PCX ; \
+ IMG_SIM ; \
+ IMG_TEXTFILE ; \
+ IMG_SVHELP ; \
+ IMG_TIFF ; \
+ IMG_URL ; \
+ IMG_WMF ; \
+ IMG_WORD ; \
+ IMG_FIXEDDEV ; \
+ IMG_REMOVEABLEDEV ; \
+ IMG_CDROMDEV ; \
+ IMG_NETWORKDEV ; \
+ IMG_RAMDEV ; \
+ IMG_TABLEFOLDER ; \
+ IMG_TABLE ; \
+ IMG_FOLDER ; \
+ IMG_EXPANDEDFOLDER ; \
+ IMG_XXX ; \
+ IMG_GALLERYIMPORT ; \
+ IMG_QUERYFOLDER ; \
+ IMG_QUERY ; \
+ IMG_FORM ; \
+ IMG_FORMFOLDER ; \
+ IMG_REPORT ; \
+ IMG_REPORTFOLDER ; \
+ IMG_OTHERS ; \
+ IMG_DXF ; \
+ IMG_MET ; \
+ IMG_PNG ; \
+ IMG_SGF ; \
+ IMG_SGV ; \
+ IMG_SVM ; \
+ IMG_TASK ; \
+ IMG_APPOINTMENT ; \
+ IMG_RELATION ; \
+ IMG_IMPRESSPACKED ; \
+ IMG_POWERPOINT ; \
+ IMG_POWERPOINTTEMPLATE ; \
+ IMG_OO_DATABASE_DOC ; \
+ IMG_OO_DRAW_DOC ; \
+ IMG_OO_MATH_DOC ; \
+ IMG_OO_GLOBAL_DOC ; \
+ IMG_OO_IMPRESS_DOC ; \
+ IMG_OO_CALC_DOC ; \
+ IMG_OO_WRITER_DOC ; \
+ IMG_OO_DRAW_TEMPLATE ; \
+ IMG_OO_IMPRESS_TEMPLATE ; \
+ IMG_OO_CALC_TEMPLATE ; \
+ IMG_OO_WRITER_TEMPLATE ; \
+ IMG_EXTENSION ;
+
+ImageList RID_SVTOOLS_IMAGELIST_BIG
+{
+ Prefix = "lx";
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ IdList =
+ {
+ X_IMAGE_LIST
+ };
+ IdCount =
+ {
+ 68 ;
+ };
+};
+
+ImageList RID_SVTOOLS_IMAGELIST_SMALL
+{
+ Prefix = "sx";
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ IdList =
+ {
+ X_IMAGE_LIST
+ };
+ IdCount =
+ {
+ 68;
+ };
+};
+
+ImageList RID_SVTOOLS_IMAGELIST_BIG_HIGHCONTRAST
+{
+ Prefix = "lxh";
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ IdList =
+ {
+ X_IMAGE_LIST
+ };
+ IdCount =
+ {
+ 68 ;
+ };
+};
+
+ImageList RID_SVTOOLS_IMAGELIST_SMALL_HIGHCONTRAST
+{
+ Prefix = "sxh";
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ IdList =
+ {
+ X_IMAGE_LIST
+ };
+ IdCount =
+ {
+ 68;
+ };
+};
+
+Bitmap BMP_PLUGIN
+{
+ File = "plugin.png" ;
+};
+
+// description strings
+
+String STR_DESCRIPTION_SOURCEFILE
+{
+ Text [ en-US ] = "Source code" ;
+};
+String STR_DESCRIPTION_BOOKMARKFILE
+{
+ Text [ en-US ] = "Bookmark file" ;
+};
+String STR_DESCRIPTION_GRAPHIC_DOC
+{
+ Text [ en-US ] = "Graphics" ;
+};
+String STR_DESCRIPTION_CFGFILE
+{
+ Text [ en-US ] = "Configuration file" ;
+};
+String STR_DESCRIPTION_APPLICATION
+{
+ Text [ en-US ] = "Application" ;
+};
+String STR_DESCRIPTION_DATABASE_TABLE
+{
+ Text [ en-US ] = "Database table" ;
+};
+String STR_DESCRIPTION_SYSFILE
+{
+ Text [ en-US ] = "System file" ;
+};
+String STR_DESCRIPTION_WORD_DOC
+{
+ Text [ en-US ] = "MS Word document" ;
+};
+String STR_DESCRIPTION_HELP_DOC
+{
+ Text [ en-US ] = "Help file" ;
+};
+String STR_DESCRIPTION_HTMLFILE
+{
+ Text [ en-US ] = "HTML document" ;
+};
+String STR_DESCRIPTION_ARCHIVFILE
+{
+ Text [ en-US ] = "Archive file" ;
+};
+String STR_DESCRIPTION_LOGFILE
+{
+ Text [ en-US ] = "Log file" ;
+};
+String STR_DESCRIPTION_SMATH_DOC
+{
+ Text = "StarMath 2.0 - 5.0" ;
+};
+String STR_DESCRIPTION_SCHART_DOC
+{
+ Text = "StarChart 3.0 - 5.0" ;
+};
+String STR_DESCRIPTION_SDRAW_DOC
+{
+ Text = "StarDraw 3.0 / 5.0 (StarImpress)" ;
+};
+
+String STR_DESCRIPTION_SDATABASE_DOC
+{
+ Text [ en-US ] = "%STAROFFICE Database" ;
+};
+
+String STR_DESCRIPTION_SCALC_DOC
+{
+ Text = "StarCalc 3.0 - 5.0" ;
+};
+String STR_DESCRIPTION_SIMPRESS_DOC
+{
+ Text = "StarImpress 4.0 / 5.0" ;
+};
+String STR_DESCRIPTION_SWRITER_DOC
+{
+ Text = "StarWriter 3.0 - 5.0" ;
+};
+String STR_DESCRIPTION_GLOBALDOC
+{
+ Text [ en-US ] = "StarWriter 4.0 / 5.0 Master Document" ;
+};
+String STR_DESCRIPTION_SIMAGE_DOC
+{
+ Text [ en-US ] = "%STAROFFICE Image" ;
+};
+String STR_DESCRIPTION_TEXTFILE
+{
+ Text [ en-US ] = "Text file" ;
+};
+String STR_DESCRIPTION_LINK
+{
+ Text [ en-US ] = "Link" ;
+};
+String STR_DESCRIPTION_SOFFICE_TEMPLATE_DOC
+{
+ Text [ en-US ] = "%STAROFFICE 3.0 - 5.0 Template" ;
+};
+String STR_DESCRIPTION_EXCEL_DOC
+{
+ Text [ en-US ] = "MS Excel document" ;
+};
+String STR_DESCRIPTION_EXCEL_TEMPLATE_DOC
+{
+ Text [ en-US ] = "MS Excel template" ;
+};
+String STR_DESCRIPTION_BATCHFILE
+{
+ Text [ en-US ] = "Batch file" ;
+};
+String STR_DESCRIPTION_FILE
+{
+ Text [ en-US ] = "File" ;
+};
+String STR_DESCRIPTION_FOLDER
+{
+ Text [ en-US ] = "Folder" ;
+};
+String STR_DESCRIPTION_FACTORY_WRITER
+{
+ Text [ en-US ] = "Text Document";
+};
+String STR_DESCRIPTION_FACTORY_CALC
+{
+ Text [ en-US ] = "Spreadsheet";
+};
+String STR_DESCRIPTION_FACTORY_IMPRESS
+{
+ Text [ en-US ] = "Presentation";
+};
+String STR_DESCRIPTION_FACTORY_DRAW
+{
+ Text [ en-US ] = "Drawing";
+};
+String STR_DESCRIPTION_FACTORY_WRITERWEB
+{
+ Text [ en-US ] = "HTML document";
+};
+String STR_DESCRIPTION_FACTORY_GLOBALDOC
+{
+ Text [ en-US ] = "Master document";
+};
+String STR_DESCRIPTION_FACTORY_MATH
+{
+ Text [ en-US ] = "Formula";
+};
+String STR_DESCRIPTION_FACTORY_DATABASE
+{
+ Text [ en-US ] = "Database";
+};
+String STR_DESCRIPTION_CALC_TEMPLATE
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Spreadsheet Template" ;
+};
+String STR_DESCRIPTION_DRAW_TEMPLATE
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Drawing Template" ;
+};
+String STR_DESCRIPTION_IMPRESS_TEMPLATE
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Presentation Template" ;
+};
+String STR_DESCRIPTION_WRITER_TEMPLATE
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Text Document Template" ;
+};
+String STR_DESCRIPTION_LOCALE_VOLUME
+{
+ Text [ en-US ] = "Local drive" ;
+};
+String STR_DESCRIPTION_FLOPPY_VOLUME
+{
+ Text [ en-US ] = "Disk drive" ;
+};
+String STR_DESCRIPTION_CDROM_VOLUME
+{
+ Text [ en-US ] = "CD-ROM drive" ;
+};
+String STR_DESCRIPTION_REMOTE_VOLUME
+{
+ Text [ en-US ] = "Network connection" ;
+};
+String STR_DESCRIPTION_POWERPOINT
+{
+ Text [ en-US ] = "MS PowerPoint Document";
+};
+
+String STR_DESCRIPTION_POWERPOINT_TEMPLATE
+{
+ Text [ en-US ] = "MS PowerPoint Template";
+};
+
+String STR_DESCRIPTION_POWERPOINT_SHOW
+{
+ Text [ en-US ] = "MS PowerPoint Show";
+};
+
+String STR_DESCRIPTION_SXMATH_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Formula" ;
+};
+
+String STR_DESCRIPTION_SXCHART_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Chart" ;
+};
+
+String STR_DESCRIPTION_SXDRAW_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Drawing" ;
+};
+
+String STR_DESCRIPTION_SXCALC_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Spreadsheet" ;
+};
+
+String STR_DESCRIPTION_SXIMPRESS_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Presentation" ;
+};
+
+String STR_DESCRIPTION_SXWRITER_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Text Document" ;
+};
+
+String STR_DESCRIPTION_SXGLOBAL_DOC
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Master Document" ;
+};
+String STR_DESCRIPTION_MATHML_DOC
+{
+ Text [ en-US ] = "MathML Document" ;
+};
+
+String STR_DESCRIPTION_OO_DATABASE_DOC
+{
+ Text [ en-US ] = "OpenDocument Database" ;
+};
+String STR_DESCRIPTION_OO_DRAW_DOC
+{
+ Text [ en-US ] = "OpenDocument Drawing" ;
+};
+String STR_DESCRIPTION_OO_MATH_DOC
+{
+ Text [ en-US ] = "OpenDocument Formula" ;
+};
+String STR_DESCRIPTION_OO_GLOBAL_DOC
+{
+ Text [ en-US ] = "OpenDocument Master Document" ;
+};
+String STR_DESCRIPTION_OO_IMPRESS_DOC
+{
+ Text [ en-US ] = "OpenDocument Presentation" ;
+};
+String STR_DESCRIPTION_OO_CALC_DOC
+{
+ Text [ en-US ] = "OpenDocument Spreadsheet" ;
+};
+String STR_DESCRIPTION_OO_WRITER_DOC
+{
+ Text [ en-US ] = "OpenDocument Text" ;
+};
+String STR_DESCRIPTION_OO_CALC_TEMPLATE
+{
+ Text [ en-US ] = "OpenDocument Spreadsheet Template" ;
+};
+String STR_DESCRIPTION_OO_DRAW_TEMPLATE
+{
+ Text [ en-US ] = "OpenDocument Drawing Template" ;
+};
+String STR_DESCRIPTION_OO_IMPRESS_TEMPLATE
+{
+ Text [ en-US ] = "OpenDocument Presentation Template" ;
+};
+String STR_DESCRIPTION_OO_WRITER_TEMPLATE
+{
+ Text [ en-US ] = "OpenDocument Text Template" ;
+};
+
+String STR_DESCRIPTION_EXTENSION
+{
+ Text [ en-US ] = "%PRODUCTNAME Extension" ;
+};
+
diff --git a/svtools/source/misc/imageresourceaccess.cxx b/svtools/source/misc/imageresourceaccess.cxx
new file mode 100644
index 000000000000..436c3f721833
--- /dev/null
+++ b/svtools/source/misc/imageresourceaccess.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_svtools.hxx"
+
+#ifndef SVTOOLS_SOURCE_MISC_IMAGERESOURCEACCESS_HXX
+#include "imageresourceaccess.hxx"
+#endif
+
+/** === begin UNO includes === **/
+#include <com/sun/star/io/NotConnectedException.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XStream.hpp>
+/** === end UNO includes === **/
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/stream.hxx>
+#include <unotools/streamwrap.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using namespace ::utl;
+ using namespace ::comphelper;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::graphic;
+
+ //====================================================================
+ //= StreamSupplier
+ //====================================================================
+ typedef ::cppu::WeakImplHelper2 < XStream
+ , XSeekable
+ > StreamSupplier_Base;
+ class StreamSupplier : public StreamSupplier_Base
+ {
+ private:
+ Reference< XInputStream > m_xInput;
+ Reference< XOutputStream > m_xOutput;
+ Reference< XSeekable > m_xSeekable;
+
+ public:
+ StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput );
+
+ protected:
+ // XStream
+ virtual Reference< XInputStream > SAL_CALL getInputStream( ) throw (RuntimeException);
+ virtual Reference< XOutputStream > SAL_CALL getOutputStream( ) throw (RuntimeException);
+
+ // XSeekable
+ virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int64 SAL_CALL getPosition( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int64 SAL_CALL getLength( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ };
+
+ //--------------------------------------------------------------------
+ StreamSupplier::StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput )
+ :m_xInput( _rxInput )
+ ,m_xOutput( _rxOutput )
+ {
+ m_xSeekable = m_xSeekable.query( m_xInput );
+ if ( !m_xSeekable.is() )
+ m_xSeekable = m_xSeekable.query( m_xOutput );
+ OSL_ENSURE( m_xSeekable.is(), "StreamSupplier::StreamSupplier: at least one of both must be seekable!" );
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInputStream > SAL_CALL StreamSupplier::getInputStream( ) throw (RuntimeException)
+ {
+ return m_xInput;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XOutputStream > SAL_CALL StreamSupplier::getOutputStream( ) throw (RuntimeException)
+ {
+ return m_xOutput;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL StreamSupplier::seek( ::sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException)
+ {
+ if ( !m_xSeekable.is() )
+ throw NotConnectedException();
+
+ m_xSeekable->seek( location );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Int64 SAL_CALL StreamSupplier::getPosition( ) throw (IOException, RuntimeException)
+ {
+ if ( !m_xSeekable.is() )
+ throw NotConnectedException();
+
+ return m_xSeekable->getPosition();
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Int64 SAL_CALL StreamSupplier::getLength( ) throw (IOException, RuntimeException)
+ {
+ if ( !m_xSeekable.is() )
+ throw NotConnectedException();
+
+ return m_xSeekable->getLength();
+ }
+
+ //====================================================================
+ //= GraphicAccess
+ //====================================================================
+ //--------------------------------------------------------------------
+ bool GraphicAccess::isSupportedURL( const ::rtl::OUString& _rURL )
+ {
+ if ( ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/" ) ) == 0 )
+ || ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:graphicrepository/" ) ) == 0 )
+ || ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:standardimage/" ) ) == 0 )
+ || ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.GraphicObject:" ) ) == 0 )
+ || ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.extension://" ) ) == 0 )
+ )
+ return true;
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ SvStream* GraphicAccess::getImageStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
+ {
+ SvStream* pReturn = NULL;
+
+ try
+ {
+ // get a GraphicProvider
+ Reference< XGraphicProvider > xProvider;
+ if ( _rxORB.is() )
+ xProvider = xProvider.query( _rxORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ) );
+ OSL_ENSURE( xProvider.is(), "GraphicAccess::getImageStream: could not create a graphic provider!" );
+
+ if ( !xProvider.is() )
+ return pReturn;
+
+ // let it create a graphic from the given URL
+ Sequence< PropertyValue > aMediaProperties( 1 );
+ aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ aMediaProperties[0].Value <<= _rImageResourceURL;
+ Reference< XGraphic > xGraphic( xProvider->queryGraphic( aMediaProperties ) );
+ OSL_ENSURE( xGraphic.is(), "GraphicAccess::getImageStream: the provider did not give us a graphic object!" );
+ if ( !xGraphic.is() )
+ return pReturn;
+
+ // copy the graphic to a in-memory buffer
+ SvMemoryStream* pMemBuffer = new SvMemoryStream;
+ Reference< XStream > xBufferAccess = new StreamSupplier(
+ new OSeekableInputStreamWrapper( *pMemBuffer ),
+ new OSeekableOutputStreamWrapper( *pMemBuffer )
+ );
+
+ aMediaProperties.realloc( 2 );
+ aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
+ aMediaProperties[0].Value <<= xBufferAccess;
+ aMediaProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) );
+ aMediaProperties[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
+ xProvider->storeGraphic( xGraphic, aMediaProperties );
+
+ pMemBuffer->Seek( 0 );
+ pReturn = pMemBuffer;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "GraphicAccess::getImageStream: caught an exception!" );
+ }
+
+ return pReturn;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInputStream > GraphicAccess::getImageXStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
+ {
+ return new OSeekableInputStreamWrapper( getImageStream( _rxORB, _rImageResourceURL ), sal_True ); // take ownership
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
diff --git a/svtools/source/misc/imap.cxx b/svtools/source/misc/imap.cxx
new file mode 100644
index 000000000000..25f23e2ef00b
--- /dev/null
+++ b/svtools/source/misc/imap.cxx
@@ -0,0 +1,1232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/window.hxx>
+
+#include "svl/urihelper.hxx"
+#include <svtools/imap.hxx>
+#include <svtools/imapobj.hxx>
+#include <svtools/imapcirc.hxx>
+#include <svtools/imaprect.hxx>
+#include <svtools/imappoly.hxx>
+
+#include <string.h>
+#include <math.h>
+
+DBG_NAME( ImageMap )
+
+
+#define SCALEPOINT(aPT,aFracX,aFracY) (aPT).X()=((aPT).X()*(aFracX).GetNumerator())/(aFracX).GetDenominator(); \
+ (aPT).Y()=((aPT).Y()*(aFracY).GetNumerator())/(aFracY).GetDenominator();
+
+
+/******************************************************************************/
+
+UINT16 IMapObject::nActualTextEncoding = (UINT16) RTL_TEXTENCODING_DONTKNOW;
+
+/******************************************************************************/
+
+
+#ifdef WIN
+#pragma optimize ( "", off )
+#endif
+
+IMapObject::IMapObject()
+ : bActive( false )
+ , nReadVersion( 0 )
+{
+}
+
+IMapObject::IMapObject( const String& rURL, const String& rAltText, const String& rDesc,
+ const String& rTarget, const String& rName, BOOL bURLActive )
+: aURL( rURL )
+, aAltText( rAltText )
+, aDesc( rDesc )
+, aTarget( rTarget )
+, aName( rName )
+, bActive( bURLActive )
+, nReadVersion( 0 )
+{
+}
+
+
+/******************************************************************************
+|*
+|* Freigabe des internen Speichers
+|*
+\******************************************************************************/
+
+UINT16 IMapObject::GetVersion() const
+{
+ return IMAP_OBJ_VERSION;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapObject::Write( SvStream& rOStm, const String& rBaseURL ) const
+{
+ IMapCompat* pCompat;
+ const rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding();
+
+ rOStm << GetType();
+ rOStm << GetVersion();
+ rOStm << ( (UINT16) eEncoding );
+
+ const ByteString aRelURL = ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), eEncoding );
+ rOStm.WriteByteString( aRelURL );
+ rOStm.WriteByteString( ByteString( aAltText, eEncoding ) );
+ rOStm << bActive;
+ rOStm.WriteByteString( ByteString( aTarget, eEncoding ) );
+
+ pCompat = new IMapCompat( rOStm, STREAM_WRITE );
+
+ WriteIMapObject( rOStm );
+ aEventList.Write( rOStm ); // V4
+ rOStm.WriteByteString( ByteString( aName, eEncoding ) ); // V5
+
+ delete pCompat;
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Import
+|*
+\******************************************************************************/
+
+void IMapObject::Read( SvStream& rIStm, const String& rBaseURL )
+{
+ IMapCompat* pCompat;
+ rtl_TextEncoding nTextEncoding;
+ ByteString aString;
+
+ // Typ und Version ueberlesen wir
+ rIStm.SeekRel( 2 );
+ rIStm >> nReadVersion;
+ rIStm >> nTextEncoding;
+ rIStm.ReadByteString( aString ); aURL = String( aString.GetBuffer(), nTextEncoding );
+ rIStm.ReadByteString( aString ); aAltText = String( aString.GetBuffer(), nTextEncoding );
+ rIStm >> bActive;
+ rIStm.ReadByteString( aString ); aTarget = String( aString.GetBuffer(), nTextEncoding );
+
+ // URL absolut machen
+ aURL = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), aURL, URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_UNAMBIGUOUS );
+ pCompat = new IMapCompat( rIStm, STREAM_READ );
+
+ ReadIMapObject( rIStm );
+
+ // ab Version 4 lesen wir eine EventListe
+ if ( nReadVersion >= 0x0004 )
+ {
+ aEventList.Read(rIStm);
+
+ // ab Version 5 kann ein Objektname vorhanden sein
+ if ( nReadVersion >= 0x0005 )
+ {
+ rIStm.ReadByteString( aString ); aName = String( aString.GetBuffer(), nTextEncoding );
+ }
+ }
+
+ delete pCompat;
+}
+
+
+/******************************************************************************
+|*
+|* Konvertierung der logischen Koordianten in Pixel
+|*
+\******************************************************************************/
+
+Point IMapObject::GetPixelPoint( const Point& rLogPoint )
+{
+ return Application::GetDefaultDevice()->LogicToPixel( rLogPoint, MapMode( MAP_100TH_MM ) );
+}
+
+
+/******************************************************************************
+|*
+|* Konvertierung der logischen Koordianten in Pixel
+|*
+\******************************************************************************/
+
+Point IMapObject::GetLogPoint( const Point& rPixelPoint )
+{
+ return Application::GetDefaultDevice()->PixelToLogic( rPixelPoint, MapMode( MAP_100TH_MM ) );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+BOOL IMapObject::IsEqual( const IMapObject& rEqObj )
+{
+ return ( ( aURL == rEqObj.aURL ) &&
+ ( aAltText == rEqObj.aAltText ) &&
+ ( aDesc == rEqObj.aDesc ) &&
+ ( aTarget == rEqObj.aTarget ) &&
+ ( aName == rEqObj.aName ) &&
+ ( bActive == rEqObj.bActive ) );
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+IMapRectangleObject::IMapRectangleObject( const Rectangle& rRect,
+ const String& rURL,
+ const String& rAltText,
+ const String& rDesc,
+ const String& rTarget,
+ const String& rName,
+ BOOL bURLActive,
+ BOOL bPixelCoords ) :
+ IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
+{
+ ImpConstruct( rRect, bPixelCoords );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapRectangleObject::ImpConstruct( const Rectangle& rRect, BOOL bPixel )
+{
+ if ( bPixel )
+ aRect = Application::GetDefaultDevice()->PixelToLogic( rRect, MapMode( MAP_100TH_MM ) );
+ else
+ aRect = rRect;
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Export
+|*
+\******************************************************************************/
+
+void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const
+{
+ rOStm << aRect;
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Import
+|*
+\******************************************************************************/
+
+void IMapRectangleObject::ReadIMapObject( SvStream& rIStm )
+{
+ rIStm >> aRect;
+}
+
+
+/******************************************************************************
+|*
+|* Typ-Rueckgabe
+|*
+\******************************************************************************/
+
+UINT16 IMapRectangleObject::GetType() const
+{
+ return IMAP_OBJ_RECTANGLE;
+}
+
+
+/******************************************************************************
+|*
+|* Hit-Test
+|*
+\******************************************************************************/
+
+BOOL IMapRectangleObject::IsHit( const Point& rPoint ) const
+{
+ return aRect.IsInside( rPoint );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Rectangle IMapRectangleObject::GetRectangle( BOOL bPixelCoords ) const
+{
+ Rectangle aNewRect;
+
+ if ( bPixelCoords )
+ aNewRect = Application::GetDefaultDevice()->LogicToPixel( aRect, MapMode( MAP_100TH_MM ) );
+ else
+ aNewRect = aRect;
+
+ return aNewRect;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapRectangleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
+{
+ Point aTL( aRect.TopLeft() );
+ Point aBR( aRect.BottomRight() );
+
+ if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
+ {
+ SCALEPOINT( aTL, rFracX, rFracY );
+ SCALEPOINT( aBR, rFracX, rFracY );
+ }
+
+ aRect = Rectangle( aTL, aBR );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+BOOL IMapRectangleObject::IsEqual( const IMapRectangleObject& rEqObj )
+{
+ return ( IMapObject::IsEqual( rEqObj ) && ( aRect == rEqObj.aRect ) );
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+IMapCircleObject::IMapCircleObject( const Point& rCenter, ULONG nCircleRadius,
+ const String& rURL,
+ const String& rAltText,
+ const String& rDesc,
+ const String& rTarget,
+ const String& rName,
+ BOOL bURLActive,
+ BOOL bPixelCoords ) :
+ IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
+{
+ ImpConstruct( rCenter, nCircleRadius, bPixelCoords );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapCircleObject::ImpConstruct( const Point& rCenter, ULONG nRad, BOOL bPixel )
+{
+ if ( bPixel )
+ {
+ MapMode aMap100( MAP_100TH_MM );
+
+ aCenter = Application::GetDefaultDevice()->PixelToLogic( rCenter, aMap100 );
+ nRadius = Application::GetDefaultDevice()->PixelToLogic( Size( nRad, 0 ), aMap100 ).Width();
+ }
+ else
+ {
+ aCenter = rCenter;
+ nRadius = nRad;
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Export
+|*
+\******************************************************************************/
+
+void IMapCircleObject::WriteIMapObject( SvStream& rOStm ) const
+{
+ UINT32 nTmp = nRadius;
+
+ rOStm << aCenter;
+ rOStm << nTmp;
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Import
+|*
+\******************************************************************************/
+
+void IMapCircleObject::ReadIMapObject( SvStream& rIStm )
+{
+ UINT32 nTmp;
+
+ rIStm >> aCenter;
+ rIStm >> nTmp;
+
+ nRadius = nTmp;
+}
+
+
+/******************************************************************************
+|*
+|* Typ-Rueckgabe
+|*
+\******************************************************************************/
+
+UINT16 IMapCircleObject::GetType() const
+{
+ return IMAP_OBJ_CIRCLE;
+}
+
+
+/******************************************************************************
+|*
+|* Hit-Test
+|*
+\******************************************************************************/
+
+BOOL IMapCircleObject::IsHit( const Point& rPoint ) const
+{
+ const Point aPoint( aCenter - rPoint );
+ BOOL bRet = FALSE;
+
+ if ( (ULONG) sqrt( (double) aPoint.X() * aPoint.X() +
+ aPoint.Y() * aPoint.Y() ) <= nRadius )
+ {
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Point IMapCircleObject::GetCenter( BOOL bPixelCoords ) const
+{
+ Point aNewPoint;
+
+ if ( bPixelCoords )
+ aNewPoint = Application::GetDefaultDevice()->LogicToPixel( aCenter, MapMode( MAP_100TH_MM ) );
+ else
+ aNewPoint = aCenter;
+
+ return aNewPoint;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+ULONG IMapCircleObject::GetRadius( BOOL bPixelCoords ) const
+{
+ ULONG nNewRadius;
+
+ if ( bPixelCoords )
+ nNewRadius = Application::GetDefaultDevice()->LogicToPixel( Size( nRadius, 0 ), MapMode( MAP_100TH_MM ) ).Width();
+ else
+ nNewRadius = nRadius;
+
+ return nNewRadius;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Rectangle IMapCircleObject::GetBoundRect() const
+{
+ long nWidth = nRadius << 1;
+
+ return Rectangle( Point( aCenter.X() - nRadius, aCenter.Y() - nRadius ),
+ Size( nWidth, nWidth ) );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapCircleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
+{
+ Fraction aAverage( rFracX );
+
+ aAverage += rFracY;
+ aAverage *= Fraction( 1, 2 );
+
+ if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
+ {
+ SCALEPOINT( aCenter, rFracX, rFracY );
+ }
+
+ nRadius = ( nRadius * aAverage.GetNumerator() ) / aAverage.GetDenominator();
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+BOOL IMapCircleObject::IsEqual( const IMapCircleObject& rEqObj )
+{
+ return ( IMapObject::IsEqual( rEqObj ) &&
+ ( aCenter == rEqObj.aCenter ) &&
+ ( nRadius == rEqObj.nRadius ) );
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+IMapPolygonObject::IMapPolygonObject( const Polygon& rPoly,
+ const String& rURL,
+ const String& rAltText,
+ const String& rDesc,
+ const String& rTarget,
+ const String& rName,
+ BOOL bURLActive,
+ BOOL bPixelCoords ) :
+ IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ),
+ bEllipse ( FALSE )
+{
+ ImpConstruct( rPoly, bPixelCoords );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::ImpConstruct( const Polygon& rPoly, BOOL bPixel )
+{
+ if ( bPixel )
+ aPoly = Application::GetDefaultDevice()->PixelToLogic( rPoly, MapMode( MAP_100TH_MM ) );
+ else
+ aPoly = rPoly;
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Export
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::WriteIMapObject( SvStream& rOStm ) const
+{
+ rOStm << aPoly;
+ rOStm << bEllipse; // >= Version 2
+ rOStm << aEllipse; // >= Version 2
+}
+
+
+/******************************************************************************
+|*
+|* Binaer-Import
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::ReadIMapObject( SvStream& rIStm )
+{
+ rIStm >> aPoly;
+
+ // Version >= 2 hat zusaetzlich Ellipsen-Information
+ if ( nReadVersion >= 2 )
+ {
+ rIStm >> bEllipse;
+ rIStm >> aEllipse;
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Typ-Rueckgabe
+|*
+\******************************************************************************/
+
+UINT16 IMapPolygonObject::GetType() const
+{
+ return IMAP_OBJ_POLYGON;
+}
+
+
+/******************************************************************************
+|*
+|* Hit-Test
+|*
+\******************************************************************************/
+
+BOOL IMapPolygonObject::IsHit( const Point& rPoint ) const
+{
+ return aPoly.IsInside( rPoint );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Polygon IMapPolygonObject::GetPolygon( BOOL bPixelCoords ) const
+{
+ Polygon aNewPoly;
+
+ if ( bPixelCoords )
+ aNewPoly = Application::GetDefaultDevice()->LogicToPixel( aPoly, MapMode( MAP_100TH_MM ) );
+ else
+ aNewPoly = aPoly;
+
+ return aNewPoly;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::SetExtraEllipse( const Rectangle& rEllipse )
+{
+ if ( aPoly.GetSize() )
+ {
+ bEllipse = TRUE;
+ aEllipse = rEllipse;
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
+{
+ USHORT nCount = aPoly.GetSize();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ Point aScaledPt( aPoly[ i ] );
+
+ if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
+ {
+ SCALEPOINT( aScaledPt, rFracX, rFracY );
+ }
+
+ aPoly[ i ] = aScaledPt;
+ }
+
+ if ( bEllipse )
+ {
+ Point aTL( aEllipse.TopLeft() );
+ Point aBR( aEllipse.BottomRight() );
+
+ if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
+ {
+ SCALEPOINT( aTL, rFracX, rFracY );
+ SCALEPOINT( aBR, rFracX, rFracY );
+ }
+
+ aEllipse = Rectangle( aTL, aBR );
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+BOOL IMapPolygonObject::IsEqual( const IMapPolygonObject& rEqObj )
+{
+ BOOL bRet = FALSE;
+
+ if ( IMapObject::IsEqual( rEqObj ) )
+ {
+ const Polygon& rEqPoly = rEqObj.aPoly;
+ const USHORT nCount = aPoly.GetSize();
+ const USHORT nEqCount = rEqPoly.GetSize();
+ BOOL bDifferent = FALSE;
+
+ if ( nCount == nEqCount )
+ {
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ if ( aPoly[ i ] != rEqPoly[ i ] )
+ {
+ bDifferent = TRUE;
+ break;
+ }
+ }
+
+ if ( !bDifferent )
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+
+/******************************************************************************
+|*
+|* Ctor
+|*
+\******************************************************************************/
+
+ImageMap::ImageMap( const String& rName ) :
+ aName ( rName )
+{
+}
+
+
+/******************************************************************************
+|*
+|* Copy-Ctor
+|*
+\******************************************************************************/
+
+ImageMap::ImageMap( const ImageMap& rImageMap )
+{
+ DBG_CTOR( ImageMap, NULL );
+
+ USHORT nCount = rImageMap.GetIMapObjectCount();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
+
+ switch( pCopyObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ maList.Insert( new IMapRectangleObject( *(IMapRectangleObject*) pCopyObj ), LIST_APPEND );
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ maList.Insert( new IMapCircleObject( *(IMapCircleObject*) pCopyObj ), LIST_APPEND );
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ maList.Insert( new IMapPolygonObject( *(IMapPolygonObject*) pCopyObj ), LIST_APPEND );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ aName = rImageMap.aName;
+}
+
+
+/******************************************************************************
+|*
+|* Dtor
+|*
+\******************************************************************************/
+
+ImageMap::~ImageMap()
+{
+ DBG_DTOR( ImageMap, NULL );
+
+ ClearImageMap();
+}
+
+
+/******************************************************************************
+|*
+|* Freigabe des internen Speichers
+|*
+\******************************************************************************/
+
+void ImageMap::ClearImageMap()
+{
+ IMapObject* pObj = (IMapObject*) maList.First();
+
+ while ( pObj )
+ {
+ delete pObj;
+ pObj = (IMapObject*) maList.Next();
+ }
+
+ maList.Clear();
+
+ aName = String();
+}
+
+
+/******************************************************************************
+|*
+|* Zuweisungsoperator
+|*
+\******************************************************************************/
+
+ImageMap& ImageMap::operator=( const ImageMap& rImageMap )
+{
+ USHORT nCount = rImageMap.GetIMapObjectCount();
+
+ ClearImageMap();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
+
+ switch( pCopyObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ maList.Insert( new IMapRectangleObject( *(IMapRectangleObject*) pCopyObj ), LIST_APPEND );
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ maList.Insert( new IMapCircleObject( *(IMapCircleObject*) pCopyObj ), LIST_APPEND );
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ maList.Insert( new IMapPolygonObject( *(IMapPolygonObject*) pCopyObj ), LIST_APPEND );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ aName = rImageMap.aName;
+
+ return *this;
+}
+
+
+/******************************************************************************
+|*
+|* Vergleichsoperator I
+|*
+\******************************************************************************/
+
+BOOL ImageMap::operator==( const ImageMap& rImageMap )
+{
+ const USHORT nCount = (USHORT) maList.Count();
+ const USHORT nEqCount = rImageMap.GetIMapObjectCount();
+ BOOL bRet = FALSE;
+
+ if ( nCount == nEqCount )
+ {
+ BOOL bDifferent = ( aName != rImageMap.aName );
+
+ for ( USHORT i = 0; ( i < nCount ) && !bDifferent; i++ )
+ {
+ IMapObject* pObj = (IMapObject*) maList.GetObject( i );
+ IMapObject* pEqObj = rImageMap.GetIMapObject( i );
+
+ if ( pObj->GetType() == pEqObj->GetType() )
+ {
+ switch( pObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ {
+ if ( !( (IMapRectangleObject*) pObj )->IsEqual( *(IMapRectangleObject*) pEqObj ) )
+ bDifferent = TRUE;
+ }
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ {
+ if ( !( (IMapCircleObject*) pObj )->IsEqual( *(IMapCircleObject*) pEqObj ) )
+ bDifferent = TRUE;
+ }
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ {
+ if ( !( (IMapPolygonObject*) pObj )->IsEqual( *(IMapPolygonObject*) pEqObj ) )
+ bDifferent = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ bDifferent = TRUE;
+ }
+
+ if ( !bDifferent )
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+
+/******************************************************************************
+|*
+|* Vergleichsoperator II
+|*
+\******************************************************************************/
+
+BOOL ImageMap::operator!=( const ImageMap& rImageMap )
+{
+ return !( *this == rImageMap );
+}
+
+
+/******************************************************************************
+|*
+|* Freigabe des internen Speichers
+|*
+\******************************************************************************/
+
+UINT16 ImageMap::GetVersion() const
+{
+ return IMAGE_MAP_VERSION;
+}
+
+
+/******************************************************************************
+|*
+|* Einfuegen eines neuen Objekts
+|*
+\******************************************************************************/
+
+void ImageMap::InsertIMapObject( const IMapObject& rIMapObject )
+{
+ switch( rIMapObject.GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ maList.Insert( new IMapRectangleObject( (IMapRectangleObject&) rIMapObject ), LIST_APPEND );
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ maList.Insert( new IMapCircleObject( (IMapCircleObject&) rIMapObject ), LIST_APPEND );
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ maList.Insert( new IMapPolygonObject( (IMapPolygonObject&) rIMapObject ), LIST_APPEND );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Hit-Test
+|*
+\******************************************************************************/
+
+IMapObject* ImageMap::GetHitIMapObject( const Size& rTotalSize,
+ const Size& rDisplaySize,
+ const Point& rRelHitPoint,
+ ULONG nFlags )
+{
+ Point aRelPoint( rTotalSize.Width() * rRelHitPoint.X() / rDisplaySize.Width(),
+ rTotalSize.Height() * rRelHitPoint.Y() / rDisplaySize.Height() );
+
+ // Falls Flags zur Spiegelung etc. angegeben sind, wird
+ // der zu pruefende Punkt vor der Pruefung entspr. transformiert
+ if ( nFlags )
+ {
+ if ( nFlags & IMAP_MIRROR_HORZ )
+ aRelPoint.X() = rTotalSize.Width() - aRelPoint.X();
+
+ if ( nFlags & IMAP_MIRROR_VERT )
+ aRelPoint.Y() = rTotalSize.Height() - aRelPoint.Y();
+ }
+
+ // Alle Objekte durchlaufen und HitTest ausfuehren
+ IMapObject* pObj = (IMapObject*) maList.First();
+ while ( pObj )
+ {
+ if ( pObj->IsHit( aRelPoint ) )
+ break;
+
+ pObj = (IMapObject*) maList.Next();
+ }
+
+ return( pObj ? ( pObj->IsActive() ? pObj : NULL ) : NULL );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Rectangle ImageMap::GetBoundRect() const
+{
+ Rectangle aBoundRect;
+ ULONG nCount = maList.Count();
+
+ for ( ULONG i = 0; i < nCount; i++ )
+ aBoundRect.Union( ( (IMapObject*) maList.GetObject( i ) )->GetBoundRect() );
+
+ return aBoundRect;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void ImageMap::Scale( const Fraction& rFracX, const Fraction& rFracY )
+{
+ USHORT nCount = (USHORT) maList.Count();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ IMapObject* pObj = GetIMapObject( i );
+
+ switch( pObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ ( (IMapRectangleObject*) pObj )->Scale( rFracX, rFracY );
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ ( (IMapCircleObject*) pObj )->Scale( rFracX, rFracY );
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ ( (IMapPolygonObject*) pObj )->Scale( rFracX, rFracY );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Objekte nacheinander wegschreiben
+|*
+\******************************************************************************/
+
+void ImageMap::ImpWriteImageMap( SvStream& rOStm, const String& rBaseURL ) const
+{
+ IMapObject* pObj;
+ USHORT nCount = (USHORT) maList.Count();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ pObj = (IMapObject*) maList.GetObject( i );
+ pObj->Write( rOStm, rBaseURL );
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Objekte nacheinander lesen
+|*
+\******************************************************************************/
+
+void ImageMap::ImpReadImageMap( SvStream& rIStm, USHORT nCount, const String& rBaseURL )
+{
+ // neue Objekte einlesen
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ UINT16 nType;
+
+ rIStm >> nType;
+ rIStm.SeekRel( -2 );
+
+ switch( nType )
+ {
+ case ( IMAP_OBJ_RECTANGLE ):
+ {
+ IMapRectangleObject* pObj = new IMapRectangleObject;
+ pObj->Read( rIStm, rBaseURL );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ break;
+
+ case ( IMAP_OBJ_CIRCLE ):
+ {
+ IMapCircleObject* pObj = new IMapCircleObject;
+ pObj->Read( rIStm, rBaseURL );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ break;
+
+ case ( IMAP_OBJ_POLYGON ):
+ {
+ IMapPolygonObject* pObj = new IMapPolygonObject;
+ pObj->Read( rIStm, rBaseURL );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Binaer speichern
+|*
+\******************************************************************************/
+
+void ImageMap::Write( SvStream& rOStm, const String& rBaseURL ) const
+{
+ IMapCompat* pCompat;
+ String aImageName( GetName() );
+ String aDummy;
+ USHORT nOldFormat = rOStm.GetNumberFormatInt();
+ UINT16 nCount = (UINT16) GetIMapObjectCount();
+ const rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding();
+
+ rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ // MagicCode schreiben
+ rOStm << IMAPMAGIC;
+ rOStm << GetVersion();
+ rOStm.WriteByteString( ByteString( aImageName, eEncoding ) );
+ rOStm.WriteByteString( ByteString( aDummy, eEncoding ) );
+ rOStm << nCount;
+ rOStm.WriteByteString( ByteString( aImageName, eEncoding ) );
+
+ pCompat = new IMapCompat( rOStm, STREAM_WRITE );
+
+ // hier kann in neueren Versionen eingefuegt werden
+
+ delete pCompat;
+
+ ImpWriteImageMap( rOStm, rBaseURL );
+
+ rOStm.SetNumberFormatInt( nOldFormat );
+}
+
+
+/******************************************************************************
+|*
+|* Binaer laden
+|*
+\******************************************************************************/
+
+void ImageMap::Read( SvStream& rIStm, const String& rBaseURL )
+{
+ ByteString aString;
+ char cMagic[6];
+ USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ UINT16 nCount;
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rIStm.Read( cMagic, sizeof( cMagic ) );
+
+ if ( !memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
+ {
+ IMapCompat* pCompat;
+
+ // alten Inhalt loeschen
+ ClearImageMap();
+
+ // Version ueberlesen wir
+ rIStm.SeekRel( 2 );
+
+ rIStm.ReadByteString( aString ); aName = String( aString, gsl_getSystemTextEncoding() );
+ rIStm.ReadByteString( aString ); // Dummy
+ rIStm >> nCount;
+ rIStm.ReadByteString( aString ); // Dummy
+
+ pCompat = new IMapCompat( rIStm, STREAM_READ );
+
+ // hier kann in neueren Versionen gelesen werden
+
+ delete pCompat;
+ ImpReadImageMap( rIStm, nCount, rBaseURL );
+
+ }
+ else
+ rIStm.SetError( SVSTREAM_GENERALERROR );
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+}
+
+
+#ifdef WIN
+#pragma optimize ( "", on )
+#endif
+
+
diff --git a/svtools/source/misc/imap2.cxx b/svtools/source/misc/imap2.cxx
new file mode 100644
index 000000000000..9834fe0fcb76
--- /dev/null
+++ b/svtools/source/misc/imap2.cxx
@@ -0,0 +1,757 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifdef WIN
+#include <sysdep.hxx>
+#endif
+#include <string.h>
+// #include <math.h>
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#ifndef _WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#include <sot/formats.hxx>
+
+#include "svl/urihelper.hxx"
+#include <svtools/imap.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/imapobj.hxx>
+#include <svtools/imaprect.hxx>
+#include <svtools/imapcirc.hxx>
+#include <svtools/imappoly.hxx>
+
+#ifdef WIN
+#include <sysdep.hxx>
+#endif
+#include <string.h>
+#include <math.h>
+
+#define NOTEOL(c) ((c)!='\0')
+
+
+TYPEINIT0_AUTOFACTORY( ImageMap );
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapObject::AppendCERNCoords( const Point& rPoint100, ByteString& rStr ) const
+{
+ const Point aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MAP_100TH_MM ) ) );
+
+ rStr += '(';
+ rStr += ByteString::CreateFromInt32( aPixPt.X() );
+ rStr += ',';
+ rStr += ByteString::CreateFromInt32( aPixPt.Y() );
+ rStr += ") ";
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapObject::AppendNCSACoords( const Point& rPoint100, ByteString& rStr ) const
+{
+ const Point aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MAP_100TH_MM ) ) );
+
+ rStr += ByteString::CreateFromInt32( aPixPt.X() );
+ rStr += ',';
+ rStr += ByteString::CreateFromInt32( aPixPt.Y() );
+ rStr += ' ';
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapObject::AppendCERNURL( ByteString& rStr, const String& rBaseURL ) const
+{
+ rStr += ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), gsl_getSystemTextEncoding() );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapObject::AppendNCSAURL( ByteString& rStr, const String& rBaseURL ) const
+{
+ rStr += ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), gsl_getSystemTextEncoding() );
+ rStr += ' ';
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapRectangleObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
+{
+ ByteString aStr( "rectangle " );
+
+ AppendCERNCoords( aRect.TopLeft(), aStr );
+ AppendCERNCoords( aRect.BottomRight(), aStr );
+ AppendCERNURL( aStr, rBaseURL );
+
+ rOStm.WriteLine( aStr );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapRectangleObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
+{
+ ByteString aStr( "rect " );
+
+ AppendNCSAURL( aStr, rBaseURL );
+ AppendNCSACoords( aRect.TopLeft(), aStr );
+ AppendNCSACoords( aRect.BottomRight(), aStr );
+
+ rOStm.WriteLine( aStr );
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapCircleObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
+{
+ ByteString aStr( "circle " );
+
+ AppendCERNCoords( aCenter, aStr );
+ aStr += ByteString::CreateFromInt32(nRadius);
+ aStr += ' ';
+ AppendCERNURL( aStr, rBaseURL );
+
+ rOStm.WriteLine( aStr );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapCircleObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
+{
+ ByteString aStr( "circle " );
+
+ AppendNCSAURL( aStr, rBaseURL );
+ AppendNCSACoords( aCenter, aStr );
+ AppendNCSACoords( aCenter + Point( nRadius, 0 ), aStr );
+
+ rOStm.WriteLine( aStr );
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
+{
+ ByteString aStr( "polygon " );
+ const USHORT nCount = aPoly.GetSize();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ AppendCERNCoords( aPoly[ i ], aStr );
+
+ AppendCERNURL( aStr, rBaseURL );
+
+ rOStm.WriteLine( aStr );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void IMapPolygonObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
+{
+ ByteString aStr( "poly " );
+ const USHORT nCount = Min( aPoly.GetSize(), (USHORT) 100 );
+
+ AppendNCSAURL( aStr, rBaseURL );
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ AppendNCSACoords( aPoly[ i ], aStr );
+
+ rOStm.WriteLine( aStr );
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void ImageMap::Write( SvStream& rOStm, ULONG nFormat, const String& rBaseURL ) const
+{
+ switch( nFormat )
+ {
+ case( IMAP_FORMAT_BIN ) : Write( rOStm, rBaseURL );
+ case( IMAP_FORMAT_CERN ) : ImpWriteCERN( rOStm, rBaseURL ); break;
+ case( IMAP_FORMAT_NCSA ) : ImpWriteNCSA( rOStm, rBaseURL ); break;
+
+ default:
+ break;
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void ImageMap::ImpWriteCERN( SvStream& rOStm, const String& rBaseURL ) const
+{
+ IMapObject* pObj;
+ USHORT nCount = (USHORT) maList.Count();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ pObj = GetIMapObject( i );
+
+ switch( pObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ ( (IMapRectangleObject*) pObj )->WriteCERN( rOStm, rBaseURL );
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ ( (IMapCircleObject*) pObj )->WriteCERN( rOStm, rBaseURL );
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ ( (IMapPolygonObject*) pObj )->WriteCERN( rOStm, rBaseURL );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void ImageMap::ImpWriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
+{
+ IMapObject* pObj;
+ USHORT nCount = (USHORT) maList.Count();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ pObj = GetIMapObject( i );
+
+ switch( pObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ ( (IMapRectangleObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
+ break;
+
+ case( IMAP_OBJ_CIRCLE ):
+ ( (IMapCircleObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
+ break;
+
+ case( IMAP_OBJ_POLYGON ):
+ ( (IMapPolygonObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+ULONG ImageMap::Read( SvStream& rIStm, ULONG nFormat, const String& rBaseURL )
+{
+ ULONG nRet = IMAP_ERR_FORMAT;
+
+ if ( nFormat == IMAP_FORMAT_DETECT )
+ nFormat = ImpDetectFormat( rIStm );
+
+ switch ( nFormat )
+ {
+ case ( IMAP_FORMAT_BIN ) : Read( rIStm, rBaseURL ); break;
+ case ( IMAP_FORMAT_CERN ) : nRet = ImpReadCERN( rIStm, rBaseURL ); break;
+ case ( IMAP_FORMAT_NCSA ) : nRet = ImpReadNCSA( rIStm, rBaseURL ); break;
+
+ default:
+ break;
+ }
+
+ if ( !rIStm.GetError() )
+ nRet = IMAP_ERR_OK;
+
+ return nRet;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+ULONG ImageMap::ImpReadCERN( SvStream& rIStm, const String& rBaseURL )
+{
+ ByteString aStr;
+
+ // alten Inhalt loeschen
+ ClearImageMap();
+
+ while ( rIStm.ReadLine( aStr ) )
+ ImpReadCERNLine( aStr, rBaseURL );
+
+ return IMAP_ERR_OK;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void ImageMap::ImpReadCERNLine( const ByteString& rLine, const String& rBaseURL )
+{
+ ByteString aStr( rLine );
+ ByteString aToken;
+
+ aStr.EraseLeadingChars( ' ' );
+ aStr.EraseLeadingChars( '\t' );
+ aStr.EraseAllChars( ';' );
+ aStr.ToLowerAscii();
+
+ const char* pStr = aStr.GetBuffer();
+ char cChar = *pStr++;
+
+ // Anweisung finden
+ while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) )
+ {
+ aToken += cChar;
+ cChar = *pStr++;
+ }
+
+ if ( NOTEOL( cChar ) )
+ {
+ if ( ( aToken == "rectangle" ) || ( aToken == "rect" ) )
+ {
+ const Point aTopLeft( ImpReadCERNCoords( &pStr ) );
+ const Point aBottomRight( ImpReadCERNCoords( &pStr ) );
+ const String aURL( ImpReadCERNURL( &pStr, rBaseURL ) );
+ const Rectangle aRect( aTopLeft, aBottomRight );
+
+ IMapRectangleObject* pObj = new IMapRectangleObject( aRect, aURL, String(), String(), String(), String() );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ else if ( ( aToken == "circle" ) || ( aToken == "circ" ) )
+ {
+ const Point aCenter( ImpReadCERNCoords( &pStr ) );
+ const long nRadius = ImpReadCERNRadius( &pStr );
+ const String aURL( ImpReadCERNURL( &pStr, rBaseURL ) );
+
+ IMapCircleObject* pObj = new IMapCircleObject( aCenter, nRadius, aURL, String(), String(), String(), String() );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ else if ( ( aToken == "polygon" ) || ( aToken == "poly" ) )
+ {
+ const USHORT nCount = aStr.GetTokenCount( '(' ) - 1;
+ Polygon aPoly( nCount );
+ String aURL;
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ aPoly[ i ] = ImpReadCERNCoords( &pStr );
+
+ aURL = ImpReadCERNURL( &pStr, rBaseURL );
+
+ IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, String(), String(), String(), String() );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Point ImageMap::ImpReadCERNCoords( const char** ppStr )
+{
+ String aStrX;
+ String aStrY;
+ Point aPt;
+ char cChar = *(*ppStr)++;
+
+ while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
+ cChar = *(*ppStr)++;
+
+ if ( NOTEOL( cChar ) )
+ {
+ while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
+ {
+ aStrX += cChar;
+ cChar = *(*ppStr)++;
+ }
+
+ if ( NOTEOL( cChar ) )
+ {
+ while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
+ cChar = *(*ppStr)++;
+
+ while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
+ {
+ aStrY += cChar;
+ cChar = *(*ppStr)++;
+ }
+
+ if ( NOTEOL( cChar ) )
+ while( NOTEOL( cChar ) && ( cChar != ')' ) )
+ cChar = *(*ppStr)++;
+
+ aPt = Point( aStrX.ToInt32(), aStrY.ToInt32() );
+ }
+ }
+
+ return aPt;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+long ImageMap::ImpReadCERNRadius( const char** ppStr )
+{
+ String aStr;
+ char cChar = *(*ppStr)++;
+
+ while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
+ cChar = *(*ppStr)++;
+
+ if ( NOTEOL( cChar ) )
+ {
+ while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
+ {
+ aStr += cChar;
+ cChar = *(*ppStr)++;
+ }
+ }
+
+ return aStr.ToInt32();
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+String ImageMap::ImpReadCERNURL( const char** ppStr, const String& rBaseURL )
+{
+ String aStr( String::CreateFromAscii( *ppStr ) );
+
+ aStr.EraseLeadingChars( ' ' );
+ aStr.EraseLeadingChars( '\t' );
+ aStr.EraseTrailingChars( ' ' );
+ aStr.EraseTrailingChars( '\t' );
+
+ return INetURLObject::GetAbsURL( rBaseURL, aStr );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+ULONG ImageMap::ImpReadNCSA( SvStream& rIStm, const String& rBaseURL )
+{
+ ByteString aStr;
+
+ // alten Inhalt loeschen
+ ClearImageMap();
+
+ while ( rIStm.ReadLine( aStr ) )
+ ImpReadNCSALine( aStr, rBaseURL );
+
+ return IMAP_ERR_OK;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+void ImageMap::ImpReadNCSALine( const ByteString& rLine, const String& rBaseURL )
+{
+ ByteString aStr( rLine );
+ ByteString aToken;
+
+ aStr.EraseLeadingChars( ' ' );
+ aStr.EraseLeadingChars( '\t' );
+ aStr.EraseAllChars( ';' );
+ aStr.ToLowerAscii();
+
+ const char* pStr = aStr.GetBuffer();
+ char cChar = *pStr++;
+
+ // Anweisung finden
+ while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) )
+ {
+ aToken += cChar;
+ cChar = *pStr++;
+ }
+
+ if ( NOTEOL( cChar ) )
+ {
+ if ( aToken == "rect" )
+ {
+ const String aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
+ const Point aTopLeft( ImpReadNCSACoords( &pStr ) );
+ const Point aBottomRight( ImpReadNCSACoords( &pStr ) );
+ const Rectangle aRect( aTopLeft, aBottomRight );
+
+ IMapRectangleObject* pObj = new IMapRectangleObject( aRect, aURL, String(), String(), String(), String() );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ else if ( aToken == "circle" )
+ {
+ const String aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
+ const Point aCenter( ImpReadNCSACoords( &pStr ) );
+ const Point aDX( aCenter - ImpReadNCSACoords( &pStr ) );
+ long nRadius = (long) sqrt( (double) aDX.X() * aDX.X() +
+ (double) aDX.Y() * aDX.Y() );
+
+ IMapCircleObject* pObj = new IMapCircleObject( aCenter, nRadius, aURL, String(), String(), String(), String() );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ else if ( aToken == "poly" )
+ {
+ const USHORT nCount = aStr.GetTokenCount( ',' ) - 1;
+ const String aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
+ Polygon aPoly( nCount );
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ aPoly[ i ] = ImpReadNCSACoords( &pStr );
+
+ IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, String(), String(), String(), String() );
+ maList.Insert( pObj, LIST_APPEND );
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+String ImageMap::ImpReadNCSAURL( const char** ppStr, const String& rBaseURL )
+{
+ String aStr;
+ char cChar = *(*ppStr)++;
+
+ while( NOTEOL( cChar ) && ( ( cChar == ' ' ) || ( cChar == '\t' ) ) )
+ cChar = *(*ppStr)++;
+
+ if ( NOTEOL( cChar ) )
+ {
+ while( NOTEOL( cChar ) && ( cChar != ' ' ) && ( cChar != '\t' ) )
+ {
+ aStr += cChar;
+ cChar = *(*ppStr)++;
+ }
+ }
+
+ return INetURLObject::GetAbsURL( rBaseURL, aStr );
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+Point ImageMap::ImpReadNCSACoords( const char** ppStr )
+{
+ String aStrX;
+ String aStrY;
+ Point aPt;
+ char cChar = *(*ppStr)++;
+
+ while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
+ cChar = *(*ppStr)++;
+
+ if ( NOTEOL( cChar ) )
+ {
+ while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
+ {
+ aStrX += cChar;
+ cChar = *(*ppStr)++;
+ }
+
+ if ( NOTEOL( cChar ) )
+ {
+ while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
+ cChar = *(*ppStr)++;
+
+ while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
+ {
+ aStrY += cChar;
+ cChar = *(*ppStr)++;
+ }
+
+ aPt = Point( aStrX.ToInt32(), aStrY.ToInt32() );
+ }
+ }
+
+ return aPt;
+}
+
+
+/******************************************************************************
+|*
+|*
+|*
+\******************************************************************************/
+
+ULONG ImageMap::ImpDetectFormat( SvStream& rIStm )
+{
+ ULONG nPos = rIStm.Tell();
+ ULONG nRet = IMAP_FORMAT_BIN;
+ char cMagic[6];
+
+ rIStm.Read( cMagic, sizeof( cMagic ) );
+
+ // Falls wir kein internes Format haben,
+ // untersuchen wir das Format
+ if ( memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
+ {
+ ByteString aStr;
+ long nCount = 128;
+
+ rIStm.Seek( nPos );
+ while ( rIStm.ReadLine( aStr ) && nCount-- )
+ {
+ aStr.ToLowerAscii();
+
+ if ( ( aStr.Search( "rect" ) != STRING_NOTFOUND ) ||
+ ( aStr.Search( "circ" ) != STRING_NOTFOUND ) ||
+ ( aStr.Search( "poly" ) != STRING_NOTFOUND ) )
+ {
+ if ( ( aStr.Search( '(' ) != STRING_NOTFOUND ) &&
+ ( aStr.Search( ')' ) != STRING_NOTFOUND ) )
+ {
+ nRet = IMAP_FORMAT_CERN;
+ }
+ else
+ nRet = IMAP_FORMAT_NCSA;
+
+ break;
+ }
+ }
+ }
+
+ rIStm.Seek( nPos );
+
+ return nRet;
+}
diff --git a/svtools/source/misc/imap3.cxx b/svtools/source/misc/imap3.cxx
new file mode 100644
index 000000000000..76763ae422f2
--- /dev/null
+++ b/svtools/source/misc/imap3.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_svtools.hxx"
+
+
+#include <svtools/imap.hxx>
+
+#include <tools/debug.hxx>
+
+
+/******************************************************************************
+|*
+|* Ctor
+|*
+\******************************************************************************/
+
+IMapCompat::IMapCompat( SvStream& rStm, const USHORT nStreamMode ) :
+ pRWStm ( &rStm ),
+ nStmMode ( nStreamMode )
+{
+ DBG_ASSERT( nStreamMode == STREAM_READ || nStreamMode == STREAM_WRITE, "Wrong Mode!" );
+
+ if ( !pRWStm->GetError() )
+ {
+ if ( nStmMode == STREAM_WRITE )
+ {
+ nCompatPos = pRWStm->Tell();
+ pRWStm->SeekRel( 4 );
+ nTotalSize = nCompatPos + 4;
+ }
+ else
+ {
+ UINT32 nTotalSizeTmp;
+ *pRWStm >> nTotalSizeTmp;
+ nTotalSize = nTotalSizeTmp;
+ nCompatPos = pRWStm->Tell();
+ }
+ }
+}
+
+
+/******************************************************************************
+|*
+|* Dtor
+|*
+\******************************************************************************/
+
+IMapCompat::~IMapCompat()
+{
+ if ( !pRWStm->GetError() )
+ {
+ if ( nStmMode == STREAM_WRITE )
+ {
+ const ULONG nEndPos = pRWStm->Tell();
+
+ pRWStm->Seek( nCompatPos );
+ *pRWStm << (UINT32) ( nEndPos - nTotalSize );
+ pRWStm->Seek( nEndPos );
+ }
+ else
+ {
+ const ULONG nReadSize = pRWStm->Tell() - nCompatPos;
+
+ if ( nTotalSize > nReadSize )
+ pRWStm->SeekRel( nTotalSize - nReadSize );
+ }
+ }
+}
+
+
+
diff --git a/svtools/source/misc/itemdel.cxx b/svtools/source/misc/itemdel.cxx
new file mode 100644
index 000000000000..559d31cdeb1d
--- /dev/null
+++ b/svtools/source/misc/itemdel.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_svtools.hxx"
+
+#include "itemdel.hxx"
+#include <vcl/svapp.hxx>
+#include <tools/errcode.hxx>
+#include <limits.h>
+
+#include <svtools/svtdata.hxx>
+#include <svl/svarray.hxx>
+#include <svl/itempool.hxx>
+
+// STATIC DATA -----------------------------------------------------------
+
+DBG_NAME(SfxItemDesruptor_Impl);
+
+// -----------------------------------------------------------------------
+
+class SfxItemDesruptor_Impl
+{
+ SfxPoolItem *pItem;
+ Link aLink;
+
+private:
+ DECL_LINK( Delete, void * );
+ SfxItemDesruptor_Impl( const SfxItemDesruptor_Impl& ); // n.i.
+
+public:
+ SfxItemDesruptor_Impl( SfxPoolItem *pItemToDesrupt );
+ ~SfxItemDesruptor_Impl();
+};
+
+SV_DECL_PTRARR( SfxItemDesruptorList_Impl, SfxItemDesruptor_Impl*, 4, 4 )
+
+// ------------------------------------------------------------------------
+SfxItemDesruptor_Impl::SfxItemDesruptor_Impl( SfxPoolItem *pItemToDesrupt ):
+ pItem(pItemToDesrupt),
+ aLink( LINK(this, SfxItemDesruptor_Impl, Delete) )
+{
+ DBG_CTOR(SfxItemDesruptor_Impl, 0);
+
+ DBG_ASSERT( 0 == pItem->GetRefCount(), "desrupting pooled item" );
+ pItem->SetKind( SFX_ITEMS_DELETEONIDLE );
+
+ // im Idle abarbeiten
+ GetpApp()->InsertIdleHdl( aLink, 1 );
+
+ // und in Liste eintragen (damit geflusht werden kann)
+ SfxItemDesruptorList_Impl* &rpList = ImpSvtData::GetSvtData().pItemDesruptList;
+ if ( !rpList )
+ rpList = new SfxItemDesruptorList_Impl;
+ const SfxItemDesruptor_Impl *pThis = this;
+ rpList->Insert( pThis, rpList->Count() );
+}
+
+// ------------------------------------------------------------------------
+SfxItemDesruptor_Impl::~SfxItemDesruptor_Impl()
+{
+ DBG_DTOR(SfxItemDesruptor_Impl, 0);
+
+ // aus Idle-Handler austragen
+ GetpApp()->RemoveIdleHdl( aLink );
+
+ // und aus Liste austragen
+ SfxItemDesruptorList_Impl* &rpList = ImpSvtData::GetSvtData().pItemDesruptList;
+ DBG_ASSERT( rpList, "no DesruptorList" );
+ const SfxItemDesruptor_Impl *pThis = this;
+ if ( rpList ) HACK(warum?)
+ rpList->Remove( rpList->GetPos(pThis) );
+
+ // reset RefCount (was set to SFX_ITEMS_SPECIAL before!)
+ pItem->SetRefCount( 0 );
+ //DBG_CHKOBJ( pItem, SfxPoolItem, 0 );
+ delete pItem;
+}
+
+// ------------------------------------------------------------------------
+IMPL_LINK( SfxItemDesruptor_Impl, Delete, void *, EMPTYARG )
+{
+ {DBG_CHKTHIS(SfxItemDesruptor_Impl, 0);}
+ delete this;
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+SfxPoolItem* DeleteItemOnIdle( SfxPoolItem* pItem )
+{
+ DBG_ASSERT( 0 == pItem->GetRefCount(), "deleting item in use" );
+ new SfxItemDesruptor_Impl( pItem );
+ return pItem;
+}
+
+// ------------------------------------------------------------------------
+void DeleteOnIdleItems()
+{
+ SfxItemDesruptorList_Impl* &rpList
+ = ImpSvtData::GetSvtData().pItemDesruptList;
+ if ( rpList )
+ {
+ USHORT n;
+ while ( 0 != ( n = rpList->Count() ) )
+ // Remove ist implizit im Dtor
+ delete rpList->GetObject( n-1 );
+ DELETEZ(rpList);
+ }
+}
+
+
diff --git a/svtools/source/misc/langtab.cxx b/svtools/source/misc/langtab.cxx
new file mode 100644
index 000000000000..d1ff94572a99
--- /dev/null
+++ b/svtools/source/misc/langtab.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+// include ---------------------------------------------------------------
+
+#include <tools/shl.hxx>
+#include <tools/debug.hxx>
+
+//#include <com/sun/star/i18n/XCharacterClassification.hpp>
+#include <com/sun/star/i18n/DirectionProperty.hpp>
+
+#include <i18npool/lang.h>
+#include <i18npool/mslangid.hxx>
+
+#include <svtools/svtools.hrc>
+#include <svtools/svtdata.hxx>
+#include <svtools/langtab.hxx>
+#include <unotools/syslocale.hxx>
+
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+SVT_DLLPUBLIC const String ApplyLreOrRleEmbedding( const String &rText )
+{
+ const USHORT nLen = rText.Len();
+ if (nLen == 0)
+ return String();
+
+ const sal_Unicode cLRE_Embedding = 0x202A; // the start char of an LRE embedding
+ const sal_Unicode cRLE_Embedding = 0x202B; // the start char of an RLE embedding
+ const sal_Unicode cPopDirectionalFormat = 0x202C; // the unicode PDF (POP_DIRECTIONAL_FORMAT) char that terminates an LRE/RLE embedding
+
+ // check if there are alreay embedding characters at the strings start
+ // if so change nothing
+ const sal_Unicode cChar = rText.GetBuffer()[0];
+ if (cChar == cLRE_Embedding || cChar == cRLE_Embedding)
+ return rText;
+
+ // since we only call the function getCharacterDirection
+ // it does not matter which locale the CharClass is for.
+ // Thus we can readily make use of SvtSysLocale::GetCharClass()
+ // which should come at no cost...
+ SvtSysLocale aSysLocale;
+ const CharClass &rCharClass = aSysLocale.GetCharClass();
+
+ // we should look for the first non-neutral LTR or RTL character
+ // and use that to determine the embedding of the whole text...
+ // Thus we can avoid to check every character of the text.
+ bool bFound = false;
+ bool bIsRtlText = false;
+ for (USHORT i = 0; i < nLen && !bFound; ++i)
+ {
+ sal_Int16 nDirection = rCharClass.getCharacterDirection( rText, i );
+ switch (nDirection)
+ {
+ case i18n::DirectionProperty_LEFT_TO_RIGHT :
+ case i18n::DirectionProperty_LEFT_TO_RIGHT_EMBEDDING :
+ case i18n::DirectionProperty_LEFT_TO_RIGHT_OVERRIDE :
+ case i18n::DirectionProperty_EUROPEAN_NUMBER :
+ case i18n::DirectionProperty_ARABIC_NUMBER : // yes! arabic numbers are written from left to right
+ {
+ bIsRtlText = false;
+ bFound = true;
+ break;
+ }
+
+ case i18n::DirectionProperty_RIGHT_TO_LEFT :
+ case i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC :
+ case i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING :
+ case i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE :
+ {
+ bIsRtlText = true;
+ bFound = true;
+ break;
+ }
+
+ default:
+ {
+ // nothing to be done, character is considered to be neutral we need to look further ...
+ }
+ }
+ }
+
+ sal_Unicode cStart = cLRE_Embedding; // default is to use LRE embedding characters
+ if (bIsRtlText)
+ cStart = cRLE_Embedding; // then use RLE embedding
+
+ // add embedding start and end chars to the text if the direction could be determined
+ String aRes( rText );
+ if (bFound)
+ {
+ aRes.Insert( cStart, 0 );
+ aRes.Insert( cPopDirectionalFormat );
+ }
+
+ return aRes;
+}
+
+//------------------------------------------------------------------------
+
+SvtLanguageTable::SvtLanguageTable() :
+ ResStringArray( SvtResId( STR_ARR_SVT_LANGUAGE_TABLE ) )
+{
+}
+
+//------------------------------------------------------------------------
+
+SvtLanguageTable::~SvtLanguageTable()
+{
+}
+
+//------------------------------------------------------------------------
+
+const String& SvtLanguageTable::GetString( const LanguageType eType ) const
+{
+ LanguageType eLang = MsLangId::getReplacementForObsoleteLanguage( eType);
+ sal_uInt32 nPos = FindIndex( eLang );
+
+ if ( RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count() )
+ return ResStringArray::GetString( nPos );
+ else
+ {
+ // If we knew what a simple "en" should alias to (en_US?) we could
+ // generally raise an error.
+ OSL_ENSURE(
+ eLang == LANGUAGE_ENGLISH, "language entry not found in resource" );
+
+ nPos = FindIndex( LANGUAGE_DONTKNOW );
+
+ if ( RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count() )
+ return ResStringArray::GetString( nPos );
+ }
+ static String aEmptyStr;
+ return aEmptyStr;
+}
+
+String SvtLanguageTable::GetLanguageString( const LanguageType eType )
+{
+ static const SvtLanguageTable aLangTable;
+ return aLangTable.GetString( eType );
+}
+
+//------------------------------------------------------------------------
+
+LanguageType SvtLanguageTable::GetType( const String& rStr ) const
+{
+ LanguageType eType = LANGUAGE_DONTKNOW;
+ sal_uInt32 nCount = Count();
+
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ if ( rStr == ResStringArray::GetString( i ) )
+ {
+ eType = LanguageType( GetValue( i ) );
+ break;
+ }
+ }
+ return eType;
+}
+
+//------------------------------------------------------------------------
+
+sal_uInt32 SvtLanguageTable::GetEntryCount() const
+{
+ return Count();
+}
+
+//------------------------------------------------------------------------
+
+LanguageType SvtLanguageTable::GetTypeAtIndex( sal_uInt32 nIndex ) const
+{
+ LanguageType nType = LANGUAGE_DONTKNOW;
+ if (nIndex < Count())
+ nType = LanguageType( GetValue( nIndex ) );
+ return nType;
+}
+
+//------------------------------------------------------------------------
+
diff --git a/svtools/source/misc/langtab.src b/svtools/source/misc/langtab.src
new file mode 100644
index 000000000000..067eb601a5af
--- /dev/null
+++ b/svtools/source/misc/langtab.src
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ // include ---------------------------------------------------------------
+#include <svtools/svtools.hrc>
+
+#define RSC_RESOURCE_USAGE 1
+#include <i18npool/lang.h>
+
+#define PairedList ItemList
+
+ // STR_ARR_SVT_LANGUAGE_TABLE ----------------------------------------------------
+StringArray STR_ARR_SVT_LANGUAGE_TABLE
+{
+ PairedList [ en-US ] =
+ {
+ < "[None]" ; LANGUAGE_NONE ; > ;
+ < "Unknown" ; LANGUAGE_DONTKNOW ; > ;
+ < "Default" ; LANGUAGE_SYSTEM ; > ;
+ < "Afrikaans (South Africa)" ; LANGUAGE_AFRIKAANS ; > ;
+ < "Albanian" ; LANGUAGE_ALBANIAN ; > ;
+ < "Arabic" ; LANGUAGE_ARABIC_PRIMARY_ONLY ; > ;
+ < "Arabic (Algeria)" ; LANGUAGE_ARABIC_ALGERIA ; > ;
+ < "Arabic (Bahrain)" ; LANGUAGE_ARABIC_BAHRAIN ; > ;
+ < "Arabic (Chad)" ; LANGUAGE_USER_ARABIC_CHAD ; > ;
+ < "Arabic (Comoros)" ; LANGUAGE_USER_ARABIC_COMOROS ; > ;
+ < "Arabic (Djibouti)" ; LANGUAGE_USER_ARABIC_DJIBOUTI ; > ;
+ < "Arabic (Egypt)" ; LANGUAGE_ARABIC_EGYPT ; > ;
+ < "Arabic (Eritrea)" ; LANGUAGE_USER_ARABIC_ERITREA ; > ;
+ < "Arabic (Iraq)" ; LANGUAGE_ARABIC_IRAQ ; > ;
+ < "Arabic (Israel)" ; LANGUAGE_USER_ARABIC_ISRAEL ; > ;
+ < "Arabic (Jordan)" ; LANGUAGE_ARABIC_JORDAN ; > ;
+ < "Arabic (Kuwait)" ; LANGUAGE_ARABIC_KUWAIT ; > ;
+ < "Arabic (Lebanon)" ; LANGUAGE_ARABIC_LEBANON ; > ;
+ < "Arabic (Libya)" ; LANGUAGE_ARABIC_LIBYA ; > ;
+ < "Arabic (Mauritania)" ; LANGUAGE_USER_ARABIC_MAURITANIA ; > ;
+ < "Arabic (Morocco)" ; LANGUAGE_ARABIC_MOROCCO ; > ;
+ < "Arabic (Oman)" ; LANGUAGE_ARABIC_OMAN ; > ;
+ < "Arabic (Palestine)" ; LANGUAGE_USER_ARABIC_PALESTINE ; > ;
+ < "Arabic (Qatar)" ; LANGUAGE_ARABIC_QATAR ; > ;
+ < "Arabic (Saudi Arabia)" ; LANGUAGE_ARABIC_SAUDI_ARABIA ; > ;
+ < "Arabic (Somalia)" ; LANGUAGE_USER_ARABIC_SOMALIA ; > ;
+ < "Arabic (Sudan)" ; LANGUAGE_USER_ARABIC_SUDAN ; > ;
+ < "Arabic (Syria)" ; LANGUAGE_ARABIC_SYRIA ; > ;
+ < "Arabic (Tunisia)" ; LANGUAGE_ARABIC_TUNISIA ; > ;
+ < "Arabic (UAE)" ; LANGUAGE_ARABIC_UAE ; > ;
+ < "Arabic (Yemen)" ; LANGUAGE_ARABIC_YEMEN ; > ;
+ < "Armenian" ; LANGUAGE_ARMENIAN ; > ;
+ < "Assami" ; LANGUAGE_ASSAMESE ; > ;
+ < "Azerbaijani Latin" ; LANGUAGE_AZERI_LATIN ; > ;
+ < "Azerbaijani Cyrillic" ; LANGUAGE_AZERI_CYRILLIC ; > ;
+ < "Basque" ; LANGUAGE_BASQUE ; > ;
+ < "Bengali (India)" ; LANGUAGE_BENGALI ; > ;
+ < "Bulgarian" ; LANGUAGE_BULGARIAN ; > ;
+ < "Belarusian" ; LANGUAGE_BELARUSIAN ; > ;
+ < "Catalan" ; LANGUAGE_CATALAN ; > ;
+ < "Chinese (traditional)" ; LANGUAGE_CHINESE_TRADITIONAL ; > ;
+ < "Chinese (simplified)" ; LANGUAGE_CHINESE_SIMPLIFIED ; > ;
+ < "Chinese (Hong Kong)" ; LANGUAGE_CHINESE_HONGKONG ; > ;
+ < "Chinese (Singapore)" ; LANGUAGE_CHINESE_SINGAPORE ; > ;
+ < "Chinese (Macau)" ; LANGUAGE_CHINESE_MACAU ; > ;
+ < "Croatian" ; LANGUAGE_CROATIAN ; > ;
+ < "Czech" ; LANGUAGE_CZECH ; > ;
+ < "Danish" ; LANGUAGE_DANISH ; > ;
+ < "Dutch (Netherlands)" ; LANGUAGE_DUTCH ; > ;
+ < "Dutch (Belgium)" ; LANGUAGE_DUTCH_BELGIAN ; > ;
+ < "English (USA)" ; LANGUAGE_ENGLISH_US ; > ;
+ < "English (UK)" ; LANGUAGE_ENGLISH_UK ; > ;
+ < "English (Australia)" ; LANGUAGE_ENGLISH_AUS ; > ;
+ < "English (Canada)" ; LANGUAGE_ENGLISH_CAN ; > ;
+ < "English (New Zealand)" ; LANGUAGE_ENGLISH_NZ ; > ;
+ < "English (Eire)" ; LANGUAGE_ENGLISH_EIRE ; > ;
+ < "English (South Africa)" ; LANGUAGE_ENGLISH_SAFRICA ; > ;
+ < "English (Jamaica)" ; LANGUAGE_ENGLISH_JAMAICA ; > ;
+ < "English (Caribbean)" ; LANGUAGE_ENGLISH_CARRIBEAN ; > ;
+ < "English (Belize)" ; LANGUAGE_ENGLISH_BELIZE ; > ;
+ < "English (Trinidad)" ; LANGUAGE_ENGLISH_TRINIDAD ; > ;
+ < "English (Zimbabwe)" ; LANGUAGE_ENGLISH_ZIMBABWE ; > ;
+ < "English (Philippines)" ; LANGUAGE_ENGLISH_PHILIPPINES ; > ;
+ < "English (India)" ; LANGUAGE_ENGLISH_INDIA ; > ;
+ < "Estonian" ; LANGUAGE_ESTONIAN ; > ;
+ < "Finnish" ; LANGUAGE_FINNISH ; > ;
+ < "Faroese" ; LANGUAGE_FAEROESE ; > ;
+ < "Farsi" ; LANGUAGE_FARSI ; > ;
+ < "French (France)" ; LANGUAGE_FRENCH ; > ;
+ < "French (Belgium)" ; LANGUAGE_FRENCH_BELGIAN ; > ;
+ < "French (Canada)" ; LANGUAGE_FRENCH_CANADIAN ; > ;
+ < "French (Switzerland)" ; LANGUAGE_FRENCH_SWISS ; > ;
+ < "French (Luxembourg)" ; LANGUAGE_FRENCH_LUXEMBOURG ; > ;
+ < "French (Monaco)" ; LANGUAGE_FRENCH_MONACO ; > ;
+ < "Gascon" ; LANGUAGE_USER_GASCON ; > ;
+ < "German (Germany)" ; LANGUAGE_GERMAN ; > ;
+ < "German (Switzerland)" ; LANGUAGE_GERMAN_SWISS ; > ;
+ < "German (Austria)" ; LANGUAGE_GERMAN_AUSTRIAN ; > ;
+ < "German (Luxembourg)" ; LANGUAGE_GERMAN_LUXEMBOURG ; > ;
+ < "German (Liechtenstein)" ; LANGUAGE_GERMAN_LIECHTENSTEIN ; > ;
+ < "Greek" ; LANGUAGE_GREEK ; > ;
+ < "Gujarati" ; LANGUAGE_GUJARATI ; > ;
+ < "Hebrew" ; LANGUAGE_HEBREW ; > ;
+ < "Hindi" ; LANGUAGE_HINDI ; > ;
+ < "Hungarian" ; LANGUAGE_HUNGARIAN ; > ;
+ < "Icelandic" ; LANGUAGE_ICELANDIC ; > ;
+ < "Indonesian" ; LANGUAGE_INDONESIAN ; > ;
+ < "Italian (Italy)" ; LANGUAGE_ITALIAN ; > ;
+ < "Italian (Switzerland)" ; LANGUAGE_ITALIAN_SWISS ; > ;
+ < "Japanese" ; LANGUAGE_JAPANESE ; > ;
+ < "Kannada" ; LANGUAGE_KANNADA ; > ;
+ < "Kashmiri (Kashmir)" ; LANGUAGE_KASHMIRI ; > ;
+ < "Kashmiri (India)" ; LANGUAGE_KASHMIRI_INDIA ; > ;
+ < "Kazak" ; LANGUAGE_KAZAK ; > ;
+ < "Konkani" ; LANGUAGE_KONKANI ; > ;
+ < "Korean (RoK)" ; LANGUAGE_KOREAN ; > ;
+ < "Latvian" ; LANGUAGE_LATVIAN ; > ;
+ < "Lithuanian" ; LANGUAGE_LITHUANIAN ; > ;
+ < "Macedonian" ; LANGUAGE_MACEDONIAN ; > ;
+ < "Malay (Malaysia)" ; LANGUAGE_MALAY_MALAYSIA ; > ;
+ < "Malay (Brunei Darussalam)" ; LANGUAGE_MALAY_BRUNEI_DARUSSALAM ; > ;
+ < "Malayalam" ; LANGUAGE_MALAYALAM ; > ;
+ < "Manipuri" ; LANGUAGE_MANIPURI ; > ;
+ < "Marathi" ; LANGUAGE_MARATHI ; > ;
+ < "Nepali (Nepal)" ; LANGUAGE_NEPALI ; > ;
+ < "Nepali (India)" ; LANGUAGE_NEPALI_INDIA ; > ;
+ < "Norwegian, Bokmål" ; LANGUAGE_NORWEGIAN_BOKMAL ; > ;
+ < "Norwegian, Nynorsk" ; LANGUAGE_NORWEGIAN_NYNORSK ; > ;
+ < "Oriya" ; LANGUAGE_ORIYA ; > ;
+ < "Polish" ; LANGUAGE_POLISH ; > ;
+ < "Portuguese (Portugal)" ; LANGUAGE_PORTUGUESE ; > ;
+ < "Portuguese (Brazil)" ; LANGUAGE_PORTUGUESE_BRAZILIAN ; > ;
+ < "Punjabi" ; LANGUAGE_PUNJABI ; > ;
+ < "Rhaeto-Romance" ; LANGUAGE_RHAETO_ROMAN ; > ;
+ < "Romanian" ; LANGUAGE_ROMANIAN ; > ;
+ < "Russian" ; LANGUAGE_RUSSIAN ; > ;
+ < "Sanskrit" ; LANGUAGE_SANSKRIT ; > ;
+ < "Serbian Cyrillic (Serbia and Montenegro)" ; LANGUAGE_SERBIAN_CYRILLIC ; > ;
+ < "Serbian Latin (Serbia and Montenegro)" ; LANGUAGE_SERBIAN_LATIN ; > ;
+ < "Serbian Cyrillic (Serbia)" ; LANGUAGE_USER_SERBIAN_CYRILLIC_SERBIA ; > ;
+ < "Serbian Latin (Serbia)" ; LANGUAGE_USER_SERBIAN_LATIN_SERBIA ; > ;
+ < "Serbian Cyrillic (Montenegro)" ; LANGUAGE_USER_SERBIAN_CYRILLIC_MONTENEGRO ; > ;
+ < "Serbian Latin (Montenegro)" ; LANGUAGE_USER_SERBIAN_LATIN_MONTENEGRO ; > ;
+ < "Sindhi" ; LANGUAGE_SINDHI ; > ;
+ < "Slovakian" ; LANGUAGE_SLOVAK ; > ;
+ < "Slovenian" ; LANGUAGE_SLOVENIAN ; > ;
+ < "Spanish (Spain)" ; LANGUAGE_SPANISH ; > ;
+ < "Spanish (Mexico)" ; LANGUAGE_SPANISH_MEXICAN ; > ;
+ < "Spanish (Guatemala)" ; LANGUAGE_SPANISH_GUATEMALA ; > ;
+ < "Spanish (Costa Rica)" ; LANGUAGE_SPANISH_COSTARICA ; > ;
+ < "Spanish (Panama)" ; LANGUAGE_SPANISH_PANAMA ; > ;
+ < "Spanish (Dom. Rep.)" ; LANGUAGE_SPANISH_DOMINICAN_REPUBLIC ; > ;
+ < "Spanish (Venezuela)" ; LANGUAGE_SPANISH_VENEZUELA ; > ;
+ < "Spanish (Colombia)" ; LANGUAGE_SPANISH_COLOMBIA ; > ;
+ < "Spanish (Peru)" ; LANGUAGE_SPANISH_PERU ; > ;
+ < "Spanish (Argentina)" ; LANGUAGE_SPANISH_ARGENTINA ; > ;
+ < "Spanish (Ecuador)" ; LANGUAGE_SPANISH_ECUADOR ; > ;
+ < "Spanish (Chile)" ; LANGUAGE_SPANISH_CHILE ; > ;
+ < "Spanish (Uruguay)" ; LANGUAGE_SPANISH_URUGUAY ; > ;
+ < "Spanish (Paraguay)" ; LANGUAGE_SPANISH_PARAGUAY ; > ;
+ < "Spanish (Bolivia)" ; LANGUAGE_SPANISH_BOLIVIA ; > ;
+ < "Spanish (El Salvador)" ; LANGUAGE_SPANISH_EL_SALVADOR ; > ;
+ < "Spanish (Honduras)" ; LANGUAGE_SPANISH_HONDURAS ; > ;
+ < "Spanish (Nicaragua)" ; LANGUAGE_SPANISH_NICARAGUA ; > ;
+ < "Spanish (Puerto Rico)" ; LANGUAGE_SPANISH_PUERTO_RICO ; > ;
+ < "Swahili (Kenya)" ; LANGUAGE_SWAHILI ; > ;
+ < "Swedish (Sweden)" ; LANGUAGE_SWEDISH ; > ;
+ < "Swedish (Finland)" ; LANGUAGE_SWEDISH_FINLAND ; > ;
+ < "Tajik" ; LANGUAGE_TAJIK ; > ;
+ < "Tamil" ; LANGUAGE_TAMIL ; > ;
+ < "Tatar" ; LANGUAGE_TATAR ; > ;
+ < "Telugu" ; LANGUAGE_TELUGU ; > ;
+ < "Thai" ; LANGUAGE_THAI ; > ;
+ < "Turkish" ; LANGUAGE_TURKISH ; > ;
+ < "Urdu (Pakistan)" ; LANGUAGE_URDU_PAKISTAN ; > ;
+ < "Urdu (India)" ; LANGUAGE_URDU_INDIA ; > ;
+ < "Ukrainian" ; LANGUAGE_UKRAINIAN ; > ;
+ < "Uzbek Latin" ; LANGUAGE_UZBEK_LATIN ; > ;
+ < "Welsh" ; LANGUAGE_WELSH ; > ;
+ < "User 1" ; LANGUAGE_USER1 ; > ;
+ < "User 2" ; LANGUAGE_USER2 ; > ;
+ < "User 3" ; LANGUAGE_USER3 ; > ;
+ < "User 4" ; LANGUAGE_USER4 ; > ;
+ < "User 5" ; LANGUAGE_USER5 ; > ;
+ < "User 6" ; LANGUAGE_USER6 ; > ;
+ < "User 7" ; LANGUAGE_USER7 ; > ;
+ < "User 8" ; LANGUAGE_USER8 ; > ;
+ < "User 9" ; LANGUAGE_USER9 ; > ;
+ < "Latin" ; LANGUAGE_LATIN ; > ;
+ < "Esperanto" ; LANGUAGE_USER_ESPERANTO ; > ;
+ < "Kinyarwanda (Rwanda)" ; LANGUAGE_USER_KINYARWANDA ; > ;
+ < "Maori (New Zealand)" ; LANGUAGE_MAORI_NEW_ZEALAND ; > ;
+ < "Galician" ; LANGUAGE_GALICIAN ; > ;
+ < "Dhivehi" ; LANGUAGE_DHIVEHI ; > ;
+ < "Northern Sotho" ; LANGUAGE_SEPEDI ; > ;
+ < "Gaelic (Scotland)" ; LANGUAGE_GAELIC_SCOTLAND ; > ;
+ < "Mongolian" ; LANGUAGE_MONGOLIAN ; > ;
+ < "Interlingua" ; LANGUAGE_USER_INTERLINGUA ; > ;
+ < "Bosnian" ; LANGUAGE_BOSNIAN_BOSNIA_HERZEGOVINA ; > ;
+ < "Bengali (Bangladesh)" ; LANGUAGE_BENGALI_BANGLADESH ; > ;
+ < "Occitan" ; LANGUAGE_USER_OCCITAN ; > ;
+ < "Khmer" ; LANGUAGE_KHMER ; > ;
+ < "Kurdish (Turkey)" ; LANGUAGE_USER_KURDISH_TURKEY ; > ;
+ < "Kurdish (Syria)" ; LANGUAGE_USER_KURDISH_SYRIA ; > ;
+ < "Kurdish (Iraq)" ; LANGUAGE_USER_KURDISH_IRAQ ; > ;
+ < "Kurdish (Iran)" ; LANGUAGE_USER_KURDISH_IRAN ; > ;
+ < "Sardinian" ; LANGUAGE_USER_SARDINIAN ; > ;
+ < "Dzongkha" ; LANGUAGE_DZONGKHA ; > ;
+ < "Swahili (Tanzania)" ; LANGUAGE_USER_SWAHILI_TANZANIA ; > ;
+ < "Lao" ; LANGUAGE_LAO ; > ;
+ < "Irish" ; LANGUAGE_GAELIC_IRELAND ; > ;
+ < "Tibetan (PR China)" ; LANGUAGE_TIBETAN ; > ;
+ < "Georgian" ; LANGUAGE_GEORGIAN ; > ;
+ < "Frisian" ; LANGUAGE_FRISIAN_NETHERLANDS ; > ;
+ < "Tswana (South Africa)" ; LANGUAGE_TSWANA ; > ;
+ < "Zulu" ; LANGUAGE_ZULU ; > ;
+ < "Vietnamese" ; LANGUAGE_VIETNAMESE ; > ;
+ < "Breton" ; LANGUAGE_USER_BRETON ; > ;
+ < "Kalaallisut" ; LANGUAGE_USER_KALAALLISUT ; > ;
+ < "Ndebele, South" ; LANGUAGE_USER_NDEBELE_SOUTH ; > ;
+ < "Southern Sotho" ; LANGUAGE_SESOTHO ; > ;
+ < "Swazi" ; LANGUAGE_USER_SWAZI ; > ;
+ < "Tsonga" ; LANGUAGE_TSONGA ; > ;
+ < "Venda" ; LANGUAGE_VENDA ; > ;
+ < "Tswana (Botswana)" ; LANGUAGE_USER_TSWANA_BOTSWANA ; > ;
+ < "Xhosa" ; LANGUAGE_XHOSA ; > ;
+ < "Sinhala" ; LANGUAGE_SINHALESE_SRI_LANKA ; > ;
+ < "Moore" ; LANGUAGE_USER_MOORE ; > ;
+ < "Bambara" ; LANGUAGE_USER_BAMBARA ; > ;
+ < "Akan" ; LANGUAGE_USER_AKAN ; > ;
+ < "Luxembourgish" ; LANGUAGE_USER_LUXEMBOURGISH ; > ;
+ < "Friulian" ; LANGUAGE_USER_FRIULIAN ; > ;
+ < "Fijian" ; LANGUAGE_USER_FIJIAN ; > ;
+ < "Afrikaans (Namibia)" ; LANGUAGE_USER_AFRIKAANS_NAMIBIA ; > ;
+ < "English (Namibia)" ; LANGUAGE_USER_ENGLISH_NAMIBIA ; > ;
+ < "Walloon" ; LANGUAGE_USER_WALLOON ; > ;
+ < "Coptic" ; LANGUAGE_USER_COPTIC ; > ;
+ < "Tigrigna (Eritrea)" ; LANGUAGE_TIGRIGNA_ERITREA ; > ;
+ < "Tigrigna (Ethiopia)" ; LANGUAGE_TIGRIGNA_ETHIOPIA ; > ;
+ < "Amharic" ; LANGUAGE_AMHARIC_ETHIOPIA ; > ;
+ < "Kirghiz" ; LANGUAGE_KIRGHIZ ; > ;
+ < "German (Belgium)" ; LANGUAGE_USER_GERMAN_BELGIUM ; > ;
+ < "Chuvash" ; LANGUAGE_USER_CHUVASH ; > ;
+ < "Burmese" ; LANGUAGE_BURMESE ; > ;
+ < "Hausa (Nigeria)" ; LANGUAGE_HAUSA_NIGERIA ; > ;
+ < "Hausa (Ghana)" ; LANGUAGE_USER_HAUSA_GHANA ; > ;
+ < "Éwé" ; LANGUAGE_USER_EWE_GHANA ; > ;
+ < "English (Ghana)" ; LANGUAGE_USER_ENGLISH_GHANA ; > ;
+ < "Sango" ; LANGUAGE_USER_SANGO ; > ;
+ < "Tagalog" ; LANGUAGE_USER_TAGALOG ; > ;
+ < "Ganda" ; LANGUAGE_USER_GANDA ; > ;
+ < "Lingala" ; LANGUAGE_USER_LINGALA_DRCONGO ; > ;
+ < "Low German" ; LANGUAGE_USER_LOW_GERMAN ; > ;
+ < "Hiligaynon" ; LANGUAGE_USER_HILIGAYNON ; > ;
+ < "Nyanja" ; LANGUAGE_USER_NYANJA ; > ;
+ < "Kashubian" ; LANGUAGE_USER_KASHUBIAN ; > ;
+ < "Spanish (Cuba)" ; LANGUAGE_USER_SPANISH_CUBA ; > ;
+ < "Tetun (Indonesia)" ; LANGUAGE_USER_TETUN ; > ;
+ < "Quechua (Bolivia, North)" ; LANGUAGE_USER_QUECHUA_NORTH_BOLIVIA ; > ;
+ < "Quechua (Bolivia, South)" ; LANGUAGE_USER_QUECHUA_SOUTH_BOLIVIA ; > ;
+ < "Somali" ; LANGUAGE_SOMALI ; > ;
+ < "Sami, Inari (Finland)" ; LANGUAGE_SAMI_INARI ; > ;
+ < "Sami, Lule (Norway)" ; LANGUAGE_SAMI_LULE_NORWAY ; > ;
+ < "Sami, Lule (Sweden)" ; LANGUAGE_SAMI_LULE_SWEDEN ; > ;
+ < "Sami, Northern (Finland)" ; LANGUAGE_SAMI_NORTHERN_FINLAND ; > ;
+ < "Sami, Northern (Norway)" ; LANGUAGE_SAMI_NORTHERN_NORWAY ; > ;
+ < "Sami, Northern (Sweden)" ; LANGUAGE_SAMI_NORTHERN_SWEDEN ; > ;
+ < "Sami, Skolt (Finland)" ; LANGUAGE_SAMI_SKOLT ; > ;
+ < "Sami, Southern (Norway)" ; LANGUAGE_SAMI_SOUTHERN_NORWAY ; > ;
+ < "Sami, Southern (Sweden)" ; LANGUAGE_SAMI_SOUTHERN_SWEDEN ; > ;
+ < "Sami, Kildin (Russia)" ; LANGUAGE_USER_SAMI_KILDIN_RUSSIA ; > ;
+ < "Guaraní, Paraguayan" ; LANGUAGE_GUARANI_PARAGUAY ; > ;
+ < "Bodo" ; LANGUAGE_USER_BODO_INDIA ; > ;
+ < "Dogri" ; LANGUAGE_USER_DOGRI_INDIA ; > ;
+ < "Maithili" ; LANGUAGE_USER_MAITHILI_INDIA ; > ;
+ < "Santali" ; LANGUAGE_USER_SANTALI_INDIA ; > ;
+ < "Tetun (Timor-Leste)" ; LANGUAGE_USER_TETUN_TIMOR_LESTE ; > ;
+ < "Turkmen" ; LANGUAGE_TURKMEN ; > ;
+ < "Maltese" ; LANGUAGE_MALTESE ; > ;
+ < "Tok Pisin" ; LANGUAGE_USER_TOK_PISIN ; > ;
+ < "Shuswap" ; LANGUAGE_USER_SHUSWAP ; > ;
+ < "Oromo" ; LANGUAGE_OROMO ; > ;
+ < "Greek, Ancient" ; LANGUAGE_USER_ANCIENT_GREEK ; > ;
+ < "Yiddish" ; LANGUAGE_YIDDISH ; > ;
+ < "Quechua (Ecuador)" ; LANGUAGE_QUECHUA_ECUADOR ; > ;
+ < "Uyghur" ; LANGUAGE_UIGHUR_CHINA ; > ;
+ < "Asturian" ; LANGUAGE_USER_ASTURIAN ; > ;
+ < "Sorbian, Upper" ; LANGUAGE_UPPER_SORBIAN_GERMANY ; > ;
+ < "Sorbian, Lower" ; LANGUAGE_LOWER_SORBIAN_GERMANY ; > ;
+ < "Latgalian" ; LANGUAGE_USER_LATGALIAN ; > ;
+ < "Maore" ; LANGUAGE_USER_MAORE ; > ;
+ < "Bushi" ; LANGUAGE_USER_BUSHI ; > ;
+ < "Tahitian" ; LANGUAGE_USER_TAHITIAN ; > ;
+ < "Malagasy, Plateau" ; LANGUAGE_USER_MALAGASY_PLATEAU ; > ;
+ < "Papiamentu (Netherlands Antilles)" ; LANGUAGE_PAPIAMENTU ; > ;
+ < "Papiamento (Aruba)" ; LANGUAGE_USER_PAPIAMENTU_ARUBA ; > ;
+ < "Sardinian, Campidanese" ; LANGUAGE_USER_SARDINIAN_CAMPIDANESE ; > ;
+ < "Sardinian, Gallurese" ; LANGUAGE_USER_SARDINIAN_GALLURESE ; > ;
+ < "Sardinian, Logudorese" ; LANGUAGE_USER_SARDINIAN_LOGUDORESE ; > ;
+ < "Sardinian, Sassarese" ; LANGUAGE_USER_SARDINIAN_SASSARESE ; > ;
+ < "Bafia" ; LANGUAGE_USER_BAFIA ; > ;
+ < "Gikuyu" ; LANGUAGE_USER_GIKUYU ; > ;
+ < "Yoruba" ; LANGUAGE_YORUBA ; > ;
+ < "Rusyn (Ukraine)" ; LANGUAGE_USER_RUSYN_UKRAINE ; > ;
+ < "Rusyn (Slovakia)" ; LANGUAGE_USER_RUSYN_SLOVAKIA ; > ;
+ };
+};
+
+// ********************************************************************** EOF
diff --git a/svtools/source/misc/makefile.mk b/svtools/source/misc/makefile.mk
new file mode 100755
index 000000000000..32781dbfefb1
--- /dev/null
+++ b/svtools/source/misc/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=svtools
+TARGET=misc
+
+ENABLE_EXCEPTIONS := TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+#use local "bmp" as it may not yet be delivered
+
+SRS1NAME=misc
+SRC1FILES=\
+ ehdl.src \
+ helpagent.src \
+ imagemgr.src \
+ langtab.src
+
+SRS2NAME=ehdl
+SRC2FILES=\
+ errtxt.src
+
+SLOFILES=\
+ $(SLO)$/acceleratorexecute.obj \
+ $(SLO)$/chartprettypainter.obj \
+ $(SLO)$/cliplistener.obj \
+ $(SLO)$/dialogclosedlistener.obj\
+ $(SLO)$/dialogcontrolling.obj \
+ $(SLO)$/ehdl.obj \
+ $(SLO)$/embedhlp.obj \
+ $(SLO)$/embedtransfer.obj \
+ $(SLO)$/helpagentwindow.obj \
+ $(SLO)$/imagemgr.obj \
+ $(SLO)$/imageresourceaccess.obj \
+ $(SLO)$/imap.obj \
+ $(SLO)$/imap2.obj \
+ $(SLO)$/imap3.obj \
+ $(SLO)$/itemdel.obj \
+ $(SLO)$/langtab.obj \
+ $(SLO)$/stringtransfer.obj \
+ $(SLO)$/svtaccessiblefactory.obj \
+ $(SLO)$/svtdata.obj \
+ $(SLO)$/templatefoldercache.obj \
+ $(SLO)$/transfer.obj \
+ $(SLO)$/transfer2.obj \
+ $(SLO)$/unitconv.obj \
+ $(SLO)$/wallitem.obj \
+ $(SLO)$/xwindowitem.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/misc/stringtransfer.cxx b/svtools/source/misc/stringtransfer.cxx
new file mode 100644
index 000000000000..fa216b27f99c
--- /dev/null
+++ b/svtools/source/misc/stringtransfer.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_svtools.hxx"
+#include <svtools/stringtransfer.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::datatransfer;
+
+ //====================================================================
+ //= OStringTransferable
+ //====================================================================
+ //--------------------------------------------------------------------
+ OStringTransferable::OStringTransferable(const ::rtl::OUString& _rContent)
+ :TransferableHelper()
+ ,m_sContent( _rContent )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void OStringTransferable::AddSupportedFormats()
+ {
+ AddFormat(SOT_FORMAT_STRING);
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool OStringTransferable::GetData( const DataFlavor& _rFlavor )
+ {
+ sal_uInt32 nFormat = SotExchange::GetFormat( _rFlavor );
+ if (SOT_FORMAT_STRING == nFormat)
+ return SetString( m_sContent, _rFlavor );
+
+ return sal_False;
+ }
+
+ //====================================================================
+ //= OStringTransfer
+ //====================================================================
+ //--------------------------------------------------------------------
+ void OStringTransfer::CopyString( const ::rtl::OUString& _rContent, Window* _pWindow )
+ {
+ OStringTransferable* pTransferable = new OStringTransferable( _rContent );
+ Reference< XTransferable > xTransfer = pTransferable;
+ pTransferable->CopyToClipboard( _pWindow );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool OStringTransfer::PasteString( ::rtl::OUString& _rContent, Window* _pWindow )
+ {
+ TransferableDataHelper aClipboardData = TransferableDataHelper::CreateFromSystemClipboard( _pWindow );
+
+ // check for a string format
+ const DataFlavorExVector& rFormats = aClipboardData.GetDataFlavorExVector();
+ for ( DataFlavorExVector::const_iterator aSearch = rFormats.begin();
+ aSearch != rFormats.end();
+ ++aSearch
+ )
+ {
+ if (SOT_FORMAT_STRING == aSearch->mnSotId)
+ {
+ String sContent;
+ sal_Bool bSuccess = aClipboardData.GetString( SOT_FORMAT_STRING, sContent );
+ _rContent = sContent;
+ return bSuccess;
+ }
+ }
+
+ return sal_False;
+ }
+
+ //--------------------------------------------------------------------
+ void OStringTransfer::StartStringDrag( const ::rtl::OUString& _rContent, Window* _pWindow, sal_Int8 _nDragSourceActions )
+ {
+ OStringTransferable* pTransferable = new OStringTransferable( _rContent );
+ Reference< XTransferable > xTransfer = pTransferable;
+ pTransferable->StartDrag(_pWindow, _nDragSourceActions);
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
diff --git a/svtools/source/misc/svtaccessiblefactory.cxx b/svtools/source/misc/svtaccessiblefactory.cxx
new file mode 100755
index 000000000000..b20863db3208
--- /dev/null
+++ b/svtools/source/misc/svtaccessiblefactory.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_svtools.hxx"
+#include "svtaccessiblefactory.hxx"
+#include <osl/module.h>
+
+// #define UNLOAD_ON_LAST_CLIENT_DYING
+ // this is not recommended currently. If enabled, the implementation will log
+ // the number of active clients, and unload the acc library when the last client
+ // goes away.
+ // Sounds like a good idea, unfortunately, there's no guarantee that all objects
+ // implemented in this library are already dead.
+ // Iow, just because an object implementing an XAccessible (implemented in this lib
+ // here) died, it's not said that everybody released all references to the
+ // XAccessibleContext used by this component, and implemented in the acc lib.
+ // So we cannot really unload the lib.
+ //
+ // Alternatively, if the lib would us own "usage counting", i.e. every component
+ // implemented therein would affect a static ref count, the acc lib could care
+ // for unloading itself.
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::accessibility;
+
+ namespace
+ {
+#ifdef UNLOAD_ON_LAST_CLIENT_DYING
+ static oslInterlockedCount s_nAccessibleFactoryAccesss = 0;
+#endif // UNLOAD_ON_LAST_CLIENT_DYING
+ static oslModule s_hAccessibleImplementationModule = NULL;
+ static GetSvtAccessibilityComponentFactory s_pAccessibleFactoryFunc = NULL;
+ static ::rtl::Reference< IAccessibleFactory > s_pFactory;
+
+ //====================================================================
+ //= AccessibleDummyFactory
+ //====================================================================
+ class AccessibleDummyFactory : public IAccessibleFactory
+ {
+ public:
+ AccessibleDummyFactory();
+
+ protected:
+ virtual ~AccessibleDummyFactory();
+
+ private:
+ AccessibleDummyFactory( const AccessibleDummyFactory& ); // never implemented
+ AccessibleDummyFactory& operator=( const AccessibleDummyFactory& ); // never implemented
+
+ oslInterlockedCount m_refCount;
+
+ public:
+ // IReference
+ virtual oslInterlockedCount SAL_CALL acquire();
+ virtual oslInterlockedCount SAL_CALL release();
+
+ // IAccessibleFactory
+ virtual IAccessibleTabListBox*
+ createAccessibleTabListBox(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*rxParent*/,
+ SvHeaderTabListBox& /*rBox*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual IAccessibleBrowseBox*
+ createAccessibleBrowseBox(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/,
+ IAccessibleTableProvider& /*_rBrowseBox*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual table::IAccessibleTableControl*
+ createAccessibleTableControl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/,
+ table::IAccessibleTable& /*_rTable*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleIconChoiceCtrl(
+ SvtIconChoiceCtrl& /*_rIconCtrl*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_xParent*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleTabBar(
+ TabBar& /*_rTabBar*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
+ createAccessibleTextWindowContext(
+ VCLXWindow* /*pVclXWindow*/, TextEngine& /*rEngine*/, TextView& /*rView*/, bool /*bCompoundControlChild*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleTreeListBox(
+ SvTreeListBox& /*_rListBox*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_xParent*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleBrowseBoxHeaderBar(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*rxParent*/,
+ IAccessibleTableProvider& /*_rOwningTable*/,
+ AccessibleBrowseBoxObjType /*_eObjType*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleBrowseBoxTableCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/,
+ IAccessibleTableProvider& /*_rBrowseBox*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_xFocusWindow*/,
+ sal_Int32 /*_nRowId*/,
+ sal_uInt16 /*_nColId*/,
+ sal_Int32 /*_nOffset*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleBrowseBoxHeaderCell(
+ sal_Int32 /*_nColumnRowId*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*rxParent*/,
+ IAccessibleTableProvider& /*_rBrowseBox*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_xFocusWindow*/,
+ AccessibleBrowseBoxObjType /*_eObjType*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createAccessibleCheckBoxCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/,
+ IAccessibleTableProvider& /*_rBrowseBox*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_xFocusWindow*/,
+ sal_Int32 /*_nRowPos*/,
+ sal_uInt16 /*_nColPos*/,
+ const TriState& /*_eState*/,
+ sal_Bool /*_bEnabled*/,
+ sal_Bool /*_bIsTriState*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ createEditBrowseBoxTableCellAccess(
+ const ::com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessible >& /*_rxParent*/,
+ const ::com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessible >& /*_rxControlAccessible*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_rxFocusWindow*/,
+ IAccessibleTableProvider& /*_rBrowseBox*/,
+ sal_Int32 /*_nRowPos*/,
+ sal_uInt16 /*_nColPos*/
+ ) const
+ {
+ return NULL;
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
+ createAccessibleToolPanelDeck(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*i_rAccessibleParent*/,
+ ::svt::ToolPanelDeck& /*i_rPanelDeck*/
+ )
+ {
+ return NULL;
+ }
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
+ createAccessibleToolPanelTabBar(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*i_rAccessibleParent*/,
+ ::svt::IToolPanelDeck& /*i_rPanelDeck*/,
+ ::svt::PanelTabBar& /*i_rTabBar*/
+ )
+ {
+ return NULL;
+ }
+ };
+
+ //----------------------------------------------------------------
+ AccessibleDummyFactory::AccessibleDummyFactory()
+ {
+ }
+
+ //----------------------------------------------------------------
+ AccessibleDummyFactory::~AccessibleDummyFactory()
+ {
+ }
+
+ //----------------------------------------------------------------
+ oslInterlockedCount SAL_CALL AccessibleDummyFactory::acquire()
+ {
+ return osl_incrementInterlockedCount( &m_refCount );
+ }
+
+ //----------------------------------------------------------------
+ oslInterlockedCount SAL_CALL AccessibleDummyFactory::release()
+ {
+ if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
+ {
+ delete this;
+ return 0;
+ }
+ return m_refCount;
+ }
+ }
+
+ //====================================================================
+ //= AccessibleFactoryAccess
+ //====================================================================
+ //--------------------------------------------------------------------
+ AccessibleFactoryAccess::AccessibleFactoryAccess()
+ :m_bInitialized( false )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ extern "C" { static void SAL_CALL thisModule() {} }
+
+ void AccessibleFactoryAccess::ensureInitialized()
+ {
+ if ( m_bInitialized )
+ return;
+
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+
+#ifdef UNLOAD_ON_LAST_CLIENT_DYING
+ if ( 1 == osl_incrementInterlockedCount( &s_nAccessibleFactoryAccesss ) )
+ { // the first client
+#endif // UNLOAD_ON_LAST_CLIENT_DYING
+ // load the library implementing the factory
+ if ( !s_pFactory.get() )
+ {
+ const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii(
+ SVLIBRARY( "acc" )
+ );
+ s_hAccessibleImplementationModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 );
+ if ( s_hAccessibleImplementationModule != NULL )
+ {
+ const ::rtl::OUString sFactoryCreationFunc =
+ ::rtl::OUString::createFromAscii( "getSvtAccessibilityComponentFactory" );
+ s_pAccessibleFactoryFunc = (GetSvtAccessibilityComponentFactory)
+ osl_getFunctionSymbol( s_hAccessibleImplementationModule, sFactoryCreationFunc.pData );
+
+ }
+ OSL_ENSURE( s_pAccessibleFactoryFunc, "ac_registerClient: could not load the library, or not retrieve the needed symbol!" );
+
+ // get a factory instance
+ if ( s_pAccessibleFactoryFunc )
+ {
+ IAccessibleFactory* pFactory = static_cast< IAccessibleFactory* >( (*s_pAccessibleFactoryFunc)() );
+ if ( pFactory )
+ {
+ s_pFactory = pFactory;
+ pFactory->release();
+ }
+ }
+ }
+
+ if ( !s_pFactory.get() )
+ // the attempt to load the lib, or to create the factory, failed
+ // -> fall back to a dummy factory
+ s_pFactory = new AccessibleDummyFactory;
+#ifdef UNLOAD_ON_LAST_CLIENT_DYING
+ }
+#endif
+
+ m_bInitialized = true;
+ }
+
+ //--------------------------------------------------------------------
+ AccessibleFactoryAccess::~AccessibleFactoryAccess()
+ {
+ if ( m_bInitialized )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+
+#ifdef UNLOAD_ON_LAST_CLIENT_DYING
+ if( 0 == osl_decrementInterlockedCount( &s_nAccessibleFactoryAccesss ) )
+ {
+ s_pFactory = NULL;
+ s_pAccessibleFactoryFunc = NULL;
+ if ( s_hAccessibleImplementationModule )
+ {
+ osl_unloadModule( s_hAccessibleImplementationModule );
+ s_hAccessibleImplementationModule = NULL;
+ }
+ }
+#endif // UNLOAD_ON_LAST_CLIENT_DYING
+ }
+ }
+
+ //--------------------------------------------------------------------
+ IAccessibleFactory& AccessibleFactoryAccess::getFactory()
+ {
+ ensureInitialized();
+ DBG_ASSERT( s_pFactory.is(), "AccessibleFactoryAccess::getFactory: at least a dummy factory should have been created!" );
+ return *s_pFactory;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/misc/svtdata.cxx b/svtools/source/misc/svtdata.cxx
new file mode 100644
index 000000000000..65715f635883
--- /dev/null
+++ b/svtools/source/misc/svtdata.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_svtools.hxx"
+
+#include <map>
+#include <tools/resmgr.hxx>
+#include <tools/shl.hxx>
+#include <vos/process.hxx>
+#include <svtools/svtdata.hxx>
+#include <vcl/svapp.hxx>
+
+//============================================================================
+//
+// ImpSvtData
+//
+//============================================================================
+
+ImpSvtData::~ImpSvtData()
+{
+ delete pResMgr;
+}
+
+//============================================================================
+ResMgr * ImpSvtData::GetResMgr(const ::com::sun::star::lang::Locale aLocale)
+{
+ if (!pResMgr)
+ {
+ pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(svt), aLocale );
+ }
+ return pResMgr;
+}
+
+ResMgr * ImpSvtData::GetResMgr()
+{
+ return GetResMgr(Application::GetSettings().GetUILocale());
+}
+
+ResMgr * ImpSvtData::GetPatchResMgr(const ::com::sun::star::lang::Locale& aLocale)
+{
+ if (!pPatchResMgr)
+ {
+ pPatchResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(svp), aLocale);
+ }
+ return pPatchResMgr;
+}
+
+ResMgr * ImpSvtData::GetPatchResMgr()
+{
+ return GetPatchResMgr(Application::GetSettings().GetUILocale());
+}
+
+SvpResId::SvpResId( USHORT nId ) :
+ ResId( nId, *ImpSvtData::GetSvtData().GetPatchResMgr() )
+{
+}
+
+//============================================================================
+// static
+ImpSvtData & ImpSvtData::GetSvtData()
+{
+ void ** pAppData = GetAppData(SHL_SVT);
+ if (!*pAppData)
+ *pAppData= new ImpSvtData;
+ return *static_cast<ImpSvtData *>(*pAppData);
+}
+
diff --git a/svtools/source/misc/templatefoldercache.cxx b/svtools/source/misc/templatefoldercache.cxx
new file mode 100644
index 000000000000..62f3ec39eb6f
--- /dev/null
+++ b/svtools/source/misc/templatefoldercache.cxx
@@ -0,0 +1,919 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "templatefoldercache.hxx"
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+#include <ucbhelper/content.hxx>
+#include <vos/ref.hxx>
+#include <vos/refernce.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <unotools/pathoptions.hxx>
+
+#include "comphelper/processfactory.hxx"
+
+#include <vector>
+#include <list>
+#include <functional>
+#include <algorithm>
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+ using namespace ::utl;
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::com::sun::star::uno;
+
+ //=====================================================================
+ //= helpers
+ //=====================================================================
+ //---------------------------------------------------------------------
+ SvStream& operator << ( SvStream& _rStorage, const util::DateTime& _rDate )
+ {
+ _rStorage << _rDate.HundredthSeconds;
+ _rStorage << _rDate.Seconds;
+ _rStorage << _rDate.Minutes;
+ _rStorage << _rDate.Hours;
+ _rStorage << _rDate.Day;
+ _rStorage << _rDate.Month;
+ _rStorage << _rDate.Year;
+
+ return _rStorage;
+ }
+
+ //---------------------------------------------------------------------
+ SvStream& operator >> ( SvStream& _rStorage, util::DateTime& _rDate )
+ {
+ _rStorage >> _rDate.HundredthSeconds;
+ _rStorage >> _rDate.Seconds;
+ _rStorage >> _rDate.Minutes;
+ _rStorage >> _rDate.Hours;
+ _rStorage >> _rDate.Day;
+ _rStorage >> _rDate.Month;
+ _rStorage >> _rDate.Year;
+
+ return _rStorage;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool operator == ( const util::DateTime& _rLHS, const util::DateTime& _rRHS )
+ {
+ return _rLHS.HundredthSeconds == _rRHS.HundredthSeconds
+ && _rLHS.Seconds == _rRHS.Seconds
+ && _rLHS.Minutes == _rRHS.Minutes
+ && _rLHS.Hours == _rRHS.Hours
+ && _rLHS.Day == _rRHS.Day
+ && _rLHS.Month == _rRHS.Month
+ && _rLHS.Year == _rRHS.Year;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool operator != ( const util::DateTime& _rLHS, const util::DateTime& _rRHS )
+ {
+ return !( _rLHS == _rRHS );
+ }
+
+ //=====================================================================
+ //= TemplateContent
+ //=====================================================================
+ struct TemplateContent;
+ typedef ::std::vector< ::vos::ORef< TemplateContent > > TemplateFolderContent;
+ typedef TemplateFolderContent::const_iterator ConstFolderIterator;
+ typedef TemplateFolderContent::iterator FolderIterator;
+
+ /** a struct describing one content in one of the template dirs (or at least it's relevant aspects)
+ */
+ struct TemplateContent : public ::vos::OReference
+ {
+ public:
+
+ private:
+ INetURLObject m_aURL;
+ String m_sLocalName; // redundant - last segment of m_aURL
+ util::DateTime m_aLastModified; // date of last modification as reported by UCP
+ TemplateFolderContent m_aSubContents; // sorted (by name) list of the children
+
+ private:
+ inline void implResetDate( )
+ {
+ m_aLastModified.HundredthSeconds = m_aLastModified.Seconds = m_aLastModified.Minutes = m_aLastModified.Hours = 0;
+ m_aLastModified.Day = m_aLastModified.Month = m_aLastModified.Year = 0;
+ }
+
+ private:
+ ~TemplateContent();
+
+ public:
+ TemplateContent();
+ TemplateContent( const INetURLObject& _rURL );
+ TemplateContent( const INetURLObject& _rURL, const util::DateTime& _rLastModified );
+
+ // attribute access
+ inline String getName( ) const { return m_sLocalName; }
+ inline String getURL( ) const { return m_aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ); }
+ inline void setModDate( const util::DateTime& _rDate ) { m_aLastModified = _rDate; }
+ inline const util::DateTime& getModDate( ) const { return m_aLastModified; }
+
+ inline TemplateFolderContent& getSubContents() { return m_aSubContents; }
+ inline const TemplateFolderContent& getSubContents() const { return m_aSubContents; }
+
+ inline ConstFolderIterator begin() const { return m_aSubContents.begin(); }
+ inline ConstFolderIterator end() const { return m_aSubContents.end(); }
+ inline TemplateFolderContent::size_type
+ size() const { return m_aSubContents.size(); }
+
+ inline void push_back( const ::vos::ORef< TemplateContent >& _rxNewElement )
+ { m_aSubContents.push_back( _rxNewElement ); }
+ };
+
+ //---------------------------------------------------------------------
+ DBG_NAME( TemplateContent )
+
+ //---------------------------------------------------------------------
+ TemplateContent::TemplateContent()
+ {
+ DBG_CTOR( TemplateContent, NULL );
+ implResetDate();
+ }
+
+ //---------------------------------------------------------------------
+ TemplateContent::TemplateContent( const INetURLObject& _rURL )
+ :m_aURL( _rURL )
+ {
+ DBG_CTOR( TemplateContent, NULL );
+ DBG_ASSERT( INET_PROT_NOT_VALID != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" );
+ m_sLocalName = m_aURL.getName();
+ implResetDate();
+ }
+
+ //---------------------------------------------------------------------
+ TemplateContent::TemplateContent( const INetURLObject& _rURL, const util::DateTime& _rLastModified )
+ :m_aURL( _rURL )
+ ,m_aLastModified( _rLastModified )
+ {
+ DBG_CTOR( TemplateContent, NULL );
+ DBG_ASSERT( INET_PROT_NOT_VALID != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" );
+ m_sLocalName = m_aURL.getName();
+ }
+
+ //---------------------------------------------------------------------
+ TemplateContent::~TemplateContent()
+ {
+ DBG_DTOR( TemplateContent, NULL );
+ }
+
+ //=====================================================================
+ //= stl helpers
+ //=====================================================================
+ //---------------------------------------------------------------------
+ /// compares two TemplateContent by URL
+ struct TemplateContentURLLess
+ :public ::std::binary_function < ::vos::ORef< TemplateContent >
+ , ::vos::ORef< TemplateContent >
+ , bool
+ >
+ {
+ bool operator() ( const ::vos::ORef< TemplateContent >& _rxLHS, const ::vos::ORef< TemplateContent >& _rxRHS ) const
+ {
+ return _rxLHS->getURL() < _rxRHS->getURL()
+ ? true
+ : false;
+ }
+ };
+
+ //---------------------------------------------------------------------
+ /// sorts the sib contents of a TemplateFolderContent
+ struct SubContentSort : public ::std::unary_function< ::vos::ORef< TemplateContent >, void >
+ {
+ void operator() ( TemplateFolderContent& _rFolder ) const
+ {
+ // sort the directory by name
+ ::std::sort(
+ _rFolder.begin(),
+ _rFolder.end(),
+ TemplateContentURLLess()
+ );
+
+ // sort the sub directories by name
+ ::std::for_each(
+ _rFolder.begin(),
+ _rFolder.end(),
+ *this
+ );
+ }
+
+ void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const
+ {
+ if ( _rxContent.isValid() && _rxContent->size() )
+ {
+ operator()( _rxContent->getSubContents() );
+ }
+ }
+ };
+ //---------------------------------------------------------------------
+ /** does a deep compare of two template contents
+ */
+ struct TemplateContentEqual
+ :public ::std::binary_function < ::vos::ORef< TemplateContent >
+ , ::vos::ORef< TemplateContent >
+ , bool
+ >
+ {
+ //.................................................................
+ bool operator() (const ::vos::ORef< TemplateContent >& _rLHS, const ::vos::ORef< TemplateContent >& _rRHS )
+ {
+ if ( !_rLHS.isValid() || !_rRHS.isValid() )
+ {
+ DBG_ERROR( "TemplateContentEqual::operator(): invalid contents!" );
+ return true;
+ // this is not strictly true, in case only one is invalid - but this is a heavy error anyway
+ }
+
+ if ( _rLHS->getURL() != _rRHS->getURL() )
+ return false;
+
+ if ( _rLHS->getModDate() != _rRHS->getModDate() )
+ return false;
+
+ if ( _rLHS->getSubContents().size() != _rRHS->getSubContents().size() )
+ return false;
+
+ if ( _rLHS->getSubContents().size() )
+ { // there are children
+ // -> compare them
+ ::std::pair< FolderIterator, FolderIterator > aFirstDifferent = ::std::mismatch(
+ _rLHS->getSubContents().begin(),
+ _rLHS->getSubContents().end(),
+ _rRHS->getSubContents().begin(),
+ *this
+ );
+ if ( aFirstDifferent.first != _rLHS->getSubContents().end() )
+ return false;// the sub contents differ
+ }
+
+ return true;
+ }
+ };
+
+ //---------------------------------------------------------------------
+ /// base class for functors which act an an SvStream
+ struct StorageHelper
+ {
+ protected:
+ SvStream& m_rStorage;
+ StorageHelper( SvStream& _rStorage ) : m_rStorage( _rStorage ) { }
+ };
+
+ //---------------------------------------------------------------------
+ /// functor which allows storing a string
+ struct StoreString
+ :public ::std::unary_function< String, void >
+ ,public StorageHelper
+ {
+ StoreString( SvStream& _rStorage ) : StorageHelper( _rStorage ) { }
+
+ void operator() ( const String& _rString ) const
+ {
+ m_rStorage.WriteByteString( _rString );
+ }
+ };
+
+ //---------------------------------------------------------------------
+ /// functor which stores the local name of a TemplateContent
+ struct StoreLocalContentName
+ :public ::std::unary_function< ::vos::ORef< TemplateContent >, void >
+ ,public StoreString
+ {
+ StoreLocalContentName( SvStream& _rStorage ) : StoreString( _rStorage ) { }
+
+ void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const
+ {
+ DBG_ERRORFILE( "This method must not be used, the whole URL must be stored!" );
+
+ // use the base class operator with the local name of the content
+ StoreString::operator() ( _rxContent->getName() );
+ }
+ };
+
+ //---------------------------------------------------------------------
+ struct StoreContentURL
+ :public ::std::unary_function< ::vos::ORef< TemplateContent >, void >
+ ,public StoreString
+ {
+ uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+ StoreContentURL( SvStream& _rStorage,
+ const uno::Reference<
+ util::XOfficeInstallationDirectories > &
+ xOfficeInstDirs )
+ : StoreString( _rStorage ), m_xOfficeInstDirs( xOfficeInstDirs ) { }
+
+ void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const
+ {
+ // use the base class operator with the local name of the content
+ String sURL = _rxContent->getURL();
+ // #116281# Keep office installtion relocatable. Never store
+ // any direct references to office installation directory.
+ sURL = m_xOfficeInstDirs->makeRelocatableURL( sURL );
+ StoreString::operator() ( sURL );
+ }
+ };
+
+ //---------------------------------------------------------------------
+ /// functor which stores the complete content of a TemplateContent
+ struct StoreFolderContent
+ :public ::std::unary_function< ::vos::ORef< TemplateContent >, void >
+ ,public StorageHelper
+ {
+ uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+ public:
+ StoreFolderContent( SvStream& _rStorage,
+ const uno::Reference<
+ util::XOfficeInstallationDirectories > &
+ xOfficeInstDirs )
+ : StorageHelper( _rStorage ), m_xOfficeInstDirs( xOfficeInstDirs ) { }
+
+ //.................................................................
+ void operator() ( const TemplateContent& _rContent ) const
+ {
+ // store the info about this content
+ m_rStorage << _rContent.getModDate();
+
+ // store the info about the children
+ // the number
+ m_rStorage << (sal_Int32)_rContent.size();
+ // their URLs ( the local name is not enough, since URL might be not a hierarchical one, "expand:" for example )
+ ::std::for_each(
+ _rContent.getSubContents().begin(),
+ _rContent.getSubContents().end(),
+ StoreContentURL( m_rStorage, m_xOfficeInstDirs )
+ );
+ // their content
+ ::std::for_each(
+ _rContent.getSubContents().begin(),
+ _rContent.getSubContents().end(),
+ *this
+ );
+ }
+
+ //.................................................................
+ void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const
+ {
+ if ( _rxContent.isValid() )
+ {
+ operator()( *_rxContent );
+ }
+ }
+ };
+
+ //---------------------------------------------------------------------
+ /// functor which reads a complete TemplateContent instance
+ struct ReadFolderContent
+ :public ::std::unary_function< ::vos::ORef< TemplateContent >, void >
+ ,public StorageHelper
+ {
+ uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+ ReadFolderContent( SvStream& _rStorage,
+ const uno::Reference<
+ util::XOfficeInstallationDirectories > &
+ xOfficeInstDirs )
+ : StorageHelper( _rStorage ), m_xOfficeInstDirs( xOfficeInstDirs ) { }
+
+ //.................................................................
+ void operator() ( TemplateContent& _rContent ) const
+ {
+ // store the info about this content
+ util::DateTime aModDate;
+ m_rStorage >> aModDate;
+ _rContent.setModDate( aModDate );
+
+ // store the info about the children
+ // the number
+ sal_Int32 nChildren = 0;
+ m_rStorage >> nChildren;
+ TemplateFolderContent& rChildren = _rContent.getSubContents();
+ rChildren.resize( 0 );
+ rChildren.reserve( nChildren );
+ // initialize them with their (local) names
+ while ( nChildren-- )
+ {
+ String sURL;
+ m_rStorage.ReadByteString( sURL );
+ sURL = m_xOfficeInstDirs->makeAbsoluteURL( sURL );
+ INetURLObject aChildURL( sURL );
+ rChildren.push_back( new TemplateContent( aChildURL ) );
+ }
+
+ // their content
+ ::std::for_each(
+ _rContent.getSubContents().begin(),
+ _rContent.getSubContents().end(),
+ *this
+ );
+ }
+
+ //.................................................................
+ void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const
+ {
+ if ( _rxContent.isValid() )
+ {
+ operator()( *_rxContent );
+ }
+ }
+ };
+
+ //=====================================================================
+ //= TemplateFolderCacheImpl
+ //=====================================================================
+ class TemplateFolderCacheImpl
+ {
+ private:
+ TemplateFolderContent m_aPreviousState; // the current state of the template dirs (as found on the HD)
+ TemplateFolderContent m_aCurrentState; // the previous state of the template dirs (as found in the cache file)
+
+ osl::Mutex m_aMutex;
+ // will be lazy inited; never access directly; use getOfficeInstDirs().
+ uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+ SvStream* m_pCacheStream;
+ sal_Bool m_bNeedsUpdate : 1;
+ sal_Bool m_bKnowState : 1;
+ sal_Bool m_bValidCurrentState : 1;
+ sal_Bool m_bAutoStoreState : 1;
+
+ public:
+ TemplateFolderCacheImpl( sal_Bool _bAutoStoreState );
+ ~TemplateFolderCacheImpl( );
+
+ sal_Bool needsUpdate( sal_Bool _bForceCheck );
+ void storeState( sal_Bool _bForceRetrieval );
+
+ private:
+ void initTemplDirs( ::std::vector< String >& _rRootDirs );
+ sal_Bool openCacheStream( sal_Bool _bForRead );
+ void closeCacheStream( );
+
+ /// read the state of the dirs from the cache file
+ sal_Bool readPreviousState();
+ /// read the current state of the dirs
+ sal_Bool readCurrentState();
+
+ String implParseSmart( const String& _rPath );
+
+ sal_Bool implReadFolder( const ::vos::ORef< TemplateContent >& _rxRoot );
+
+ static String getCacheFileName();
+ static sal_Int32 getMagicNumber();
+ static void normalize( TemplateFolderContent& _rState );
+
+ // @return <TRUE/> if the states equal
+ static sal_Bool equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS );
+
+ // late initialize m_xOfficeInstDirs
+ uno::Reference< util::XOfficeInstallationDirectories > getOfficeInstDirs();
+ };
+
+ //---------------------------------------------------------------------
+ TemplateFolderCacheImpl::TemplateFolderCacheImpl( sal_Bool _bAutoStoreState )
+ :m_pCacheStream ( NULL )
+ ,m_bNeedsUpdate ( sal_True )
+ ,m_bKnowState ( sal_False )
+ ,m_bValidCurrentState ( sal_False )
+ ,m_bAutoStoreState ( _bAutoStoreState )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ TemplateFolderCacheImpl::~TemplateFolderCacheImpl( )
+ {
+ // store the current state if possible and required
+ if ( m_bValidCurrentState && m_bAutoStoreState )
+ storeState( sal_False );
+
+ closeCacheStream( );
+ }
+
+ //---------------------------------------------------------------------
+ sal_Int32 TemplateFolderCacheImpl::getMagicNumber()
+ {
+ sal_Int32 nMagic = 0;
+ ( nMagic += (sal_Int8)'T' ) <<= 4;
+ ( nMagic += (sal_Int8)'D' ) <<= 4;
+ ( nMagic += (sal_Int8)'S' ) <<= 4;
+ ( nMagic += (sal_Int8)'C' ) <<= 0;
+ return nMagic;
+ }
+
+ //---------------------------------------------------------------------
+ String TemplateFolderCacheImpl::getCacheFileName()
+ {
+ return String::CreateFromAscii( ".templdir.cache" );
+ }
+
+
+ //---------------------------------------------------------------------
+ void TemplateFolderCacheImpl::normalize( TemplateFolderContent& _rState )
+ {
+ SubContentSort()( _rState );
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCacheImpl::equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS )
+ {
+ if ( _rLHS.size() != _rRHS.size() )
+ return sal_False;
+
+ // as both arrays are sorted (by definition - this is a precondition of this method)
+ // we can simply go from the front to the back and compare the single elements
+
+ ::std::pair< ConstFolderIterator, ConstFolderIterator > aFirstDifferent = ::std::mismatch(
+ _rLHS.begin(),
+ _rLHS.end(),
+ _rRHS.begin(),
+ TemplateContentEqual()
+ );
+
+ return aFirstDifferent.first == _rLHS.end();
+ }
+
+ //---------------------------------------------------------------------
+ void TemplateFolderCacheImpl::storeState( sal_Bool _bForceRetrieval )
+ {
+ if ( !m_bValidCurrentState || _bForceRetrieval )
+ readCurrentState( );
+
+ if ( m_bValidCurrentState && openCacheStream( sal_False ) )
+ {
+ *m_pCacheStream << getMagicNumber();
+
+ // store the template root folders
+ // the size
+ *m_pCacheStream << (sal_Int32)m_aCurrentState.size();
+ // the complete URLs
+ ::std::for_each(
+ m_aCurrentState.begin(),
+ m_aCurrentState.end(),
+ StoreContentURL( *m_pCacheStream, getOfficeInstDirs() )
+ );
+
+ // the contents
+ ::std::for_each(
+ m_aCurrentState.begin(),
+ m_aCurrentState.end(),
+ StoreFolderContent( *m_pCacheStream, getOfficeInstDirs() )
+ );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ String TemplateFolderCacheImpl::implParseSmart( const String& _rPath )
+ {
+ INetURLObject aParser;
+ aParser.SetSmartProtocol( INET_PROT_FILE );
+ aParser.SetURL( _rPath, INetURLObject::WAS_ENCODED );
+ if ( INET_PROT_NOT_VALID == aParser.GetProtocol() )
+ {
+ String sURL;
+ LocalFileHelper::ConvertPhysicalNameToURL( _rPath, sURL );
+ aParser.SetURL( sURL, INetURLObject::WAS_ENCODED );
+ }
+ return aParser.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+
+ //---------------------------------------------------------------------
+ void TemplateFolderCacheImpl::closeCacheStream( )
+ {
+ DELETEZ( m_pCacheStream );
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCacheImpl::implReadFolder( const ::vos::ORef< TemplateContent >& _rxRoot )
+ {
+ try
+ {
+ // create a content for the current folder root
+ Reference< XResultSet > xResultSet;
+ Sequence< ::rtl::OUString > aContentProperties( 4);
+ aContentProperties[0] = ::rtl::OUString::createFromAscii( "Title" );
+ aContentProperties[1] = ::rtl::OUString::createFromAscii( "DateModified" );
+ aContentProperties[2] = ::rtl::OUString::createFromAscii( "DateCreated" );
+ aContentProperties[3] = ::rtl::OUString::createFromAscii( "IsFolder" );
+
+ // get the set of sub contents in the folder
+ try
+ {
+ Reference< XDynamicResultSet > xDynResultSet;
+
+ ::ucbhelper::Content aTemplateRoot( _rxRoot->getURL(), Reference< XCommandEnvironment >() );
+ xDynResultSet = aTemplateRoot.createDynamicCursor( aContentProperties, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS );
+ if ( xDynResultSet.is() )
+ xResultSet = xDynResultSet->getStaticResultSet();
+ }
+ catch( CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "TemplateFolderCacheImpl::implReadFolder: caught a CommandAbortedException!" );
+ return sal_False;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // collect the infos about the sub contents
+ if ( xResultSet.is() )
+ {
+ Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
+ Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
+
+ while ( xResultSet->next() )
+ {
+ INetURLObject aSubContentURL( xContentAccess->queryContentIdentifierString() );
+
+ // a new content instance
+ ::vos::ORef< TemplateContent > xChild = new TemplateContent( aSubContentURL );
+
+ // the modified date
+ xChild->setModDate( xRow->getTimestamp( 2 ) ); // date modified
+ if ( xRow->wasNull() )
+ xChild->setModDate( xRow->getTimestamp( 3 ) ); // fallback: date created
+
+ // push back this content
+ _rxRoot->push_back( xChild );
+
+ // is it a folder?
+ if ( xRow->getBoolean( 4 ) && !xRow->wasNull() )
+ { // yes -> step down
+ ConstFolderIterator aNextLevelRoot = _rxRoot->end();
+ --aNextLevelRoot;
+ implReadFolder( *aNextLevelRoot );
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "TemplateFolderCacheImpl::implReadFolder: caught an exception!" );
+ return sal_False;
+ }
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCacheImpl::readCurrentState()
+ {
+ // reset
+ m_bValidCurrentState = sal_False;
+ TemplateFolderContent aTemplateFolderContent;
+ m_aCurrentState.swap( aTemplateFolderContent );
+
+ // the template directories from the config
+ String aDirs = SvtPathOptions().GetTemplatePath();
+ sal_uInt16 nDirs = aDirs.GetTokenCount( ';' );
+
+ m_aCurrentState.reserve( nDirs );
+ // loop through all the root-level template folders
+ for ( sal_uInt16 i=0; i<nDirs; ++i)
+ {
+ // create a new entry
+ m_aCurrentState.push_back( new TemplateContent( INetURLObject( aDirs.GetToken( i, ';' ) ) ) );
+ TemplateFolderContent::iterator aCurrentRoot = m_aCurrentState.end();
+ --aCurrentRoot;
+
+ if ( !implReadFolder( *aCurrentRoot ) )
+ return sal_False;
+ }
+
+ // normalize the array (which basically means "sort it")
+ normalize( m_aCurrentState );
+
+ m_bValidCurrentState = sal_True;
+ return m_bValidCurrentState;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCacheImpl::readPreviousState()
+ {
+ DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::readPreviousState: not to be called without stream!" );
+
+ // reset
+ TemplateFolderContent aTemplateFolderContent;
+ m_aPreviousState.swap( aTemplateFolderContent );
+
+ // check the magic number
+ sal_Int32 nMagic = 0;
+ *m_pCacheStream >> nMagic;
+ DBG_ASSERT( getMagicNumber() == nMagic, "TemplateFolderCacheImpl::readPreviousState: invalid cache file!" );
+ if ( getMagicNumber() != nMagic )
+ return sal_False;
+
+ // the root directories
+ // their number
+ sal_Int32 nRootDirectories = 0;
+ *m_pCacheStream >> nRootDirectories;
+ // init empty TemplateContens with the URLs
+ m_aPreviousState.reserve( nRootDirectories );
+ while ( nRootDirectories-- )
+ {
+ String sURL;
+ m_pCacheStream->ReadByteString( sURL );
+ // #116281# Keep office installtion relocatable. Never store
+ // any direct references to office installation directory.
+ sURL = getOfficeInstDirs()->makeAbsoluteURL( sURL );
+ m_aPreviousState.push_back(
+ new TemplateContent( INetURLObject(sURL) ) );
+ }
+
+ // read the contents of the root folders
+ ::std::for_each(
+ m_aPreviousState.begin(),
+ m_aPreviousState.end(),
+ ReadFolderContent( *m_pCacheStream, getOfficeInstDirs() )
+ );
+
+ DBG_ASSERT( !m_pCacheStream->GetErrorCode(), "TemplateFolderCacheImpl::readPreviousState: unknown error during reading the state cache!" );
+
+ // normalize the array (which basically means "sort it")
+ normalize( m_aPreviousState );
+
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCacheImpl::openCacheStream( sal_Bool _bForRead )
+ {
+ // close any old stream instance
+ closeCacheStream( );
+
+ // get the storage directory
+ String sStorageURL = implParseSmart( SvtPathOptions().GetStoragePath() );
+ INetURLObject aStorageURL( sStorageURL );
+ if ( INET_PROT_NOT_VALID == aStorageURL.GetProtocol() )
+ {
+ DBG_ERROR( "TemplateFolderCacheImpl::openCacheStream: invalid storage path!" );
+ return sal_False;
+ }
+
+ // append our name
+ aStorageURL.Append( getCacheFileName() );
+
+ // open the stream
+ m_pCacheStream = UcbStreamHelper::CreateStream( aStorageURL.GetMainURL( INetURLObject::DECODE_TO_IURI ),
+ _bForRead ? STREAM_READ | STREAM_NOCREATE : STREAM_WRITE | STREAM_TRUNC );
+ DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::openCacheStream: could not open/create the cache stream!" );
+ if ( m_pCacheStream && m_pCacheStream->GetErrorCode() )
+ {
+ DELETEZ( m_pCacheStream );
+ }
+
+ if ( m_pCacheStream )
+ m_pCacheStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
+
+ return NULL != m_pCacheStream;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCacheImpl::needsUpdate( sal_Bool _bForceCheck )
+ {
+ if ( m_bKnowState && !_bForceCheck )
+ return m_bNeedsUpdate;
+
+ m_bNeedsUpdate = sal_True;
+ m_bKnowState = sal_True;
+
+ if ( readCurrentState() )
+ {
+ // open the stream which contains the cached state of the directories
+ if ( openCacheStream( sal_True ) )
+ { // opening the stream succeeded
+ if ( readPreviousState() )
+ {
+ m_bNeedsUpdate = !equalStates( m_aPreviousState, m_aCurrentState );
+ }
+ else
+ {
+ closeCacheStream();
+ }
+ }
+ }
+ return m_bNeedsUpdate;
+ }
+
+ //---------------------------------------------------------------------
+ void TemplateFolderCacheImpl::initTemplDirs( ::std::vector< String >& )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ uno::Reference< util::XOfficeInstallationDirectories >
+ TemplateFolderCacheImpl::getOfficeInstDirs()
+ {
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ // @@@ This is bad!
+ uno::Reference< lang::XMultiServiceFactory > xSMgr
+ = comphelper::getProcessServiceFactory();
+ OSL_ENSURE( xSMgr.is(), "No service manager!" );
+
+ uno::Reference< beans::XPropertySet > xPropSet(
+ xSMgr, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ uno::Reference< uno::XComponentContext > xCtx;
+ xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
+ >>= xCtx;
+
+ OSL_ENSURE( xCtx.is(),
+ "Unable to obtain component context from service manager!" );
+
+ if ( xCtx.is() )
+ {
+ xCtx->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.util.theOfficeInstallationDirectories" ) ) )
+ >>= m_xOfficeInstDirs;
+ }
+
+ OSL_ENSURE( m_xOfficeInstDirs.is(),
+ "Unable to obtain office directories singleton!" );
+
+ }
+ }
+ }
+ return m_xOfficeInstDirs;
+ }
+
+ //=====================================================================
+ //= TemplateFolderCache
+ //=====================================================================
+ //---------------------------------------------------------------------
+ TemplateFolderCache::TemplateFolderCache( sal_Bool _bAutoStoreState )
+ :m_pImpl( new TemplateFolderCacheImpl( _bAutoStoreState ) )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ TemplateFolderCache::~TemplateFolderCache( )
+ {
+ DELETEZ( m_pImpl );
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool TemplateFolderCache::needsUpdate( sal_Bool _bForceCheck )
+ {
+ return m_pImpl->needsUpdate( _bForceCheck );
+ }
+
+ //---------------------------------------------------------------------
+ void TemplateFolderCache::storeState( sal_Bool _bForceRetrieval )
+ {
+ m_pImpl->storeState( _bForceRetrieval );
+ }
+
+//.........................................................................
+} // namespace sfx2
+//.........................................................................
+
diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx
new file mode 100644
index 000000000000..268533ebb8c8
--- /dev/null
+++ b/svtools/source/misc/transfer.cxx
@@ -0,0 +1,2422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#ifdef WNT
+#include <tools/prewin.h>
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#pragma warning(disable: 4917)
+#endif
+#include <shlobj.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tools/postwin.h>
+#endif
+#include <vos/mutex.hxx>
+#include <rtl/memory.h>
+#include <rtl/uuid.h>
+#include <rtl/uri.hxx>
+#ifndef DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#include <unotools/ucbstreamhelper.hxx>
+#include <sot/exchange.hxx>
+#include <sot/storage.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sot/filelist.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+#include <comphelper/seqstream.hxx>
+#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPEFACTORY_HPP_
+#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPE_HPP_
+#include <com/sun/star/datatransfer/XMimeContentType.hpp>
+#endif
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+#include "svl/urlbmk.hxx"
+#include "inetimg.hxx"
+#include <svtools/wmf.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/transfer.hxx>
+#include <cstdio>
+
+// --------------
+// - Namespaces -
+// --------------
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::clipboard;
+using namespace ::com::sun::star::datatransfer::dnd;
+
+// --------------------------------
+// - TransferableObjectDescriptor -
+// --------------------------------
+
+#define TOD_SIG1 0x01234567
+#define TOD_SIG2 0x89abcdef
+
+SvStream& operator>>( SvStream& rIStm, TransferableObjectDescriptor& rObjDesc )
+{
+ sal_uInt32 nSize, nViewAspect, nSig1, nSig2;
+
+ rIStm >> nSize;
+ rIStm >> rObjDesc.maClassName;
+ rIStm >> nViewAspect;
+ rIStm >> rObjDesc.maSize.Width();
+ rIStm >> rObjDesc.maSize.Height();
+ rIStm >> rObjDesc.maDragStartPos.X();
+ rIStm >> rObjDesc.maDragStartPos.Y();
+ rIStm.ReadByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
+ rIStm.ReadByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
+ rIStm >> nSig1 >> nSig2;
+
+ rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( nViewAspect );
+
+ // don't use width/height info from external objects
+ if( ( TOD_SIG1 != nSig1 ) || ( TOD_SIG2 != nSig2 ) )
+ {
+ rObjDesc.maSize.Width() = 0;
+ rObjDesc.maSize.Height() = 0;
+ }
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const TransferableObjectDescriptor& rObjDesc )
+{
+ const sal_uInt32 nFirstPos = rOStm.Tell(), nViewAspect = rObjDesc.mnViewAspect;
+ const sal_uInt32 nSig1 = TOD_SIG1, nSig2 = TOD_SIG2;
+
+ rOStm.SeekRel( 4 );
+ rOStm << rObjDesc.maClassName;
+ rOStm << nViewAspect;
+ rOStm << rObjDesc.maSize.Width();
+ rOStm << rObjDesc.maSize.Height();
+ rOStm << rObjDesc.maDragStartPos.X();
+ rOStm << rObjDesc.maDragStartPos.Y();
+ rOStm.WriteByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
+ rOStm.WriteByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
+ rOStm << nSig1 << nSig2;
+
+ const sal_uInt32 nLastPos = rOStm.Tell();
+
+ rOStm.Seek( nFirstPos );
+ rOStm << ( nLastPos - nFirstPos );
+ rOStm.Seek( nLastPos );
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------------
+// the reading of the parameter is done using the special service ::com::sun::star::datatransfer::MimeContentType,
+// a similar approach should be implemented for creation of the mimetype string;
+// for now the set of acceptable characters has to be hardcoded, in future it should be part of the service that creates the mimetype
+const ::rtl::OUString aQuotedParamChars = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "()<>@,;:\\\"/[]?=!#$%&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. " ) );
+
+static ::rtl::OUString ImplGetParameterString( const TransferableObjectDescriptor& rObjDesc )
+{
+ const ::rtl::OUString aChar( ::rtl::OUString::createFromAscii( "\"" ) );
+ const ::rtl::OUString aClassName( rObjDesc.maClassName.GetHexName() );
+ ::rtl::OUString aParams;
+
+ if( aClassName.getLength() )
+ {
+ aParams += ::rtl::OUString::createFromAscii( ";classname=\"" );
+ aParams += aClassName;
+ aParams += aChar;
+ }
+
+ if( rObjDesc.maTypeName.Len() )
+ {
+ aParams += ::rtl::OUString::createFromAscii( ";typename=\"" );
+ aParams += rObjDesc.maTypeName;
+ aParams += aChar;
+ }
+
+ if( rObjDesc.maDisplayName.Len() )
+ {
+ // the display name might contain unacceptable characters, encode all of them
+ // this seems to be the only parameter currently that might contain such characters
+ sal_Bool pToAccept[128];
+ for ( sal_Int32 nBInd = 0; nBInd < 128; nBInd++ )
+ pToAccept[nBInd] = sal_False;
+
+ for ( sal_Int32 nInd = 0; nInd < aQuotedParamChars.getLength(); nInd++ )
+ {
+ sal_Unicode nChar = aQuotedParamChars.getStr()[nInd];
+ if ( nChar < 128 )
+ pToAccept[nChar] = sal_True;
+ }
+
+ aParams += ::rtl::OUString::createFromAscii( ";displayname=\"" );
+ aParams += ::rtl::Uri::encode( rObjDesc.maDisplayName, pToAccept, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 );
+ aParams += aChar;
+ }
+
+ aParams += ::rtl::OUString::createFromAscii( ";viewaspect=\"" );
+ aParams += ::rtl::OUString::valueOf( static_cast< sal_Int32 >( rObjDesc.mnViewAspect ) );
+ aParams += aChar;
+
+ aParams += ::rtl::OUString::createFromAscii( ";width=\"" );
+ aParams += ::rtl::OUString::valueOf( rObjDesc.maSize.Width() );
+ aParams += aChar;
+
+ aParams += ::rtl::OUString::createFromAscii( ";height=\"" );
+ aParams += ::rtl::OUString::valueOf( rObjDesc.maSize.Height() );
+ aParams += aChar;
+
+ aParams += ::rtl::OUString::createFromAscii( ";posx=\"" );
+ aParams += ::rtl::OUString::valueOf( rObjDesc.maDragStartPos.X() );
+ aParams += aChar;
+
+ aParams += ::rtl::OUString::createFromAscii( ";posy=\"" );
+ aParams += ::rtl::OUString::valueOf( rObjDesc.maDragStartPos.X() );
+ aParams += aChar;
+
+ return aParams;
+}
+
+// -----------------------------------------------------------------------------
+
+static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, const DataFlavorEx& rFlavorEx )
+{
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+ Reference< XMimeContentTypeFactory > xMimeFact;
+
+ try
+ {
+ if( xFact.is() )
+ {
+ xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
+ "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
+ UNO_QUERY );
+ }
+
+ if( xMimeFact.is() )
+ {
+ Reference< XMimeContentType > xMimeType( xMimeFact->createMimeContentType( rFlavorEx.MimeType ) );
+
+ if( xMimeType.is() )
+ {
+ const ::rtl::OUString aClassNameString( ::rtl::OUString::createFromAscii( "classname" ) );
+ const ::rtl::OUString aTypeNameString( ::rtl::OUString::createFromAscii( "typename" ) );
+ const ::rtl::OUString aDisplayNameString( ::rtl::OUString::createFromAscii( "displayname" ) );
+ const ::rtl::OUString aViewAspectString( ::rtl::OUString::createFromAscii( "viewaspect" ) );
+ const ::rtl::OUString aWidthString( ::rtl::OUString::createFromAscii( "width" ) );
+ const ::rtl::OUString aHeightString( ::rtl::OUString::createFromAscii( "height" ) );
+ const ::rtl::OUString aPosXString( ::rtl::OUString::createFromAscii( "posx" ) );
+ const ::rtl::OUString aPosYString( ::rtl::OUString::createFromAscii( "posy" ) );
+
+ if( xMimeType->hasParameter( aClassNameString ) )
+ {
+ rObjDesc.maClassName.MakeId( xMimeType->getParameterValue( aClassNameString ) );
+ }
+
+ if( xMimeType->hasParameter( aTypeNameString ) )
+ {
+ rObjDesc.maTypeName = xMimeType->getParameterValue( aTypeNameString );
+ }
+
+ if( xMimeType->hasParameter( aDisplayNameString ) )
+ {
+ // the display name might contain unacceptable characters, in this case they should be encoded
+ // this seems to be the only parameter currently that might contain such characters
+ rObjDesc.maDisplayName = ::rtl::Uri::decode( xMimeType->getParameterValue( aDisplayNameString ), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ }
+
+ if( xMimeType->hasParameter( aViewAspectString ) )
+ {
+ rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( xMimeType->getParameterValue( aViewAspectString ).toInt32() );
+ }
+
+ if( xMimeType->hasParameter( aWidthString ) )
+ {
+ rObjDesc.maSize.Width() = xMimeType->getParameterValue( aWidthString ).toInt32();
+ }
+
+ if( xMimeType->hasParameter( aHeightString ) )
+ {
+ rObjDesc.maSize.Height() = xMimeType->getParameterValue( aHeightString ).toInt32();
+ }
+
+ if( xMimeType->hasParameter( aPosXString ) )
+ {
+ rObjDesc.maDragStartPos.X() = xMimeType->getParameterValue( aPosXString ).toInt32();
+ }
+
+ if( xMimeType->hasParameter( aPosYString ) )
+ {
+ rObjDesc.maDragStartPos.Y() = xMimeType->getParameterValue( aPosYString ).toInt32();
+ }
+ }
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------
+// - TransferableHelper::TerminateListener -
+// -----------------------------------------
+
+TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) :
+ mrParent( rTransferableHelper )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableHelper::TerminateListener::~TerminateListener()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) throw( TerminationVetoException, RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) throw( RuntimeException )
+{
+ mrParent.ImplFlush();
+}
+
+// ----------------------
+// - TransferableHelper -
+// ----------------------
+
+TransferableHelper::TransferableHelper() :
+ mpFormats( new DataFlavorExVector ),
+ mpObjDesc( NULL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableHelper::~TransferableHelper()
+{
+ delete mpObjDesc;
+ delete mpFormats;
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) throw( UnsupportedFlavorException, IOException, RuntimeException )
+{
+ if( !maAny.hasValue() || !mpFormats->size() || ( maLastFormat != rFlavor.MimeType ) )
+ {
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ maLastFormat = rFlavor.MimeType;
+ maAny = Any();
+
+ try
+ {
+ DataFlavor aSubstFlavor;
+ sal_Bool bDone = sal_False;
+
+ // add formats if not already done
+ if( !mpFormats->size() )
+ AddSupportedFormats();
+
+ // check alien formats first and try to get a substitution format
+ if( SotExchange::GetFormatDataFlavor( FORMAT_STRING, aSubstFlavor ) &&
+ TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) )
+ {
+ GetData( aSubstFlavor );
+ bDone = maAny.hasValue();
+ }
+ else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
+ TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
+ SotExchange::GetFormatDataFlavor( FORMAT_BITMAP, aSubstFlavor ) )
+ {
+ GetData( aSubstFlavor );
+ bDone = sal_True;
+ }
+ else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
+ TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
+ SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
+ {
+ GetData( aSubstFlavor );
+
+ if( maAny.hasValue() )
+ {
+ Sequence< sal_Int8 > aSeq;
+
+ if( maAny >>= aSeq )
+ {
+ SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
+ GDIMetaFile aMtf;
+
+ *pSrcStm >> aMtf;
+ delete pSrcStm;
+
+ Graphic aGraphic( aMtf );
+ SvMemoryStream aDstStm( 65535, 65535 );
+
+ if( GraphicConverter::Export( aDstStm, aGraphic, CVT_EMF ) == ERRCODE_NONE )
+ {
+ maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
+ aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
+ bDone = sal_True;
+ }
+ }
+ }
+ }
+ else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
+ TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
+ SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
+ {
+ GetData( aSubstFlavor );
+
+ if( maAny.hasValue() )
+ {
+ Sequence< sal_Int8 > aSeq;
+
+ if( maAny >>= aSeq )
+ {
+ SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
+ GDIMetaFile aMtf;
+
+ *pSrcStm >> aMtf;
+ delete pSrcStm;
+
+ SvMemoryStream aDstStm( 65535, 65535 );
+
+ // taking wmf without file header
+ if ( ConvertGDIMetaFileToWMF( aMtf, aDstStm, NULL, FALSE ) )
+ {
+ maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
+ aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
+ bDone = sal_True;
+ }
+ }
+ }
+ }
+
+ // reset Any if substitute doesn't work
+ if( !bDone && maAny.hasValue() )
+ maAny = Any();
+
+ // if any is not yet filled, use standard format
+ if( !maAny.hasValue() )
+ GetData( rFlavor );
+
+#ifdef DEBUG
+ if( maAny.hasValue() && ::com::sun::star::uno::TypeClass_STRING != maAny.getValueType().getTypeClass() )
+ fprintf( stderr, "TransferableHelper delivers sequence of data [ %s ]\n", ByteString( String( rFlavor.MimeType), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+#endif
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ if( !maAny.hasValue() )
+ throw UnsupportedFlavorException();
+ }
+
+ return maAny;
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ if( !mpFormats->size() )
+ AddSupportedFormats();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Sequence< DataFlavor > aRet( mpFormats->size() );
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_uInt32 nCurPos = 0;
+
+ while( aIter != aEnd )
+ {
+ aRet[ nCurPos++ ] = *aIter++;
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL TransferableHelper::isDataFlavorSupported( const DataFlavor& rFlavor ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ if( !mpFormats->size() )
+ AddSupportedFormats();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+
+ while( aIter != aEnd )
+ {
+ if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
+ {
+ aIter = aEnd;
+ bRet = sal_True;
+ }
+ else
+ aIter++;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ if( mxTerminateListener.is() )
+ {
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+
+ if( xFact.is() )
+ {
+ Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
+
+ if( xDesktop.is() )
+ xDesktop->removeTerminateListener( mxTerminateListener );
+ }
+
+ mxTerminateListener = Reference< XTerminateListener >();
+ }
+
+ ObjectReleased();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE );
+ ObjectReleased();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException )
+{
+ sal_Int64 nRet;
+
+ if( ( rId.getLength() == 16 ) &&
+ ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
+ {
+ nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ else
+ nRet = 0;
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::ImplFlush()
+{
+ if( mxClipboard.is() )
+ {
+ Reference< XFlushableClipboard > xFlushableClipboard( mxClipboard, UNO_QUERY );
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ if( xFlushableClipboard.is() )
+ xFlushableClipboard->flushClipboard();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ DBG_ERROR( "Could not flush clipboard" );
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::AddFormat( SotFormatStringId nFormat )
+{
+ DataFlavor aFlavor;
+
+ if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
+ AddFormat( aFlavor );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::AddFormat( const DataFlavor& rFlavor )
+{
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_Bool bAdd = sal_True;
+
+ while( aIter != aEnd )
+ {
+ if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
+ {
+ // update MimeType for SOT_FORMATSTR_ID_OBJECTDESCRIPTOR in every case
+ if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId ) && mpObjDesc )
+ {
+ DataFlavor aObjDescFlavor;
+
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDescFlavor );
+ aIter->MimeType = aObjDescFlavor.MimeType;
+ aIter->MimeType += ::ImplGetParameterString( *mpObjDesc );
+
+#ifdef DEBUG
+ fprintf( stderr, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
+ ByteString( String( aIter->MimeType), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+#endif
+ }
+
+ aIter = aEnd;
+ bAdd = sal_False;
+ }
+ else
+ aIter++;
+ }
+
+ if( bAdd )
+ {
+ DataFlavorEx aFlavorEx;
+ DataFlavor aObjDescFlavor;
+
+ aFlavorEx.MimeType = rFlavor.MimeType;
+ aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
+ aFlavorEx.DataType = rFlavor.DataType;
+ aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
+
+ if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aFlavorEx.mnSotId ) && mpObjDesc )
+ aFlavorEx.MimeType += ::ImplGetParameterString( *mpObjDesc );
+
+ mpFormats->push_back( aFlavorEx );
+
+ if( FORMAT_BITMAP == aFlavorEx.mnSotId )
+ {
+ AddFormat( SOT_FORMATSTR_ID_BMP );
+ }
+ else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId )
+ {
+ AddFormat( SOT_FORMATSTR_ID_EMF );
+ AddFormat( SOT_FORMATSTR_ID_WMF );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
+{
+ DataFlavor aFlavor;
+
+ if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
+ RemoveFormat( aFlavor );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor )
+{
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+
+ while( aIter != aEnd )
+ {
+ if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
+ {
+ aIter = mpFormats->erase( aIter );
+ aEnd = mpFormats->end();
+ }
+ else
+ ++aIter;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::HasFormat( SotFormatStringId nFormat )
+{
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while( aIter != aEnd )
+ {
+ if( nFormat == (*aIter).mnSotId )
+ {
+ aIter = aEnd;
+ bRet = sal_True;
+ }
+ else
+ ++aIter;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::ClearFormats()
+{
+ mpFormats->clear();
+ maAny.clear();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
+{
+ maAny = rAny;
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetString( const ::rtl::OUString& rString, const DataFlavor& rFlavor )
+{
+ DataFlavor aFileFlavor;
+
+ if( rString.getLength() &&
+ SotExchange::GetFormatDataFlavor( FORMAT_FILE, aFileFlavor ) &&
+ TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) )
+ {
+ const String aString( rString );
+ const ByteString aByteStr( aString, gsl_getSystemTextEncoding() );
+ Sequence< sal_Int8 > aSeq( aByteStr.Len() + 1 );
+
+ rtl_copyMemory( aSeq.getArray(), aByteStr.GetBuffer(), aByteStr.Len() );
+ aSeq[ aByteStr.Len() ] = 0;
+ maAny <<= aSeq;
+ }
+ else
+ maAny <<= rString;
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetBitmap( const Bitmap& rBitmap, const DataFlavor& )
+{
+ if( !rBitmap.IsEmpty() )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+
+ aMemStm << rBitmap;
+ maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
+ }
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
+{
+ if( rMtf.GetActionCount() )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+
+ ( (GDIMetaFile&) rMtf ).Write( aMemStm );
+ maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
+ }
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
+{
+ if( rGraphic.GetType() != GRAPHIC_NONE )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
+ aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
+ aMemStm << rGraphic;
+ maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
+ }
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
+{
+ SvMemoryStream aMemStm( 8192, 8192 );
+
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
+ rIMap.Write( aMemStm, String() );
+ maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
+ const ::com::sun::star::datatransfer::DataFlavor& )
+{
+ PrepareOLE( rDesc );
+
+ SvMemoryStream aMemStm( 1024, 1024 );
+
+ aMemStm << rDesc;
+ maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
+
+ return( maAny.hasValue() );
+ }
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
+ const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ rtl_TextEncoding eSysCSet = gsl_getSystemTextEncoding();
+
+ switch( SotExchange::GetFormat( rFlavor ) )
+ {
+ case( SOT_FORMATSTR_ID_SOLK ):
+ {
+ ByteString sURL( rBmk.GetURL(), eSysCSet ),
+ sDesc( rBmk.GetDescription(), eSysCSet );
+ ByteString sOut( ByteString::CreateFromInt32( sURL.Len() ));
+ ( sOut += '@' ) += sURL;
+ sOut += ByteString::CreateFromInt32( sDesc.Len() );
+ ( sOut += '@' ) += sDesc;
+
+ Sequence< sal_Int8 > aSeq( sOut.Len() );
+ memcpy( aSeq.getArray(), sOut.GetBuffer(), sOut.Len() );
+ maAny <<= aSeq;
+ }
+ break;
+
+ case( FORMAT_STRING ):
+ maAny <<= ::rtl::OUString( rBmk.GetURL() );
+ break;
+
+ case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
+ {
+ ByteString sURL( rBmk.GetURL(), eSysCSet );
+ Sequence< sal_Int8 > aSeq( sURL.Len() );
+ memcpy( aSeq.getArray(), sURL.GetBuffer(), sURL.Len() );
+ maAny <<= aSeq;
+ }
+ break;
+
+ case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
+ {
+ Sequence< sal_Int8 > aSeq( 2048 );
+
+ memset( aSeq.getArray(), 0, 2048 );
+ strcpy( reinterpret_cast< char* >( aSeq.getArray() ), ByteString( rBmk.GetURL(), eSysCSet).GetBuffer() );
+ strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, ByteString( rBmk.GetDescription(), eSysCSet ).GetBuffer() );
+
+ maAny <<= aSeq;
+ }
+ break;
+
+#ifdef WNT
+ case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
+ {
+ Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
+ FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
+ FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ];
+
+ pFDesc->cItems = 1;
+ memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
+ rFDesc1.dwFlags = FD_LINKUI;
+
+ ByteString aStr( rBmk.GetDescription(), eSysCSet );
+ for( USHORT nChar = 0; nChar < aStr.Len(); ++nChar )
+ if( strchr( "\\/:*?\"<>|", aStr.GetChar( nChar ) ) )
+ aStr.Erase( nChar--, 1 );
+
+ aStr.Insert( "Shortcut to ", 0 );
+ aStr += ".URL";
+ strcpy( rFDesc1.cFileName, aStr.GetBuffer() );
+
+ maAny <<= aSeq;
+ }
+ break;
+
+ case SOT_FORMATSTR_ID_FILECONTENT:
+ {
+ String aStr( RTL_CONSTASCII_STRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
+ maAny <<= ::rtl::OUString( aStr += rBmk.GetURL() );
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
+ const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ SvMemoryStream aMemStm( 1024, 1024 );
+
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
+ rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
+
+ maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetFileList( const FileList& rFileList,
+ const ::com::sun::star::datatransfer::DataFlavor& )
+{
+ SvMemoryStream aMemStm( 4096, 4096 );
+
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
+ aMemStm << rFileList;
+
+ maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) );
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
+{
+ SotStorageStreamRef xStm( new SotStorageStream( String() ) );
+
+ xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
+
+ if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
+ {
+ const sal_uInt32 nLen = xStm->Seek( STREAM_SEEK_TO_END );
+ Sequence< sal_Int8 > aSeq( nLen );
+
+ xStm->Seek( STREAM_SEEK_TO_BEGIN );
+ xStm->Read( aSeq.getArray(), nLen );
+
+ if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
+ {
+ //JP 24.7.2001: as I know was this only for the writer application and this
+ // writes now UTF16 format into the stream
+ //JP 6.8.2001: and now it writes UTF8 because then exist no problem with
+ // little / big endians! - Bug 88121
+ maAny <<= ::rtl::OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
+ }
+ else
+ maAny <<= aSeq;
+ }
+
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::SetInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rIf,
+ const ::com::sun::star::datatransfer::DataFlavor& )
+{
+ maAny <<= rIf;
+ return( maAny.hasValue() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
+{
+ DBG_ERROR( "TransferableHelper::WriteObject( ... ) not implemented" );
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::DragFinished( sal_Int8 )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::ObjectReleased()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc )
+{
+ delete mpObjDesc;
+ mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
+
+ if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) )
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::CopyToClipboard( Window *pWindow ) const
+{
+ DBG_ASSERT( pWindow, "Window pointer is NULL" );
+ Reference< XClipboard > xClipboard;
+
+ if( pWindow )
+ xClipboard = pWindow->GetClipboard();
+
+ if( xClipboard.is() )
+ mxClipboard = xClipboard;
+
+ if( mxClipboard.is() && !mxTerminateListener.is() )
+ {
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+
+ if( xFact.is() )
+ {
+ Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
+
+ if( xDesktop.is() )
+ xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
+ }
+
+ mxClipboard->setContents( pThis, pThis );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::CopyToSelection( Window *pWindow ) const
+{
+ DBG_ASSERT( pWindow, "Window pointer is NULL" );
+ Reference< XClipboard > xSelection;
+
+ if( pWindow )
+ xSelection = pWindow->GetPrimarySelection();
+
+ if( xSelection.is() && !mxTerminateListener.is() )
+ {
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+
+ if( xFact.is() )
+ {
+ Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
+
+ if( xDesktop.is() )
+ xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
+ }
+
+ xSelection->setContents( pThis, pThis );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
+ sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
+
+{
+ DBG_ASSERT( pWindow, "Window pointer is NULL" );
+ Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
+
+ if( xDragSource.is() )
+ {
+ /*
+ * #96792# release mouse before actually starting DnD.
+ * This is necessary for the X11 DnD implementation to work.
+ */
+ if( pWindow->IsMouseCaptured() )
+ pWindow->ReleaseMouse();
+
+ const Point aPt( pWindow->GetPointerPosPixel() );
+
+ // On Mac OS X we are forced to execute 'startDrag' synchronously
+ // contrary to the XDragSource interface specification because
+ // we can receive drag events from the system only in the main
+ // thread
+#if !defined(QUARTZ)
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+#endif
+
+ try
+ {
+ DragGestureEvent aEvt;
+ aEvt.DragAction = DNDConstants::ACTION_COPY;
+ aEvt.DragOriginX = aPt.X();
+ aEvt.DragOriginY = aPt.Y();
+ aEvt.DragSource = xDragSource;
+
+ xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // See above for the reason of this define
+#if !defined(QUARTZ)
+ Application::AcquireSolarMutex( nRef );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableHelper::ClearSelection( Window *pWindow )
+{
+ DBG_ASSERT( pWindow, "Window pointer is NULL" );
+ Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
+
+ if( xSelection.is() )
+ xSelection->setContents( NULL, NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XClipboard> TransferableHelper::GetSystemClipboard()
+{
+ Window *pFocusWindow = Application::GetFocusWindow();
+
+ if( pFocusWindow )
+ return pFocusWindow->GetClipboard();
+
+ return Reference< XClipboard > ();
+}
+
+// -----------------------------------------------------------------------------
+
+const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
+{
+ static 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;
+}
+
+// ---------------------------------
+// - TransferableClipboardNotifier -
+// ---------------------------------
+
+class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
+{
+private:
+ ::osl::Mutex& mrMutex;
+ Reference< XClipboardNotifier > mxNotifier;
+ TransferableDataHelper* mpListener;
+
+protected:
+ // XClipboardListener
+ virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
+
+public:
+ TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
+
+ /// determines whether we're currently listening
+ inline bool isListening() const { return !isDisposed(); }
+
+ /// determines whether the instance is disposed
+ inline bool isDisposed() const { return mpListener == NULL; }
+
+ /// makes the instance non-functional
+ void dispose();
+};
+
+// -----------------------------------------------------------------------------
+
+TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
+ :mrMutex( _rMutex )
+ ,mxNotifier( _rxClipboard, UNO_QUERY )
+ ,mpListener( &_rListener )
+{
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ if ( mxNotifier.is() )
+ mxNotifier->addClipboardListener( this );
+ else
+ // born dead
+ mpListener = NULL;
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // the SolarMutex here is necessary, since
+ // - we cannot call mpListener without our own mutex locked
+ // - Rebind respectively InitFormats (called by Rebind) will
+ // try to lock the SolarMutex, too
+ ::osl::MutexGuard aGuard( mrMutex );
+ if( mpListener )
+ mpListener->Rebind( event.Contents );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
+{
+ // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
+ dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableClipboardNotifier::dispose()
+{
+ ::osl::MutexGuard aGuard( mrMutex );
+
+ Reference< XClipboardListener > xKeepMeAlive( this );
+
+ if ( mxNotifier.is() )
+ mxNotifier->removeClipboardListener( this );
+ mxNotifier.clear();
+
+ mpListener = NULL;
+}
+
+// -------------------------------
+// - TransferableDataHelper_Impl -
+// -------------------------------
+
+struct TransferableDataHelper_Impl
+{
+ ::osl::Mutex maMutex;
+ TransferableClipboardNotifier* mpClipboardListener;
+
+ TransferableDataHelper_Impl()
+ :mpClipboardListener( NULL )
+ {
+ }
+};
+
+// --------------------------
+// - TransferableDataHelper -
+// --------------------------
+
+TransferableDataHelper::TransferableDataHelper() :
+ mpFormats( new DataFlavorExVector ),
+ mpObjDesc( new TransferableObjectDescriptor ),
+ mpImpl( new TransferableDataHelper_Impl )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) :
+ mxTransfer( rxTransferable ),
+ mpFormats( new DataFlavorExVector ),
+ mpObjDesc( new TransferableObjectDescriptor ),
+ mpImpl( new TransferableDataHelper_Impl )
+{
+ InitFormats();
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper ) :
+ mxTransfer( rDataHelper.mxTransfer ),
+ mxClipboard( rDataHelper.mxClipboard ),
+ mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) ),
+ mpObjDesc( new TransferableObjectDescriptor( *rDataHelper.mpObjDesc ) ),
+ mpImpl( new TransferableDataHelper_Impl )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
+{
+ if ( this != &rDataHelper )
+ {
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+
+ bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
+
+ if ( bWasClipboardListening )
+ StopClipboardListening();
+
+ mxTransfer = rDataHelper.mxTransfer;
+ delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
+ delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor( *rDataHelper.mpObjDesc );
+ mxClipboard = rDataHelper.mxClipboard;
+
+ if ( bWasClipboardListening )
+ StartClipboardListening();
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableDataHelper::~TransferableDataHelper()
+{
+ StopClipboardListening( );
+ {
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+ delete mpFormats, mpFormats = NULL;
+ delete mpObjDesc, mpObjDesc = NULL;
+ }
+ delete mpImpl;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
+ DataFlavorExVector& rDataFlavorExVector )
+{
+ try
+ {
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+ Reference< XMimeContentTypeFactory > xMimeFact;
+ DataFlavorEx aFlavorEx;
+ const ::rtl::OUString aCharsetStr( ::rtl::OUString::createFromAscii( "charset" ) );
+
+ if( xFact.is() )
+ xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
+ "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
+ UNO_QUERY );
+
+ for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
+ {
+ const DataFlavor& rFlavor = rDataFlavorSeq[ i ];
+ Reference< XMimeContentType > xMimeType;
+
+ try
+ {
+ if( xMimeFact.is() && rFlavor.MimeType.getLength() )
+ xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+
+ }
+
+ aFlavorEx.MimeType = rFlavor.MimeType;
+ aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
+ aFlavorEx.DataType = rFlavor.DataType;
+ aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
+
+ rDataFlavorExVector.push_back( aFlavorEx );
+
+ // add additional formats for special mime types
+ if( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId )
+ {
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
+ {
+ aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
+ rDataFlavorExVector.push_back( aFlavorEx );
+ }
+ }
+ else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId )
+ {
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
+ {
+ aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
+ rDataFlavorExVector.push_back( aFlavorEx );
+ }
+ }
+ else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId )
+ {
+ // #104735# HTML_SIMPLE may also be inserted without comments
+ aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
+ rDataFlavorExVector.push_back( aFlavorEx );
+ }
+ else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
+ {
+ // add, if it is a UTF-8 byte buffer
+ if( xMimeType->hasParameter( aCharsetStr ) )
+ {
+ const ::rtl::OUString aCharset( xMimeType->getParameterValue( aCharsetStr ) );
+
+ if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) ||
+ xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) )
+ {
+ rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
+
+ }
+ }
+ }
+ else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/rtf" ) ) )
+ {
+ rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
+ }
+ else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/html" ) ) )
+
+ {
+ rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
+ }
+ else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) )
+ {
+ rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
+ }
+ else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice-objectdescriptor-xml" ) ) )
+ {
+ rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR;
+ }
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableDataHelper::InitFormats()
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+
+ mpFormats->clear();
+ delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor;
+
+ if( mxTransfer.is() )
+ {
+ TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
+
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+
+ while( aIter != aEnd )
+ {
+ if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId )
+ {
+ ImplSetParameterString( *mpObjDesc, *aIter );
+ aIter = aEnd;
+ }
+ else
+ ++aIter;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while( aIter != aEnd )
+ {
+ if( nFormat == (*aIter++).mnSotId )
+ {
+ aIter = aEnd;
+ bRet = sal_True;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while( aIter != aEnd )
+ {
+ if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
+ {
+ aIter = aEnd;
+ bRet = sal_True;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_uInt32 TransferableDataHelper::GetFormatCount() const
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+ return mpFormats->size();
+}
+
+// -----------------------------------------------------------------------------
+
+
+SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+ DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
+ return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
+}
+
+// -----------------------------------------------------------------------------
+
+DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+ DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
+
+ DataFlavor aRet;
+
+ if( nFormat < mpFormats->size() )
+ aRet = (*mpFormats)[ nFormat ];
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
+{
+ Reference< XTransferable > xRet;
+
+ if( mxTransfer.is() )
+ {
+ try
+ {
+ xRet = mxTransfer;
+
+ // do a dummy call to check, if this interface is valid (nasty)
+ Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
+
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ xRet = Reference< XTransferable >();
+ }
+ }
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Any TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
+{
+ Any aReturn;
+
+ DataFlavor aFlavor;
+ if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
+ aReturn = GetAny( aFlavor );
+
+ return aReturn;
+}
+
+
+// -----------------------------------------------------------------------------
+
+Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+ Any aRet;
+
+ try
+ {
+ if( mxTransfer.is() )
+ {
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ const SotFormatStringId nRequestFormat = SotExchange::GetFormat( rFlavor );
+
+ if( nRequestFormat )
+ {
+ // try to get alien format first
+ while( aIter != aEnd )
+ {
+ if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
+ aRet = mxTransfer->getTransferData( *aIter );
+
+ if( aRet.hasValue() )
+ aIter = aEnd;
+ else
+ aIter++;
+ }
+ }
+
+ if( !aRet.hasValue() )
+ aRet = mxTransfer->getTransferData( rFlavor );
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
+{
+ ::rtl::OUString aOUString;
+ sal_Bool bRet = GetString( nFormat, aOUString );
+
+ rStr = aOUString;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
+{
+ ::rtl::OUString aOUString;
+ sal_Bool bRet = GetString( rFlavor, aOUString );
+
+ rStr = aOUString;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, ::rtl::OUString& rStr )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, ::rtl::OUString& rStr )
+{
+ Any aAny( GetAny( rFlavor ) );
+ sal_Bool bRet = sal_False;
+
+ if( aAny.hasValue() )
+ {
+ ::rtl::OUString aOUString;
+ Sequence< sal_Int8 > aSeq;
+
+ if( aAny >>= aOUString )
+ {
+ rStr = aOUString;
+ bRet = sal_True;
+ }
+ else if( aAny >>= aSeq )
+ {
+
+ const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
+ sal_Int32 nLen = aSeq.getLength();
+
+ //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
+ //DVO 2002-05-27: strip _all_ trailing zeros
+ while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
+ --nLen;
+
+ rStr = ::rtl::OUString( pChars, nLen, gsl_getSystemTextEncoding() );
+ bRet = sal_True;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmap( aFlavor, rBmp ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& rBmp )
+{
+ SotStorageStreamRef xStm;
+ DataFlavor aSubstFlavor;
+ sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
+
+ if( bRet )
+ {
+ *xStm >> rBmp;
+ bRet = ( xStm->GetError() == ERRCODE_NONE );
+
+ /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
+ problem is, that some graphics are inserted much too big because the nXPelsPerMeter
+ and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
+ Due to this reason the following code assumes that bitmaps with a logical size
+ greater than 50 cm aren't having the correct mapmode set.
+
+ The following code should be removed if DDBs and DIBs are supported via clipboard
+ properly.
+ */
+ if ( bRet )
+ {
+ MapMode aMapMode = rBmp.GetPrefMapMode();
+ if ( aMapMode.GetMapUnit() != MAP_PIXEL )
+ {
+ Size aSize = OutputDevice::LogicToLogic( rBmp.GetPrefSize(), aMapMode, MAP_100TH_MM );
+ if ( ( aSize.Width() > 5000 ) || ( aSize.Height() > 5000 ) )
+ rBmp.SetPrefMapMode( MAP_PIXEL );
+ }
+ }
+ }
+
+ if( !bRet &&
+ HasFormat( SOT_FORMATSTR_ID_BMP ) &&
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
+ GetSotStorageStream( aSubstFlavor, xStm ) )
+ {
+ xStm->ResetError();
+ *xStm >> rBmp;
+ bRet = ( xStm->GetError() == ERRCODE_NONE );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
+{
+ SotStorageStreamRef xStm;
+ DataFlavor aSubstFlavor;
+ sal_Bool bRet = sal_False;
+
+ if( GetSotStorageStream( rFlavor, xStm ) )
+ {
+ *xStm >> rMtf;
+ bRet = ( xStm->GetError() == ERRCODE_NONE );
+ }
+
+ if( !bRet &&
+ HasFormat( SOT_FORMATSTR_ID_EMF ) &&
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
+ GetSotStorageStream( aSubstFlavor, xStm ) )
+ {
+ Graphic aGraphic;
+
+ if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
+ {
+ rMtf = aGraphic.GetGDIMetaFile();
+ bRet = TRUE;
+ }
+ }
+
+ if( !bRet &&
+ HasFormat( SOT_FORMATSTR_ID_WMF ) &&
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
+ GetSotStorageStream( aSubstFlavor, xStm ) )
+ {
+ Graphic aGraphic;
+
+ if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
+ {
+ rMtf = aGraphic.GetGDIMetaFile();
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
+{
+ DataFlavor aFlavor;
+ sal_Bool bRet = sal_False;
+
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
+ TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
+ {
+ Bitmap aBmp;
+
+ if( ( bRet = GetBitmap( aFlavor, aBmp ) ) == sal_True )
+ rGraphic = aBmp;
+ }
+ else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
+ TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
+ {
+ GDIMetaFile aMtf;
+
+ if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
+ rGraphic = aMtf;
+ }
+ else
+ {
+ SotStorageStreamRef xStm;
+
+ if( GetSotStorageStream( rFlavor, xStm ) )
+ {
+ *xStm >> rGraphic;
+ bRet = ( xStm->GetError() == ERRCODE_NONE );
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
+{
+ SotStorageStreamRef xStm;
+ sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
+
+ if( bRet )
+ {
+ rIMap.Read( *xStm, String() );
+ bRet = ( xStm->GetError() == ERRCODE_NONE );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor&, TransferableObjectDescriptor& rDesc )
+{
+ rDesc = *mpObjDesc;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
+{
+ sal_Bool bRet = sal_False;
+ if( HasFormat( rFlavor ))
+ {
+ const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
+ switch( nFormat )
+ {
+ case( SOT_FORMATSTR_ID_SOLK ):
+ case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
+ {
+ String aString;
+ if( GetString( rFlavor, aString ) )
+ {
+ if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
+ {
+ rBmk = INetBookmark( aString, aString );
+ bRet = sal_True;
+ }
+ else
+ {
+ String aURL, aDesc;
+ sal_uInt16 nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
+
+ if( !nLen && aString.GetChar( 0 ) != '0' )
+ {
+ DBG_WARNING( "SOLK: 1. len=0" );
+ }
+ if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
+ {
+ DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
+ }
+ aURL = aString.Copy( nStart + 1, nLen );
+
+ aString.Erase( 0, nStart + 1 + nLen );
+ nStart = aString.Search( '@' );
+ nLen = (sal_uInt16) aString.ToInt32();
+
+ if( !nLen && aString.GetChar( 0 ) != '0' )
+ {
+ DBG_WARNING( "SOLK: 2. len=0" );
+ }
+ if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
+ {
+ DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
+ }
+ aDesc = aString.Copy( nStart+1, nLen );
+
+ rBmk = INetBookmark( aURL, aDesc );
+ bRet = sal_True;
+ }
+ }
+ }
+ break;
+
+ case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
+ {
+ Sequence< sal_Int8 > aSeq;
+
+ if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
+ {
+ rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), gsl_getSystemTextEncoding() ),
+ String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, gsl_getSystemTextEncoding() ) );
+ bRet = sal_True;
+ }
+ }
+ break;
+
+#ifdef WNT
+ case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
+ {
+ Sequence< sal_Int8 > aSeq;
+
+ if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
+ {
+ FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
+
+ if( pFDesc->cItems )
+ {
+ ByteString aDesc( pFDesc->fgd[ 0 ].cFileName );
+ rtl_TextEncoding eTextEncoding = gsl_getSystemTextEncoding();
+
+ if( ( aDesc.Len() > 4 ) && aDesc.Copy( aDesc.Len() - 4 ).EqualsIgnoreCaseAscii( ".URL" ) )
+ {
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( String( aDesc, eTextEncoding ) ).GetMainURL( INetURLObject::NO_DECODE ),
+ STREAM_STD_READ );
+
+ if( !pStream || pStream->GetError() )
+ {
+ DataFlavor aFileContentFlavor;
+
+ aSeq.realloc( 0 );
+ delete pStream;
+
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
+ GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
+ {
+ pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
+ }
+ else
+ pStream = NULL;
+ }
+
+ if( pStream )
+ {
+ ByteString aLine;
+ sal_Bool bSttFnd = sal_False;
+
+ while( pStream->ReadLine( aLine ) )
+ {
+ if( aLine.EqualsIgnoreCaseAscii( "[InternetShortcut]" ) )
+ bSttFnd = sal_True;
+ else if( bSttFnd && aLine.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "URL=" ) )
+ {
+ rBmk = INetBookmark( String( aLine.Erase( 0, 4 ), eTextEncoding ),
+ String( aDesc.Erase( aDesc.Len() - 4 ), eTextEncoding ) );
+ bRet = sal_True;
+ break;
+ }
+ }
+
+ delete pStream;
+ }
+ }
+ }
+ }
+ }
+ break;
+#endif
+
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
+ INetImage& rINtImg )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetINetImage(
+ const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
+ INetImage& rINtImg )
+{
+ SotStorageStreamRef xStm;
+ sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
+
+ if( bRet )
+ bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
+ FileList& rFileList )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetFileList(
+ const ::com::sun::star::datatransfer::DataFlavor&,
+ FileList& rFileList )
+{
+ SotStorageStreamRef xStm;
+ sal_Bool bRet = sal_False;
+
+ for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
+ {
+ if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
+ {
+ const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
+
+ if( GetSotStorageStream( aFlavor, xStm ) )
+ {
+ if( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) > -1 )
+ {
+ ByteString aByteString;
+
+ while( xStm->ReadLine( aByteString ) )
+ if( aByteString.Len() && aByteString.GetChar( 0 ) != '#' )
+ rFileList.AppendFile( String( aByteString, RTL_TEXTENCODING_UTF8 ) );
+
+ bRet = sal_True;
+ }
+ else
+ bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
+{
+#ifdef DEBUG
+ fprintf( stderr, "TransferableDataHelper requests sequence of data\n" );
+#endif
+
+ const Any aAny( GetAny( rFlavor ) );
+ return( aAny.hasValue() && ( aAny >>= rSeq ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
+{
+ Sequence< sal_Int8 > aSeq;
+ sal_Bool bRet = GetSequence( rFlavor, aSeq );
+
+ if( bRet )
+ {
+ rxStream = new SotStorageStream( String() );
+ rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
+ rxStream->Seek( 0 );
+ }
+
+ return bRet;
+}
+
+sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
+{
+ Sequence< sal_Int8 > aSeq;
+ sal_Bool bRet = GetSequence( rFlavor, aSeq );
+
+ if( bRet )
+ rxStream = new ::comphelper::SequenceInputStream( aSeq );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+
+sal_Bool TransferableDataHelper::GetInterface( SotFormatStringId nFormat, Reference< XInterface >& rIf )
+{
+ DataFlavor aFlavor;
+ return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInterface( aFlavor, rIf ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::GetInterface( const DataFlavor& rFlavor, Reference< XInterface >& rIf )
+{
+ const Any aAny( GetAny( rFlavor ) );
+ return( aAny.hasValue() && ( aAny >>= rIf ) );
+}
+
+// -----------------------------------------------------------------------------
+void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
+{
+ mxTransfer = _rxNewContent;
+ InitFormats();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferableDataHelper::StartClipboardListening( )
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+
+ StopClipboardListening( );
+
+ mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
+ mpImpl->mpClipboardListener->acquire();
+
+ return mpImpl->mpClipboardListener->isListening();
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferableDataHelper::StopClipboardListening( )
+{
+ ::osl::MutexGuard aGuard( mpImpl->maMutex );
+
+ if ( mpImpl->mpClipboardListener )
+ {
+ mpImpl->mpClipboardListener->dispose();
+ mpImpl->mpClipboardListener->release();
+ mpImpl->mpClipboardListener = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
+{
+ DBG_ASSERT( pWindow, "Window pointer is NULL" );
+
+ Reference< XClipboard > xClipboard;
+ TransferableDataHelper aRet;
+
+ if( pWindow )
+ xClipboard = pWindow->GetClipboard();
+
+ if( xClipboard.is() )
+ {
+ try
+
+ {
+ Reference< XTransferable > xTransferable( xClipboard->getContents() );
+
+ if( xTransferable.is() )
+ {
+ aRet = TransferableDataHelper( xTransferable );
+ aRet.mxClipboard = xClipboard;
+ // also copy the clipboard - 99030 - 23.05.2002 - fs@openoffice.org
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ return aRet;
+}
+
+
+// -----------------------------------------------------------------------------
+
+TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
+{
+ DBG_ASSERT( pWindow, "Window pointer is NULL" );
+
+ Reference< XClipboard > xSelection;
+ TransferableDataHelper aRet;
+
+ if( pWindow )
+ xSelection = pWindow->GetPrimarySelection();
+
+ if( xSelection.is() )
+ {
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ Reference< XTransferable > xTransferable( xSelection->getContents() );
+
+ if( xTransferable.is() )
+ {
+ aRet = TransferableDataHelper( xTransferable );
+ aRet.mxClipboard = xSelection;
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
+ const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
+ sal_Bool )
+{
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+ Reference< XMimeContentTypeFactory > xMimeFact;
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ if( xFact.is() )
+ xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
+ "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
+ UNO_QUERY );
+
+ if( xMimeFact.is() )
+ {
+ Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
+ Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
+
+ if( xRequestType1.is() && xRequestType2.is() )
+ {
+ if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
+ {
+ if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
+ {
+ // special handling for text/plain media types
+ const ::rtl::OUString aCharsetString( ::rtl::OUString::createFromAscii( "charset" ) );
+
+ if( !xRequestType2->hasParameter( aCharsetString ) ||
+ xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) ||
+ xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) )
+ {
+ bRet = sal_True;
+ }
+ }
+ else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice" ) ) )
+ {
+ // special handling for application/x-openoffice media types
+ const ::rtl::OUString aFormatString( ::rtl::OUString::createFromAscii( "windows_formatname" ) );
+
+ if( xRequestType1->hasParameter( aFormatString ) &&
+ xRequestType2->hasParameter( aFormatString ) &&
+ xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
+ {
+ bRet = sal_True;
+ }
+ }
+ else
+ bRet = sal_True;
+ }
+ }
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
+ }
+
+ return bRet;
+}
diff --git a/svtools/source/misc/transfer2.cxx b/svtools/source/misc/transfer2.cxx
new file mode 100644
index 000000000000..dcd0f81b2758
--- /dev/null
+++ b/svtools/source/misc/transfer2.cxx
@@ -0,0 +1,635 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <vos/mutex.hxx>
+#ifndef DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#include <unotools/ucbstreamhelper.hxx>
+#include <sot/exchange.hxx>
+#include <sot/storage.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <comphelper/processfactory.hxx>
+#ifndef _COM_SUN_STAR_DATATRANSFER_DND_DROPTARGETDRAGCONTEXT_HPP_
+#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp>
+#endif
+
+#include "svl/urlbmk.hxx"
+#include "inetimg.hxx"
+#include <svtools/imap.hxx>
+#include <svtools/transfer.hxx>
+
+// --------------
+// - Namespaces -
+// --------------
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::clipboard;
+using namespace ::com::sun::star::datatransfer::dnd;
+
+// -----------------------------------------
+// - DragSourceHelper::DragGestureListener -
+// -----------------------------------------
+
+DragSourceHelper::DragGestureListener::DragGestureListener( DragSourceHelper& rDragSourceHelper ) :
+ mrParent( rDragSourceHelper )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+DragSourceHelper::DragGestureListener::~DragGestureListener()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DragSourceHelper::DragGestureListener::disposing( const EventObject& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DragSourceHelper::DragGestureListener::dragGestureRecognized( const DragGestureEvent& rDGE ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const Point aPtPixel( rDGE.DragOriginX, rDGE.DragOriginY );
+ mrParent.StartDrag( rDGE.DragAction, aPtPixel );
+}
+
+// --------------------
+// - DragSourceHelper -
+// --------------------
+
+DragSourceHelper::DragSourceHelper( Window* pWindow ) :
+ mxDragGestureRecognizer( pWindow->GetDragGestureRecognizer() )
+{
+ if( mxDragGestureRecognizer.is() )
+ {
+ mxDragGestureListener = new DragSourceHelper::DragGestureListener( *this );
+ mxDragGestureRecognizer->addDragGestureListener( mxDragGestureListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+DragSourceHelper::~DragSourceHelper()
+{
+ if( mxDragGestureRecognizer.is() )
+ mxDragGestureRecognizer->removeDragGestureListener( mxDragGestureListener );
+}
+
+// -----------------------------------------------------------------------------
+
+void DragSourceHelper::StartDrag( sal_Int8, const Point& )
+{
+}
+
+// ----------------------------------------
+// - DropTargetHelper::DropTargetListener -
+// ----------------------------------------
+
+DropTargetHelper::DropTargetListener::DropTargetListener( DropTargetHelper& rDropTargetHelper ) :
+ mrParent( rDropTargetHelper ),
+ mpLastDragOverEvent( NULL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+DropTargetHelper::DropTargetListener::~DropTargetListener()
+{
+ delete mpLastDragOverEvent;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetHelper::DropTargetListener::disposing( const EventObject& ) throw( RuntimeException )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetHelper::DropTargetListener::drop( const DropTargetDropEvent& rDTDE ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ AcceptDropEvent aAcceptEvent;
+ ExecuteDropEvent aExecuteEvt( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );
+ sal_Int8 nRet = DNDConstants::ACTION_NONE;
+
+ aExecuteEvt.mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );
+
+ // in case of a default action, call ::AcceptDrop first and use the returned
+ // accepted action as the execute action in the call to ::ExecuteDrop
+ aAcceptEvent.mnAction = aExecuteEvt.mnAction;
+ aAcceptEvent.maPosPixel = aExecuteEvt.maPosPixel;
+ (DropTargetEvent&)( aAcceptEvent.maDragEvent ) = (DropTargetEvent&) rDTDE;
+ ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).DropAction = rDTDE.DropAction;
+ ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).LocationX = rDTDE.LocationX;
+ ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).LocationY = rDTDE.LocationY;
+ ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).SourceActions = rDTDE.SourceActions;
+ aAcceptEvent.mbLeaving = sal_False;
+ aAcceptEvent.mbDefault = aExecuteEvt.mbDefault;
+
+ nRet = mrParent.AcceptDrop( aAcceptEvent );
+
+ if( DNDConstants::ACTION_NONE != nRet )
+ {
+ rDTDE.Context->acceptDrop( nRet );
+
+ if( aExecuteEvt.mbDefault )
+ aExecuteEvt.mnAction = nRet;
+
+ nRet = mrParent.ExecuteDrop( aExecuteEvt );
+ }
+
+ rDTDE.Context->dropComplete( DNDConstants::ACTION_NONE != nRet );
+
+ if( mpLastDragOverEvent )
+ {
+ delete mpLastDragOverEvent;
+ mpLastDragOverEvent = NULL;
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetHelper::DropTargetListener::dragEnter( const DropTargetDragEnterEvent& rDTDEE ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ mrParent.ImplBeginDrag( rDTDEE.SupportedDataFlavors );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ dragOver( rDTDEE );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetHelper::DropTargetListener::dragOver( const DropTargetDragEvent& rDTDE ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ if( mpLastDragOverEvent )
+ delete mpLastDragOverEvent;
+
+ mpLastDragOverEvent = new AcceptDropEvent( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );
+ mpLastDragOverEvent->mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );
+
+ const sal_Int8 nRet = mrParent.AcceptDrop( *mpLastDragOverEvent );
+
+ if( DNDConstants::ACTION_NONE == nRet )
+ rDTDE.Context->rejectDrag();
+ else
+ rDTDE.Context->acceptDrag( nRet );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetHelper::DropTargetListener::dragExit( const DropTargetEvent& ) throw( RuntimeException )
+{
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ if( mpLastDragOverEvent )
+ {
+ mpLastDragOverEvent->mbLeaving = sal_True;
+ mrParent.AcceptDrop( *mpLastDragOverEvent );
+ delete mpLastDragOverEvent;
+ mpLastDragOverEvent = NULL;
+ }
+
+ mrParent.ImplEndDrag();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetHelper::DropTargetListener::dropActionChanged( const DropTargetDragEvent& ) throw( RuntimeException )
+{
+}
+
+// --------------------
+// - DropTargetHelper -
+// --------------------
+
+DropTargetHelper::DropTargetHelper( Window* pWindow ) :
+ mxDropTarget( pWindow->GetDropTarget() ),
+ mpFormats( new DataFlavorExVector )
+{
+ ImplConstruct();
+}
+
+// -----------------------------------------------------------------------------
+
+DropTargetHelper::DropTargetHelper( const Reference< XDropTarget >& rxDropTarget ) :
+ mxDropTarget( rxDropTarget ),
+ mpFormats( new DataFlavorExVector )
+{
+ ImplConstruct();
+}
+
+// -----------------------------------------------------------------------------
+
+DropTargetHelper::~DropTargetHelper()
+{
+ if( mxDropTarget.is() )
+ mxDropTarget->removeDropTargetListener( mxDropTargetListener );
+
+ delete mpFormats;
+}
+
+// -----------------------------------------------------------------------------
+
+void DropTargetHelper::ImplConstruct()
+{
+ if( mxDropTarget.is() )
+ {
+ mxDropTargetListener = new DropTargetHelper::DropTargetListener( *this );
+ mxDropTarget->addDropTargetListener( mxDropTargetListener );
+ mxDropTarget->setActive( sal_True );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void DropTargetHelper::ImplBeginDrag( const Sequence< DataFlavor >& rSupportedDataFlavors )
+{
+ mpFormats->clear();
+ TransferableDataHelper::FillDataFlavorExVector( rSupportedDataFlavors, *mpFormats );
+}
+
+// -----------------------------------------------------------------------------
+
+void DropTargetHelper::ImplEndDrag()
+{
+ mpFormats->clear();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int8 DropTargetHelper::AcceptDrop( const AcceptDropEvent& )
+{
+ return( DNDConstants::ACTION_NONE );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int8 DropTargetHelper::ExecuteDrop( const ExecuteDropEvent& )
+{
+ return( DNDConstants::ACTION_NONE );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool DropTargetHelper::IsDropFormatSupported( SotFormatStringId nFormat )
+{
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while( aIter != aEnd )
+ {
+ if( nFormat == (*aIter++).mnSotId )
+ {
+ bRet = sal_True;
+ aIter = aEnd;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool DropTargetHelper::IsDropFormatSupported( const DataFlavor& rFlavor )
+{
+ DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while( aIter != aEnd )
+ {
+ if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
+ {
+ bRet = sal_True;
+ aIter = aEnd;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+// TransferDataContainer
+// -----------------------------------------------------------------------------
+
+struct TDataCntnrEntry_Impl
+{
+ ::com::sun::star::uno::Any aAny;
+ SotFormatStringId nId;
+};
+
+// -----------------------------------------------------------------------------
+
+typedef ::std::list< TDataCntnrEntry_Impl > TDataCntnrEntryList;
+
+// -----------------------------------------------------------------------------
+
+struct TransferDataContainer_Impl
+{
+ TDataCntnrEntryList aFmtList;
+ Link aFinshedLnk;
+ INetBookmark* pBookmk;
+ Graphic* pGrf;
+
+ TransferDataContainer_Impl()
+ : pBookmk( 0 ), pGrf( 0 )
+ {
+ }
+
+ ~TransferDataContainer_Impl()
+ {
+ delete pBookmk;
+ delete pGrf;
+ }
+};
+
+// -----------------------------------------------------------------------------
+
+TransferDataContainer::TransferDataContainer()
+ : pImpl( new TransferDataContainer_Impl )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TransferDataContainer::~TransferDataContainer()
+{
+ delete pImpl;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::AddSupportedFormats()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferDataContainer::GetData( const
+ ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ TDataCntnrEntryList::iterator aIter( pImpl->aFmtList.begin() ),
+ aEnd( pImpl->aFmtList.end() );
+ sal_Bool bFnd = sal_False;
+ ULONG nFmtId = SotExchange::GetFormat( rFlavor );
+
+ // test first the list
+ for( ; aIter != aEnd; ++aIter )
+ {
+ TDataCntnrEntry_Impl& rEntry = (TDataCntnrEntry_Impl&)*aIter;
+ if( nFmtId == rEntry.nId )
+ {
+ bFnd = SetAny( rEntry.aAny, rFlavor );
+ break;
+ }
+ }
+
+ // test second the bookmark pointer
+ if( !bFnd )
+ switch( nFmtId )
+ {
+ case SOT_FORMAT_STRING:
+ case SOT_FORMATSTR_ID_SOLK:
+ case SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK:
+ case SOT_FORMATSTR_ID_FILECONTENT:
+ case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
+ case SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR:
+ if( pImpl->pBookmk )
+ bFnd = SetINetBookmark( *pImpl->pBookmk, rFlavor );
+ break;
+
+ case SOT_FORMATSTR_ID_SVXB:
+ case SOT_FORMAT_BITMAP:
+ case SOT_FORMAT_GDIMETAFILE:
+ if( pImpl->pGrf )
+ bFnd = SetGraphic( *pImpl->pGrf, rFlavor );
+ break;
+ }
+
+ return bFnd;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::ClearData()
+{
+ delete pImpl;
+ pImpl = new TransferDataContainer_Impl;
+ ClearFormats();
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyINetBookmark( const INetBookmark& rBkmk )
+{
+ if( !pImpl->pBookmk )
+ pImpl->pBookmk = new INetBookmark( rBkmk );
+ else
+ *pImpl->pBookmk = rBkmk;
+
+ AddFormat( SOT_FORMAT_STRING );
+ AddFormat( SOT_FORMATSTR_ID_SOLK );
+ AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
+ AddFormat( SOT_FORMATSTR_ID_FILECONTENT );
+ AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyAnyData( ULONG nFormatId,
+ const sal_Char* pData, ULONG nLen )
+{
+ if( nLen )
+ {
+ TDataCntnrEntry_Impl aEntry;
+ aEntry.nId = nFormatId;
+
+ Sequence< sal_Int8 > aSeq( nLen );
+ memcpy( aSeq.getArray(), pData, nLen );
+ aEntry.aAny <<= aSeq;
+ pImpl->aFmtList.push_back( aEntry );
+ AddFormat( nFormatId );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyByteString( ULONG nFormatId,
+ const ByteString& rStr )
+{
+ CopyAnyData( nFormatId, rStr.GetBuffer(), rStr.Len() );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyINetImage( const INetImage& rINtImg )
+{
+ SvMemoryStream aMemStm( 1024, 1024 );
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
+ rINtImg.Write( aMemStm, SOT_FORMATSTR_ID_INET_IMAGE );
+ CopyAnyData( SOT_FORMATSTR_ID_INET_IMAGE, (sal_Char*)aMemStm.GetData(),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyImageMap( const ImageMap& rImgMap )
+{
+ SvMemoryStream aMemStm( 8192, 8192 );
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
+ rImgMap.Write( aMemStm, String() );
+ CopyAnyData( SOT_FORMATSTR_ID_SVIM, (sal_Char*)aMemStm.GetData(),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyGraphic( const Graphic& rGrf )
+{
+ GraphicType nType = rGrf.GetType();
+ if( GRAPHIC_NONE != nType )
+ {
+ if( !pImpl->pGrf )
+ pImpl->pGrf = new Graphic( rGrf );
+ else
+ *pImpl->pGrf = rGrf;
+
+ AddFormat( SOT_FORMATSTR_ID_SVXB );
+ if( GRAPHIC_BITMAP == nType )
+ AddFormat( SOT_FORMAT_BITMAP );
+ else if( GRAPHIC_GDIMETAFILE == nType )
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyString( USHORT nFmt, const String& rStr )
+{
+ if( rStr.Len() )
+ {
+ TDataCntnrEntry_Impl aEntry;
+ aEntry.nId = nFmt;
+ rtl::OUString aStr( rStr );
+ aEntry.aAny <<= aStr;
+ pImpl->aFmtList.push_back( aEntry );
+ AddFormat( aEntry.nId );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyString( const String& rStr )
+{
+ CopyString( SOT_FORMAT_STRING, rStr );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::CopyAny( USHORT nFmt,
+ const ::com::sun::star::uno::Any& rAny )
+{
+ TDataCntnrEntry_Impl aEntry;
+ aEntry.nId = nFmt;
+ aEntry.aAny = rAny;
+ pImpl->aFmtList.push_back( aEntry );
+ AddFormat( aEntry.nId );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool TransferDataContainer::HasAnyData() const
+{
+ return pImpl->aFmtList.begin() != pImpl->aFmtList.end() ||
+ 0 != pImpl->pBookmk;
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::StartDrag(
+ Window* pWindow, sal_Int8 nDragSourceActions,
+ const Link& rLnk, sal_Int32 nDragPointer, sal_Int32 nDragImage )
+{
+ pImpl->aFinshedLnk = rLnk;
+ TransferableHelper::StartDrag( pWindow, nDragSourceActions,
+ nDragPointer, nDragImage );
+}
+
+// -----------------------------------------------------------------------------
+
+void TransferDataContainer::DragFinished( sal_Int8 nDropAction )
+{
+ if( pImpl->aFinshedLnk.IsSet() )
+ pImpl->aFinshedLnk.Call( &nDropAction );
+}
diff --git a/svtools/source/misc/unitconv.cxx b/svtools/source/misc/unitconv.cxx
new file mode 100644
index 000000000000..612bcb4f0221
--- /dev/null
+++ b/svtools/source/misc/unitconv.cxx
@@ -0,0 +1,763 @@
+/*************************************************************************
+ *
+ * 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: dlgutil.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+// include ---------------------------------------------------------------
+
+#include <svtools/unitconv.hxx>
+
+// -----------------------------------------------------------------------
+
+void SetFieldUnit( MetricField& rField, FieldUnit eUnit, BOOL bAll )
+{
+ sal_Int64 nFirst = rField.Denormalize( rField.GetFirst( FUNIT_TWIP ) );
+ sal_Int64 nLast = rField.Denormalize( rField.GetLast( FUNIT_TWIP ) );
+ sal_Int64 nMin = rField.Denormalize( rField.GetMin( FUNIT_TWIP ) );
+ sal_Int64 nMax = rField.Denormalize( rField.GetMax( FUNIT_TWIP ) );
+
+ if ( !bAll )
+ {
+ switch ( eUnit )
+ {
+ case FUNIT_M:
+ case FUNIT_KM:
+ eUnit = FUNIT_CM;
+ break;
+
+ case FUNIT_FOOT:
+ case FUNIT_MILE:
+ eUnit = FUNIT_INCH;
+ break;
+ default: ;//prevent warning
+ }
+ }
+ rField.SetUnit( eUnit );
+ switch( eUnit )
+ {
+ case FUNIT_MM:
+ rField.SetSpinSize( 50 );
+ break;
+
+ case FUNIT_INCH:
+ rField.SetSpinSize( 2 );
+ break;
+
+ default:
+ rField.SetSpinSize( 10 );
+ }
+
+ if ( FUNIT_POINT == eUnit )
+ {
+ if( rField.GetDecimalDigits() > 1 )
+ rField.SetDecimalDigits( 1 );
+ }
+ else
+ rField.SetDecimalDigits( 2 );
+
+ if ( !bAll )
+ {
+ rField.SetFirst( rField.Normalize( nFirst ), FUNIT_TWIP );
+ rField.SetLast( rField.Normalize( nLast ), FUNIT_TWIP );
+ rField.SetMin( rField.Normalize( nMin ), FUNIT_TWIP );
+ rField.SetMax( rField.Normalize( nMax ), FUNIT_TWIP );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SetFieldUnit( MetricBox& rBox, FieldUnit eUnit, BOOL bAll )
+{
+ sal_Int64 nMin = rBox.Denormalize( rBox.GetMin( FUNIT_TWIP ) );
+ sal_Int64 nMax = rBox.Denormalize( rBox.GetMax( FUNIT_TWIP ) );
+
+ if ( !bAll )
+ {
+ switch ( eUnit )
+ {
+ case FUNIT_M:
+ case FUNIT_KM:
+ eUnit = FUNIT_CM;
+ break;
+
+ case FUNIT_FOOT:
+ case FUNIT_MILE:
+ eUnit = FUNIT_INCH;
+ break;
+ default: ;//prevent warning
+ }
+ }
+ rBox.SetUnit( eUnit );
+
+ if ( FUNIT_POINT == eUnit && rBox.GetDecimalDigits() > 1 )
+ rBox.SetDecimalDigits( 1 );
+ else
+ rBox.SetDecimalDigits( 2 );
+
+ if ( !bAll )
+ {
+ rBox.SetMin( rBox.Normalize( nMin ), FUNIT_TWIP );
+ rBox.SetMax( rBox.Normalize( nMax ), FUNIT_TWIP );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SetMetricValue( MetricField& rField, long nCoreValue, SfxMapUnit eUnit )
+{
+ sal_Int64 nVal = OutputDevice::LogicToLogic( nCoreValue, (MapUnit)eUnit, MAP_100TH_MM );
+ nVal = rField.Normalize( nVal );
+ rField.SetValue( nVal, FUNIT_100TH_MM );
+
+}
+
+// -----------------------------------------------------------------------
+
+long GetCoreValue( const MetricField& rField, SfxMapUnit eUnit )
+{
+ sal_Int64 nVal = rField.GetValue( FUNIT_100TH_MM );
+ // avoid rounding issues
+ const sal_Int64 nSizeMask = 0xffffffffff000000LL;
+ bool bRoundBefore = true;
+ if( nVal >= 0 )
+ {
+ if( (nVal & nSizeMask) == 0 )
+ bRoundBefore = false;
+ }
+ else
+ {
+ if( ((-nVal) & nSizeMask ) == 0 )
+ bRoundBefore = false;
+ }
+ if( bRoundBefore )
+ nVal = rField.Denormalize( nVal );
+ sal_Int64 nUnitVal = OutputDevice::LogicToLogic( static_cast<long>(nVal), MAP_100TH_MM, (MapUnit)eUnit );
+ if( ! bRoundBefore )
+ nUnitVal = rField.Denormalize( nUnitVal );
+ return static_cast<long>(nUnitVal);
+}
+
+// -----------------------------------------------------------------------
+
+long CalcToUnit( float nIn, SfxMapUnit eUnit )
+{
+ // nIn ist in Points
+
+ DBG_ASSERT( eUnit == SFX_MAPUNIT_TWIP ||
+ eUnit == SFX_MAPUNIT_100TH_MM ||
+ eUnit == SFX_MAPUNIT_10TH_MM ||
+ eUnit == SFX_MAPUNIT_MM ||
+ eUnit == SFX_MAPUNIT_CM, "this unit is not implemented" );
+
+ float nTmp = nIn;
+
+ if ( SFX_MAPUNIT_TWIP != eUnit )
+ nTmp = nIn * 10 / 567;
+
+ switch ( eUnit )
+ {
+ case SFX_MAPUNIT_100TH_MM: nTmp *= 100; break;
+ case SFX_MAPUNIT_10TH_MM: nTmp *= 10; break;
+ case SFX_MAPUNIT_MM: break;
+ case SFX_MAPUNIT_CM: nTmp /= 10; break;
+ default: ;//prevent warning
+ }
+
+ nTmp *= 20;
+ long nRet = (long)nTmp;
+ return nRet;
+//! return (long)(nTmp * 20);
+}
+
+// -----------------------------------------------------------------------
+
+long ItemToControl( long nIn, SfxMapUnit eItem, SfxFieldUnit eCtrl )
+{
+ long nOut = 0;
+
+ switch ( eItem )
+ {
+ case SFX_MAPUNIT_100TH_MM:
+ case SFX_MAPUNIT_10TH_MM:
+ case SFX_MAPUNIT_MM:
+ {
+ if ( eItem == SFX_MAPUNIT_10TH_MM )
+ nIn /= 10;
+ else if ( eItem == SFX_MAPUNIT_100TH_MM )
+ nIn /= 100;
+ nOut = TransformMetric( nIn, FUNIT_MM, (FieldUnit)eCtrl );
+ }
+ break;
+
+ case SFX_MAPUNIT_CM:
+ {
+ nOut = TransformMetric( nIn, FUNIT_CM, (FieldUnit)eCtrl );
+ }
+ break;
+
+ case SFX_MAPUNIT_1000TH_INCH:
+ case SFX_MAPUNIT_100TH_INCH:
+ case SFX_MAPUNIT_10TH_INCH:
+ case SFX_MAPUNIT_INCH:
+ {
+ if ( eItem == SFX_MAPUNIT_10TH_INCH )
+ nIn /= 10;
+ else if ( eItem == SFX_MAPUNIT_100TH_INCH )
+ nIn /= 100;
+ else if ( eItem == SFX_MAPUNIT_1000TH_INCH )
+ nIn /= 1000;
+ nOut = TransformMetric( nIn, FUNIT_INCH, (FieldUnit)eCtrl );
+ }
+ break;
+
+ case SFX_MAPUNIT_POINT:
+ {
+ nOut = TransformMetric( nIn, FUNIT_POINT, (FieldUnit)eCtrl );
+ }
+ break;
+
+ case SFX_MAPUNIT_TWIP:
+ {
+ nOut = TransformMetric( nIn, FUNIT_TWIP, (FieldUnit)eCtrl );
+ }
+ break;
+ default: ;//prevent warning
+ }
+ return nOut;
+}
+
+// -----------------------------------------------------------------------
+
+long ControlToItem( long nIn, SfxFieldUnit eCtrl, SfxMapUnit eItem )
+{
+ return ItemToControl( nIn, eItem, eCtrl );
+}
+
+// -----------------------------------------------------------------------
+
+FieldUnit MapToFieldUnit( const SfxMapUnit eUnit )
+{
+ switch ( eUnit )
+ {
+ case SFX_MAPUNIT_100TH_MM:
+ case SFX_MAPUNIT_10TH_MM:
+ case SFX_MAPUNIT_MM:
+ return FUNIT_MM;
+
+ case SFX_MAPUNIT_CM:
+ return FUNIT_CM;
+
+ case SFX_MAPUNIT_1000TH_INCH:
+ case SFX_MAPUNIT_100TH_INCH:
+ case SFX_MAPUNIT_10TH_INCH:
+ case SFX_MAPUNIT_INCH:
+ return FUNIT_INCH;
+
+ case SFX_MAPUNIT_POINT:
+ return FUNIT_POINT;
+
+ case SFX_MAPUNIT_TWIP:
+ return FUNIT_TWIP;
+ default: ;//prevent warning
+ }
+ return FUNIT_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+MapUnit FieldToMapUnit( const SfxFieldUnit /*eUnit*/ )
+{
+ return MAP_APPFONT;
+}
+
+// -----------------------------------------------------------------------
+
+long ConvertValueToMap( long nVal, SfxMapUnit eUnit )
+{
+ long nNew = nVal;
+
+ switch ( eUnit )
+ {
+ case SFX_MAPUNIT_10TH_MM:
+ case SFX_MAPUNIT_10TH_INCH:
+ nNew *= 10;
+ break;
+
+ case SFX_MAPUNIT_100TH_MM:
+ case SFX_MAPUNIT_100TH_INCH:
+ nNew *= 100;
+ break;
+
+ case SFX_MAPUNIT_1000TH_INCH:
+ nNew *= 1000;
+ default: ;//prevent warning
+ }
+ return nNew;
+}
+
+// -----------------------------------------------------------------------
+
+long ConvertValueToUnit( long nVal, SfxMapUnit eUnit )
+{
+ long nNew = nVal;
+
+ switch ( eUnit )
+ {
+ case SFX_MAPUNIT_10TH_MM:
+ case SFX_MAPUNIT_10TH_INCH:
+ nNew /= 10;
+ break;
+
+ case SFX_MAPUNIT_100TH_MM:
+ case SFX_MAPUNIT_100TH_INCH:
+ nNew /= 100;
+ break;
+
+ case SFX_MAPUNIT_1000TH_INCH:
+ nNew /= 1000;
+ break;
+ default: ;//prevent warning
+ }
+ return nNew;
+}
+
+// -----------------------------------------------------------------------
+
+long CalcToPoint( long nIn, SfxMapUnit eUnit, USHORT nFaktor )
+{
+ DBG_ASSERT( eUnit == SFX_MAPUNIT_TWIP ||
+ eUnit == SFX_MAPUNIT_100TH_MM ||
+ eUnit == SFX_MAPUNIT_10TH_MM ||
+ eUnit == SFX_MAPUNIT_MM ||
+ eUnit == SFX_MAPUNIT_CM, "this unit is not implemented" );
+
+ long nRet = 0;
+
+ if ( SFX_MAPUNIT_TWIP == eUnit )
+ nRet = nIn;
+ else
+ nRet = nIn * 567;
+
+ switch ( eUnit )
+ {
+ case SFX_MAPUNIT_100TH_MM: nRet /= 100; break;
+ case SFX_MAPUNIT_10TH_MM: nRet /= 10; break;
+ case SFX_MAPUNIT_MM: break;
+ case SFX_MAPUNIT_CM: nRet *= 10; break;
+ default: ;//prevent warning
+ }
+
+ // ggf. aufrunden
+ if ( SFX_MAPUNIT_TWIP != eUnit )
+ {
+ long nMod = 10;
+ long nTmp = nRet % nMod;
+
+ if ( nTmp >= 4 )
+ nRet += 10 - nTmp;
+ nRet /= 10;
+ }
+ return nRet * nFaktor / 20;
+}
+
+// -----------------------------------------------------------------------
+
+long CMToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long MMToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 10;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long InchToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 1440 ) && nIn >= ( LONG_MIN / 1440 ) )
+ nRet = nIn * 1440;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PointToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
+ nRet = nIn * 20;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PicaToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 240 ) && nIn >= ( LONG_MIN / 240 ) )
+ nRet = nIn * 240;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long TwipsToCM( long nIn )
+{
+ long nRet = nIn / 567;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long InchToCM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
+ nRet = nIn * 254 / 100;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long MMToCM( long nIn )
+{
+ long nRet = nIn / 10;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PointToCM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
+ nRet = nIn * 20 / 567;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PicaToCM( long nIn)
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 12 / 20 ) && nIn >= ( LONG_MIN / 12 / 20 ) )
+ nRet = nIn * 12 * 20 / 567;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long TwipsToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
+ nRet = nIn * 10 / 566;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long CMToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
+ nRet = nIn * 10;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long InchToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
+ nRet = nIn * 254 / 10;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PointToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 200 ) && nIn >= ( LONG_MIN / 200 ) )
+ nRet = nIn * 200 / 567;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PicaToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 12 / 200 ) && nIn >= ( LONG_MIN / 12 / 200 ) )
+ nRet = nIn * 12 * 200 / 567;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long TwipsToInch( long nIn )
+{
+ long nRet = nIn / 1440;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long CMToInch( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 100 ) && nIn >= ( LONG_MIN / 100 ) )
+ nRet = nIn * 100 / 254;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long MMToInch( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
+ nRet = nIn * 10 / 254;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PointToInch( long nIn )
+{
+ long nRet = nIn / 72;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PicaToInch( long nIn )
+{
+ long nRet = nIn / 6;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long TwipsToPoint( long nIn )
+{
+ long nRet = nIn / 20;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long InchToPoint( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 72 ) && nIn >= ( LONG_MIN / 72 ) )
+ nRet = nIn * 72;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long CMToPoint( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 20;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long MMToPoint( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 200;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PicaToPoint( long nIn )
+{
+ long nRet = nIn / 12;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long TwipsToPica( long nIn )
+{
+ long nRet = nIn / 240;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long InchToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 6 ) && nIn >= ( LONG_MIN / 6 ) )
+ nRet = nIn * 6;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long PointToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 12 ) && nIn >= ( LONG_MIN / 12 ) )
+ nRet = nIn * 12;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long CMToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 20 / 12;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long MMToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 200 / 12;
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long Nothing( long nIn )
+{
+ long nRet = nIn;
+ return nRet;
+}
+
+FUNC_CONVERT ConvertTable[6][6] =
+{
+// CM, MM INCH POINT PICAS=32 TWIPS
+ { Nothing, CMToMM, CMToInch, CMToPoint, CMToPica, CMToTwips },
+ { MMToCM, Nothing, MMToInch, MMToPoint, MMToPica, MMToTwips },
+ { InchToCM, InchToMM, Nothing, InchToPoint, InchToPica, InchToTwips },
+ { PointToCM, PointToMM, PointToInch, Nothing, PointToPica, PointToTwips },
+ { PicaToCM, PicaToMM, PicaToInch, PicaToPoint, Nothing, PicaToTwips },
+ { TwipsToCM, TwipsToMM, TwipsToInch, TwipsToPoint,TwipsToPica, Nothing }
+};
+
+// -----------------------------------------------------------------------
+
+long TransformMetric( long nVal, FieldUnit aOld, FieldUnit aNew )
+{
+ if ( aOld == FUNIT_NONE || aNew == FUNIT_NONE ||
+ aOld == FUNIT_CUSTOM || aNew == FUNIT_CUSTOM )
+ {
+ return nVal;
+ }
+
+ USHORT nOld = 0;
+ USHORT nNew = 0;
+
+ switch ( aOld )
+ {
+ case FUNIT_CM:
+ nOld = 0; break;
+ case FUNIT_MM:
+ nOld = 1; break;
+ case FUNIT_INCH:
+ nOld = 2; break;
+ case FUNIT_POINT:
+ nOld = 3; break;
+ case FUNIT_PICA:
+ nOld = 4; break;
+ case FUNIT_TWIP:
+ nOld = 5; break;
+ default: ;//prevent warning
+ }
+
+ switch ( aNew )
+ {
+ case FUNIT_CM:
+ nNew = 0; break;
+ case FUNIT_MM:
+ nNew = 1; break;
+ case FUNIT_INCH:
+ nNew = 2; break;
+ case FUNIT_POINT:
+ nNew = 3; break;
+ case FUNIT_PICA:
+ nNew = 4; break;
+ case FUNIT_TWIP:
+ nNew = 5; break;
+ default: ;//prevent warning
+ }
+ return ConvertTable[nOld][nNew]( nVal );
+}
+
diff --git a/svtools/source/misc/wallitem.cxx b/svtools/source/misc/wallitem.cxx
new file mode 100644
index 000000000000..505af52c9908
--- /dev/null
+++ b/svtools/source/misc/wallitem.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_svtools.hxx"
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <tools/color.hxx>
+
+#include <vcl/graph.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/cvtgrf.hxx>
+
+#include "wallitem.hxx"
+#include <svl/cntwall.hxx>
+
+// -----------------------------------------------------------------------
+
+//static
+void SfxBrushItemLink::Set( SfxBrushItemLink* pLink )
+{
+ SfxBrushItemLink** ppLink = (SfxBrushItemLink**)GetAppData(SHL_BRUSHITEM);
+ if( !*ppLink )
+ *ppLink = pLink;
+ else
+ delete pLink;
+}
+
diff --git a/svtools/source/misc/xwindowitem.cxx b/svtools/source/misc/xwindowitem.cxx
new file mode 100755
index 000000000000..a382d8293617
--- /dev/null
+++ b/svtools/source/misc/xwindowitem.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_svtools.hxx"
+
+#include "svtools/xwindowitem.hxx"
+
+#include <vcl/window.hxx>
+
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////
+
+TYPEINIT1_FACTORY( XWindowItem, SfxPoolItem, new XWindowItem );
+
+
+XWindowItem::XWindowItem() :
+ SfxPoolItem()
+{
+}
+
+
+XWindowItem::XWindowItem( USHORT nWhichId, Window * pWin ) :
+ SfxPoolItem( nWhichId )
+{
+ if (pWin)
+ {
+ m_xWin = uno::Reference< awt::XWindow >( pWin->GetComponentInterface(), uno::UNO_QUERY );
+ // the assertion can't possibly fails since VCLXWindow implements XWindow...
+ DBG_ASSERT( m_xWin.is(), "failed to get XWindow" );
+ }
+}
+
+
+XWindowItem::XWindowItem( USHORT nWhichId, uno::Reference< awt::XWindow > & rxWin ) :
+ SfxPoolItem( nWhichId ),
+ m_xWin( rxWin )
+{
+}
+
+
+XWindowItem::XWindowItem( const XWindowItem &rItem ) :
+ SfxPoolItem( Which() ),
+ m_xWin( rItem.m_xWin )
+{
+}
+
+
+XWindowItem::~XWindowItem()
+{
+}
+
+
+SfxPoolItem * XWindowItem::Clone( SfxItemPool* /*pPool*/ ) const
+{
+ return new XWindowItem( *this );
+}
+
+
+int XWindowItem::operator == ( const SfxPoolItem & rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ const XWindowItem * pItem = dynamic_cast< const XWindowItem * >(&rAttr);
+ return pItem ? m_xWin == pItem->m_xWin : 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+
diff --git a/svtools/source/plugapp/commtest.cxx b/svtools/source/plugapp/commtest.cxx
new file mode 100644
index 000000000000..3a235afcc61b
--- /dev/null
+++ b/svtools/source/plugapp/commtest.cxx
@@ -0,0 +1,261 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/toolbox.hxx>
+
+
+#include <tools/simplecm.hxx>
+#include "communi.hxx"
+#include "brooker.hxx"
+//#include <tools/bcst.hxx>
+
+#include "commtest.hrc"
+
+
+
+#define TCP_PORT 17612
+
+#define CUniString( constAsciiStr ) UniString( RTL_CONSTASCII_USTRINGPARAM ( constAsciiStr ) )
+
+
+class PacketSender : public Timer
+{
+ SvStream* mpData;
+ CommunicationLinkRef mxCL;
+
+public:
+ PacketSender( ULONG nDelay, SvStream* pData, CommunicationLink* pCL );
+ virtual void Timeout();
+};
+
+PacketSender::PacketSender( ULONG nDelay, SvStream* pData, CommunicationLink* pCL )
+: mpData( pData )
+, mxCL( pCL )
+{
+ SetTimeout( nDelay );
+ Start();
+}
+
+void PacketSender::Timeout()
+{
+ mxCL->TransferDataStream( mpData );
+ delete mpData;
+ delete this;
+}
+
+
+
+class DelayedDeleter : public Timer
+{
+ CommunicationManager *mpManager;
+
+public:
+ DelayedDeleter( ULONG nDelay, CommunicationManager *pManager );
+ virtual void Timeout();
+};
+
+DelayedDeleter::DelayedDeleter( ULONG nDelay, CommunicationManager *pManager )
+: mpManager( pManager )
+{
+ SetTimeout( nDelay );
+ Start();
+}
+
+void DelayedDeleter::Timeout()
+{
+ delete mpManager;
+ delete this;
+}
+
+
+
+
+class CommunicationTester : public Application
+{
+ DECL_LINK( TBClick, ToolBox* );
+ DECL_LINK( DataReceived, CommunicationLink* );
+ DECL_LINK( ConnectionOpened, CommunicationLink* );
+ DECL_LINK( ConnectionClosed, CommunicationLink* );
+
+
+ CommunicationManager *pClientTcp, *pServerTcp;
+ InformationBroadcaster *pBCSTSend;
+ InformationBroadcaster *pBCSTListen;
+ InformationBrooker *pBCSTBrooker;
+public:
+ CommunicationTester();
+
+ virtual void Main();
+};
+
+CommunicationTester IchSelber;
+
+CommunicationTester::CommunicationTester()
+: pClientTcp( NULL )
+, pServerTcp( NULL )
+, pBCSTSend( NULL )
+, pBCSTListen( NULL )
+, pBCSTBrooker( NULL )
+{}
+
+void CommunicationTester::Main()
+{
+ ResMgr *pRes = ResMgr::CreateResMgr( "commtest" );
+ Resource::SetResManager( pRes );
+ WorkWindow aWW( NULL, WB_APP | WB_STDWORK );
+ aWW.Show();
+ ToolBox aTB( &aWW, ResId( TBMenu ) );
+ aTB.Show();
+ aTB.RecalcItems();
+ aTB.SetFloatingMode( TRUE );
+ aTB.SetFloatingMode( FALSE );
+ aTB.SetClickHdl( LINK( this, CommunicationTester, TBClick ) );
+
+ Execute();
+}
+
+#define SWITCH( pManager, ManagerClass ) \
+{ \
+ if ( pManager ) \
+ { \
+ pManager->StopCommunication(); \
+ new DelayedDeleter( 1000, pManager ); \
+ pTB->SetItemState( pTB->GetCurItemId(), STATE_NOCHECK ); \
+ pManager = NULL; \
+ } \
+ else \
+ { \
+ pManager = new ManagerClass; \
+ pManager->SetConnectionOpenedHdl( LINK( this, CommunicationTester, ConnectionOpened ) );\
+ pManager->SetConnectionClosedHdl( LINK( this, CommunicationTester, ConnectionClosed ) );\
+ pManager->SetDataReceivedHdl( LINK( this, CommunicationTester, DataReceived ) );\
+ pTB->SetItemState( pTB->GetCurItemId(), STATE_CHECK ); \
+ } \
+}
+
+
+IMPL_LINK( CommunicationTester, TBClick, ToolBox*, pTB )
+{
+ switch ( pTB->GetCurItemId() )
+ {
+ case SERVER_TCP:
+ {
+ SWITCH( pServerTcp, CommunicationManagerServerViaSocket( TCP_PORT, (USHORT) 32000 ) );
+ if ( pServerTcp )
+ pServerTcp->StartCommunication(); // Am Port horchen
+ }
+ break;
+ case CLIENT_TCP:
+ {
+ SWITCH( pClientTcp, CommunicationManagerClientViaSocket( "localhost", TCP_PORT ) );
+ if ( pClientTcp )
+ pClientTcp->StartCommunication(); // Eine Verbindung aufbauen
+ }
+ break;
+ case BCST_BROOKER:
+ {
+ if ( pBCSTBrooker )
+ {
+ delete pBCSTBrooker;
+ pBCSTBrooker = NULL;
+ }
+ else
+ {
+ pBCSTBrooker = new InformationBrooker();
+ }
+ }
+ break;
+ case BCST_LISTEN:
+ {
+ if ( pBCSTListen )
+ {
+ delete pBCSTListen;
+ pBCSTListen = NULL;
+ }
+ else
+ {
+ pBCSTListen = new InformationBroadcaster();
+ }
+ }
+ case BCST_SEND:
+ {
+ if ( pBCSTSend )
+ {
+ pBCSTSend->Broadcast( BCST_CAT_PL2X, "Message: BCST_CAT_PL2X" );
+ pBCSTSend->Broadcast( BCST_CAT_MINORCOPY, "Message: BCST_CAT_MINORCOPY" );
+ pBCSTSend->Broadcast( BCST_CAT_DELIVER, "Message: BCST_CAT_DELIVER" );
+ pBCSTSend->Broadcast( BCST_CAT_ALL, "Message: BCST_CAT_ALL" );
+ }
+ else
+ {
+ pBCSTSend = new InformationBroadcaster();
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+IMPL_LINK( CommunicationTester, ConnectionOpened, CommunicationLink*, pCL )
+{
+ SvStream *pData = pCL->GetBestCommunicationStream();
+ while ( pData->Tell() < 70 ) *pData << 123;
+
+ pCL->TransferDataStream( pData );
+ return 0;
+}
+
+IMPL_LINK( CommunicationTester, ConnectionClosed, CommunicationLink*, pCL )
+{
+ return 0;
+}
+
+IMPL_LINK( CommunicationTester, DataReceived, CommunicationLink*, pCL )
+{
+ // Find Manager
+ CommunicationManager* pManager;
+ if ( pClientTcp && pClientTcp->IsLinkValid( pCL ) )
+ {
+ pManager = pClientTcp;
+ }
+ if ( pServerTcp && pServerTcp->IsLinkValid( pCL ) )
+ {
+ DBG_ASSERT( !pManager, "CommunicationLink bei mehreren Managern eingetragen");
+ pManager = pServerTcp;
+ }
+ DBG_ASSERT( pCL->GetCommunicationManager() == pManager, "Manager des Link != Manager bei dem der Link Valid ist");
+
+ // Send Data Back (Echo)
+ new PacketSender( 1000, pCL->GetServiceData(), pCL );
+
+ return 0;
+}
+
diff --git a/svtools/source/plugapp/commtest.hrc b/svtools/source/plugapp/commtest.hrc
new file mode 100644
index 000000000000..f0f646b49bfc
--- /dev/null
+++ b/svtools/source/plugapp/commtest.hrc
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 TBMenu 256
+
+
+#define SERVER_TCP 1
+#define CLIENT_TCP 2
+#define BCST_BROOKER 3
+#define BCST_LISTEN 4
+#define BCST_SEND 5
diff --git a/svtools/source/plugapp/commtest.src b/svtools/source/plugapp/commtest.src
new file mode 100644
index 000000000000..7073699f4956
--- /dev/null
+++ b/svtools/source/plugapp/commtest.src
@@ -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 "commtest.hrc"
+
+ToolBox TBMenu {
+ Border = TRUE;
+ SVLook = TRUE;
+ Dockable = TRUE;
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 100, 20 );
+ LineCount = 2;
+// FloatingLines = 2;
+ ItemList = {
+ ToolBoxItem {
+ Identifier = SERVER_TCP;
+ Text = "Server TCP";
+ };
+ ToolBoxItem {
+ Identifier = CLIENT_TCP;
+ Text = "Client TCP";
+ };
+ ToolBoxItem {
+ Identifier = BCST_BROOKER;
+ Text = "BroadcastBrooker";
+ };
+ ToolBoxItem {
+ Identifier = BCST_SEND;
+ Text = "BroadcastClientSend";
+ };
+ ToolBoxItem {
+ Identifier = BCST_LISTEN;
+ Text = "BroadcastClientListen";
+ };
+ };
+ Scroll = TRUE;
+};
diff --git a/svtools/source/plugapp/makefile.mk b/svtools/source/plugapp/makefile.mk
new file mode 100644
index 000000000000..f1dd0a4a8334
--- /dev/null
+++ b/svtools/source/plugapp/makefile.mk
@@ -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.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=plugapp
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/ttprops.obj
+
+
+SRS2NAME=$(TARGET)
+SRC2FILES= testtool.src
+
+
+LIB1TARGET= $(SLB)$/plugapp.lib
+LIB1OBJFILES= $(SLOFILES)
+
+######## Testapplikation #########
+
+SRC1FILES= commtest.src
+SRS1NAME= commtest
+
+######## Ende Testapplikation #########
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/plugapp/testtool.hrc b/svtools/source/plugapp/testtool.hrc
new file mode 100644
index 000000000000..d6a234b74236
--- /dev/null
+++ b/svtools/source/plugapp/testtool.hrc
@@ -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.
+ *
+ ************************************************************************/
+#define TTSTART 12345
+
+#define DisplayHidToolBox ( TTSTART + 0 )
+#define TT_SHOW 1
+#define TT_SHOW2 ( TTSTART + 1 )
+#define TT_OUTPUT 3
+#define TT_SEND_DATA 4
+#define TT_ALLWIN 5
+#define TT_KURZNAME 6
+#define TT_LANGNAME 7
+#define TT_ALTERNATE_CAPTION ( TTSTART + 2 )
+
+#define TT_INLINE_TRANSLATION ( TTSTART + 3)
+#define TT_GB_TRANSLATION 1
+#define TT_E_NEW 2
+#define TT_FT_OLD 3
+#define TT_GB_COMMENT 4
+#define TT_E_COMMENT 5
+
+#define TT_PB_SELECT 6
+#define TT_PB_RESTORE 7
+#define TT_PB_ACCEPT 8
+#define TT_PB_NEXT 9
+
+#define TT_DISCARD_CHANGED_DATA ( TTSTART + 4 )
+#define TT_NO_CONTROL ( TTSTART + 5 )
+
+
+#define TT_GPF ( TTSTART + 6 )
diff --git a/svtools/source/plugapp/testtool.src b/svtools/source/plugapp/testtool.src
new file mode 100644
index 000000000000..9cc52c58f013
--- /dev/null
+++ b/svtools/source/plugapp/testtool.src
@@ -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 "testtool.hrc"
+#include <svl/solar.hrc>
+
+
+#define Control_Control 5
+#define Control_Border 7
+#define Button_Button Control_Control
+#define ButtonWidth 40
+
+
+ToolBox DisplayHidToolBox {
+ SVLook = TRUE ;
+ ItemList = {
+ ToolBoxItem {
+ Type = TOOLBOXITEM_BUTTON;
+ _ToolBoxItemFlags = TIB_AUTOCHECK ;
+
+/*
+class FlagToolBoxState
+{
+ TIB_CHECKABLE, TIB_AUTOCHECK, TIB_RADIOCHECK, TIB_LEFT,
+ TIB_AUTOSIZE, TIB_DROPDOWN,
+};*/
+ Identifier = TT_SHOW;
+ ItemBitmap = Bitmap {
+ File = "ttshow.bmp";
+ };
+ Text[ en-US ] = "Display IDs";
+ };
+ ToolBoxItem {
+ Type = TOOLBOXITEM_SEPARATOR;
+ };
+ ToolBoxItem {
+ _ToolBoxItemFlags = TIB_AUTOSIZE;
+ Identifier = TT_OUTPUT;
+ Text[ en-US ] = "This is the input window";
+ };
+ ToolBoxItem {
+ Type = TOOLBOXITEM_SEPARATOR;
+ };
+ ToolBoxItem {
+ Identifier = TT_SEND_DATA;
+ ItemBitmap = Bitmap {
+ File = "ttremote.bmp";
+ };
+ Text[ en-US ] = "Transfer to TestTool";
+ };
+ ToolBoxItem {
+ Type = TOOLBOXITEM_SEPARATOR;
+ };
+ ToolBoxItem {
+ Identifier = TT_ALLWIN;
+ ItemBitmap = Bitmap {
+ File = "ttall.bmp";
+ };
+ Text[ en-US ] = "Show all windows";
+ };
+ ToolBoxItem {
+ Identifier = TT_KURZNAME;
+ ItemBitmap = Bitmap {
+ File = "ttdef.bmp";
+ };
+ Text[ en-US ] = "Show short names (if available)";
+ };
+ ToolBoxItem {
+ Identifier = TT_LANGNAME;
+ ItemBitmap = Bitmap {
+ File = "tthid.bmp";
+ };
+ Text[ en-US ] = "Always show long-name";
+ };
+ };
+ Text[ en-US ] = "DisplayHID";
+};
+
+Bitmap TT_SHOW2 {
+ File = "ttshow2.bmp";
+};
+
+WorkWindow TT_INLINE_TRANSLATION {
+ SVLook = TRUE;
+ Size = MAP_APPFONT( 2*Control_Border + 4*ButtonWidth + 3*Button_Button, 120 );
+ Moveable = TRUE;
+ Sizeable = TRUE;
+ Closeable = TRUE;
+ Border = TRUE;
+ GroupBox TT_GB_TRANSLATION {
+ Pos = MAP_APPFONT( 2, 3 );
+ Size = MAP_APPFONT( 173, 44 );
+ Text[ en-US ] = "Translation";
+ };
+ Edit TT_E_NEW {
+ Disable = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT( 7, 16 );
+ Size = MAP_APPFONT( 162, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Edit";
+ };
+ FixedText TT_FT_OLD {
+ Pos = MAP_APPFONT( 7, 33 );
+ Size = MAP_APPFONT( 162, 10 );
+ Text[ en-US ] = "Original Text";
+ };
+ GroupBox TT_GB_COMMENT {
+ Pos = MAP_APPFONT( 2, 52 );
+ Size = MAP_APPFONT( 173, 32 );
+ Text[ en-US ] = "Comment";
+ };
+ Edit TT_E_COMMENT {
+ Disable = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT( 7, 64 );
+ Size = MAP_APPFONT( 162, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Comment";
+ };
+ PushButton TT_PB_SELECT {
+ Pos = MAP_APPFONT( Control_Border, 89 );
+ Size = MAP_APPFONT( ButtonWidth, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Select";
+ };
+ PushButton TT_PB_RESTORE {
+ Disable = TRUE;
+ Pos = MAP_APPFONT( Control_Border + ButtonWidth + Button_Button, 89 );
+ Size = MAP_APPFONT( ButtonWidth, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Restore";
+ };
+ PushButton TT_PB_ACCEPT {
+ Disable = TRUE;
+ Pos = MAP_APPFONT( Control_Border + 2*(ButtonWidth + Button_Button), 89 );
+ Size = MAP_APPFONT( ButtonWidth, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Accept";
+ };
+ PushButton TT_PB_NEXT {
+ Pos = MAP_APPFONT( Control_Border + 3*(ButtonWidth + Button_Button), 89 );
+ Size = MAP_APPFONT( ButtonWidth, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Next";
+ };
+ Text[ en-US ] = "Inplace Translation";
+};
+
+MessBox TT_DISCARD_CHANGED_DATA {
+ Buttons = WB_YES_NO;
+ DefButton = WB_DEF_YES;
+ Message[ en-US ] = "The Translation will be lost. Proceed anyway?";
+};
+
+ErrorBox TT_NO_CONTROL {
+ Buttons = WB_OK;
+ DefButton = WB_DEF_OK;
+ Message[ en-US ] = "The Control is no longer valid. The Translation cannot be saved.";
+};
+
+String TT_GPF
+{
+ Text[ en-US ] = "GPF occurred";
+};
+
+String TT_ALTERNATE_CAPTION
+{
+ Text[ en-US ] = "HelpID does not match UniqueID: ";
+};
+
diff --git a/svtools/source/plugapp/ttprops.cxx b/svtools/source/plugapp/ttprops.cxx
new file mode 100644
index 000000000000..2ae41a4c50c1
--- /dev/null
+++ b/svtools/source/plugapp/ttprops.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_svtools.hxx"
+#include <svtools/ttprops.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/bitmap.hxx>
+#include <tools/rtti.hxx>
+
+TYPEINIT1( TTProperties, ApplicationProperty )
+
+BOOL TTProperties::RequestProperty( USHORT nRequest )
+{
+ if ( (( nRequest & TT_PR_ONCE ) == 0) || (nDonePRs & (nRequest & 0x0ff)) == 0 )
+ {
+ nActualPR = nRequest;
+ nDonePRs |= nRequest;
+ GetpApp()->Property( *this );
+ return nActualPR == 0;
+ }
+ return TRUE;
+}
+
+
+BOOL TTProperties::GetSlots()
+{
+ RequestProperty( TT_PR_SLOTS );
+ return HasSlots();
+}
+
+USHORT TTProperties::ExecuteFunction( USHORT nSID, SfxPoolItem** ppArgs, USHORT nMode )
+{
+ mnSID = nSID;
+ mppArgs = ppArgs;
+ mnMode = nMode;
+ RequestProperty( TT_PR_DISPATCHER );
+ mppArgs = NULL;
+ return nActualPR;
+}
+
+BOOL TTProperties::Img( Bitmap *pBmp )
+{
+ BOOL bRet;
+ mpBmp = pBmp;
+ bRet = RequestProperty( TT_PR_IMG );
+ mpBmp = NULL;
+ return bRet;
+}
+
+SvtResId TTProperties::GetSvtResId( USHORT nId )
+{
+ return SvtResId( nId );
+}
+
diff --git a/svtools/source/productregistration/makefile.mk b/svtools/source/productregistration/makefile.mk
new file mode 100644
index 000000000000..a26e8feca753
--- /dev/null
+++ b/svtools/source/productregistration/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=svtools
+TARGET=productregistration.uno
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+GEN_HID=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE=
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/productregistration.obj \
+ $(SLO)$/registrationdlg.obj
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1OBJS= \
+ $(SLOFILES)
+
+SHL1STDLIBS=\
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1NAME= $(SHL1TARGET)
+
+SRS1NAME= productregistration
+SRC1FILES= \
+ registrationdlg.src
+
+RESLIB1NAME=productregistration
+RESLIB1IMAGES=$(PRJ)$/res
+RESLIB1SRSFILES=\
+ $(SRS)$/productregistration.srs
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/productregistration/productregistration.cxx b/svtools/source/productregistration/productregistration.cxx
new file mode 100644
index 000000000000..39629f5c3f77
--- /dev/null
+++ b/svtools/source/productregistration/productregistration.cxx
@@ -0,0 +1,507 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "productregistration.hxx"
+#include "unotools/regoptions.hxx"
+#include "registrationdlg.hxx"
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#include "cppuhelper/factory.hxx"
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <osl/diagnose.h>
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+
+#define PRODREG_IMPLNAME "com.sun.star.comp.setup.ProductRegistration"
+#define PRODREG_SERVNAME "com.sun.star.setup.ProductRegistration"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::container;
+
+using rtl::OUString;
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using namespace ::com::sun::star::task;
+ using namespace ::com::sun::star::system;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::frame;
+ using namespace ::com::sun::star::awt;
+
+ //-------------------------------------------------------------------
+
+ struct EqualsOUString : public ::std::unary_function< OUString, sal_Bool >
+ {
+ const OUString& m_rCompare;
+ EqualsOUString( const OUString& _rCompare ) : m_rCompare( _rCompare ) { }
+
+ sal_Bool operator() ( const OUString& _rCompare )
+ {
+ return m_rCompare.equals( _rCompare );
+ }
+ };
+
+ //====================================================================
+ //= OProductRegistration
+ //====================================================================
+
+ //--------------------------------------------------------------------
+ OProductRegistration::OProductRegistration( const Reference< XMultiServiceFactory >& _rxORB )
+ :m_xORB( _rxORB )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInterface > OProductRegistration::Create( const Reference< XMultiServiceFactory >& _rxORB )
+ {
+ return static_cast< ::cppu::OWeakObject* >( new OProductRegistration( _rxORB ) );
+ }
+
+ //--------------------------------------------------------------------
+ OUString SAL_CALL OProductRegistration::getImplementationName_Static( )
+ {
+ return OUString::createFromAscii( PRODREG_IMPLNAME );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< OUString > SAL_CALL OProductRegistration::getSupportedServiceNames_Static( ) throw (RuntimeException)
+ {
+ Sequence< OUString > aServiceNames( 1 );
+ aServiceNames[ 0 ] = OUString::createFromAscii( PRODREG_SERVNAME );
+ return aServiceNames;
+ }
+
+ //--------------------------------------------------------------------
+ OUString SAL_CALL OProductRegistration::getImplementationName( ) throw (RuntimeException)
+ {
+ return getImplementationName_Static( );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SAL_CALL OProductRegistration::supportsService( const OUString& _rServiceName ) throw (RuntimeException)
+ {
+ Sequence< OUString > aServiceNames( getSupportedServiceNames( ) );
+ const OUString* pNames = aServiceNames.getConstArray( );
+ const OUString* pNamesEnd = aServiceNames.getConstArray( ) + aServiceNames.getLength();
+
+ const OUString* pFound = ::std::find_if(
+ pNames,
+ pNamesEnd,
+ EqualsOUString( _rServiceName )
+ );
+ return pFound != pNamesEnd;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< OUString > SAL_CALL OProductRegistration::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ return getSupportedServiceNames_Static( );
+ }
+
+ //--------------------------------------------------------------------
+ static Reference< XFrame > lcl_getActiveFrame( const Reference< XMultiServiceFactory >& xFactory )
+ {
+ try
+ {
+ Reference< XDesktop > xDesktop(
+ xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ) ),
+ UNO_QUERY_THROW );
+
+ Reference< XFrame > xFrame(xDesktop->getCurrentFrame());
+ if( ! xFrame.is() )
+ {
+ // Perhaps the frames collection of the desktop knows about an "active frame"?
+ Reference< XFramesSupplier > xFrames( xDesktop, UNO_QUERY_THROW );
+ xFrame = xFrames->getActiveFrame();
+ }
+
+ return xFrame;
+ }
+ catch(const Exception& )
+ {
+ OSL_ENSURE( sal_False, "lcl_getActiveFrame: caught an exception!" );
+ return Reference< XFrame >();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ static Window* lcl_getPreferredDialogParent( const Reference< XFrame >& xFrame )
+ {
+ Window* pReturn = Application::GetDefDialogParent();
+
+ try
+ {
+ if ( xFrame.is() )
+ {
+ Reference< XWindow > xWindow = xFrame->getContainerWindow();
+ if ( xWindow.is() )
+ pReturn = VCLUnoHelper::GetWindow( xWindow );
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "lcl_getPreferredDialogParent: caught an exception!" );
+ }
+
+ return pReturn;
+ }
+
+ //--------------------------------------------------------------------
+ static bool lcl_isEvalVersion( const Reference< XMultiServiceFactory >& _rxORB )
+ {
+ bool bIsEvaluationVersion = false;
+
+ try
+ {
+ Reference < XMaterialHolder > xHolder(
+ _rxORB->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.tab.tabreg" ) ) ),
+ UNO_QUERY
+ );
+
+ if ( xHolder.is() )
+ {
+ Any aData = xHolder->getMaterial();
+ Sequence < NamedValue > aSeq;
+
+ if ( aData >>= aSeq )
+ {
+ // it's an evaluation version - a non-eval version wouldn't provide this "material"
+ bIsEvaluationVersion = true;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( false, "lcl_isEvalVersion: caught an exception!" );
+ }
+
+ return bIsEvaluationVersion;
+ }
+
+ //--------------------------------------------------------------------
+ static bool lcl_doNewStyleRegistration( const Reference< XMultiServiceFactory >& xFactory, bool online )
+ {
+ try
+ {
+ Reference< XMultiServiceFactory > xConfigProvider(
+ xFactory->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) )
+ ),
+ UNO_QUERY_THROW
+ );
+
+ PropertyValue aNodePath;
+ aNodePath.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aNodePath.Value = makeAny( OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Jobs/Events" ) ) );
+
+ Sequence< Any > lArguments(1);
+ lArguments[0] = makeAny( aNodePath );
+
+ Reference< XHierarchicalNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
+ lArguments
+ ),
+ UNO_QUERY_THROW
+ );
+
+ if( ! xNameAccess->hasByHierarchicalName( OUString( RTL_CONSTASCII_USTRINGPARAM( "onRegisterNow/JobList" ) ) ) )
+ return false;
+
+ Reference< XJobExecutor > xJobExecutor(
+ xFactory->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.JobExecutor" ) )
+ ),
+ UNO_QUERY_THROW
+ );
+
+ xJobExecutor->trigger( online ? OUString( RTL_CONSTASCII_USTRINGPARAM( "onRegisterNow" ) ) :
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "onRegisterLater" ) ) );
+
+ return true;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( false, "lcl_getOnlineRegistrationDispatch: caught an exception!" );
+ return false;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OProductRegistration::trigger( const OUString& _rEvent ) throw (RuntimeException)
+ {
+ bool registerOnline = false;
+
+ switch ( classify( _rEvent ) )
+ {
+ case etRegistrationRequired:
+ registerOnline = true;
+ break;
+
+ default:
+ break;
+ }
+
+ // prefer new style registration
+ if( ! lcl_doNewStyleRegistration(m_xORB, registerOnline ) && registerOnline )
+ doOnlineRegistration();
+ }
+
+ //--------------------------------------------------------------------
+ Any SAL_CALL OProductRegistration::execute( const Sequence< NamedValue >& ) throw (IllegalArgumentException, Exception, RuntimeException)
+ {
+ Any aReturn;
+
+ static sal_Bool bFirstEncounter( sal_True );
+ if ( bFirstEncounter )
+ { // during this session, this event was never triggered before ....
+ bFirstEncounter = sal_False;
+
+ sal_Bool bDeactivateJob = sal_True;
+
+ // our config options
+ utl::RegOptions aRegOptions;
+ // check them for the permissions for the dialog
+ utl::RegOptions::DialogPermission ePermission( aRegOptions.getDialogPermission() );
+
+ if ( utl::RegOptions::dpDisabled != ePermission )
+ { // the dialog is _not_ disabled
+
+ // for this session, I'm no interested in the dialog registration anymore
+ aRegOptions.markSessionDone( );
+
+ if ( ( utl::RegOptions::dpNotThisSession == ePermission ) // first trigger session not reached
+ || ( utl::RegOptions::dpRemindLater == ePermission ) // or at a later reminder date
+ )
+ { // the dialog should be executed during one of the next sessions
+ bDeactivateJob = sal_False;
+ }
+ else
+ {
+ // if we're here, the dialog should be executed during this session
+ OSL_ENSURE( utl::RegOptions::dpThisSession == ePermission, "OProductRegistration::execute: invalid permissions!" );
+
+ {
+ // this is some kind of HACK.
+ // This registration dialog is intended to appear very very early during the
+ // first office start after installation. Unfortunately, this is so early
+ // that even SFX is not yet loaded, thus the SfxHelp class is not yet available,
+ // thus, there is no help during the lifetime of the dialog.
+ // To fake this, we explicitly load the necessary services when the user
+ // really requests help herein.
+ // #110791# - 2003-06-11 - fs@openoffice.org
+ Reference < XInitialization > xOfficeWrapper(
+ m_xORB->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.OfficeWrapper" ) )
+ ),
+ UNO_QUERY
+ );
+ if ( xOfficeWrapper.is() )
+ xOfficeWrapper->initialize( Sequence < Any >() );
+ }
+
+ std::auto_ptr<ResMgr> pResMgr (ResMgr::CreateResMgr (
+ CREATEVERSIONRESMGR_NAME(productregistration)));
+
+ Reference< XFrame > xFrame = lcl_getActiveFrame( m_xORB );
+ // execute it
+ RegistrationDialog aDialog (
+ lcl_getPreferredDialogParent( xFrame ),
+ ResId( DLG_REGISTRATION_REQUEST, *pResMgr.get() ),
+ lcl_isEvalVersion( m_xORB ) );
+ aDialog.Execute();
+
+ bool registerOnline = false;
+
+ switch ( aDialog.getResponse() )
+ {
+ case RegistrationDialog::urRegisterNow:
+ registerOnline = true;
+ break;
+
+ case RegistrationDialog::urRegisterLater:
+ bDeactivateJob = sal_False;
+ // remind again in seven days from now on ...
+ aRegOptions.activateReminder( 7 );
+ break;
+
+ case RegistrationDialog::urRegisterNever:
+ case RegistrationDialog::urAlreadyRegistered:
+ // never register or already registered
+ // -> deactivate the job, and nothing else
+ break;
+
+ default:
+ OSL_ENSURE( sal_False, "OProductRegistration::execute: invalid response from the dialog!" );
+ }
+
+ // prefer new style registration
+ if( ! lcl_doNewStyleRegistration(m_xORB, registerOnline) && registerOnline )
+ doOnlineRegistration();
+ }
+ }
+
+ Sequence< NamedValue > aJobResponse( 1 );
+ aJobResponse[0].Name = OUString::createFromAscii( "Deactivate" );
+ aJobResponse[0].Value <<= bDeactivateJob;
+ aReturn <<= aJobResponse;
+ }
+
+ return aReturn;
+ }
+
+ //--------------------------------------------------------------------
+ void OProductRegistration::doOnlineRegistration( )
+ {
+ sal_Bool bSuccess = sal_False;
+ try
+ {
+ // create the Desktop component which can load components
+ Reference< XSystemShellExecute > xSystemShell(
+ m_xORB->createInstance( OUString::createFromAscii( "com.sun.star.system.SystemShellExecute" ) ),
+ UNO_QUERY
+ );
+ OSL_ENSURE( xSystemShell.is(), "OProductRegistration::doOnlineRegistration: invalid SystemExecute component!" );
+
+ // access the configuration to retrieve the URL we shall use for registration
+ utl::RegOptions aOptions;
+ OUString sRegistrationURL( aOptions.getRegistrationURL( ) );
+ OSL_ENSURE( sRegistrationURL.getLength(), "OProductRegistration::doOnlineRegistration: invalid URL found!" );
+
+ if ( xSystemShell.is() && sRegistrationURL.getLength() )
+ {
+ xSystemShell->execute( sRegistrationURL, OUString(), SystemShellExecuteFlags::DEFAULTS );
+ bSuccess = sal_True;
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+ if ( !bSuccess )
+ {
+ std::auto_ptr<ResMgr> pResMgr (ResMgr::CreateResMgr (
+ CREATEVERSIONRESMGR_NAME(productregistration)));
+
+ ErrorBox aRegistrationError(
+ Application::GetDefDialogParent(),
+ ResId( ERRBOX_REG_NOSYSBROWSER, *pResMgr.get() ));
+ aRegistrationError.Execute();
+
+ // try again later
+ utl::RegOptions aRegOptions;
+ aRegOptions.activateReminder( 7 );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ OProductRegistration::EventType OProductRegistration::classify( const OUString& _rEventDesc )
+ {
+ EventType eReturn = etUnknown;
+ if ( _rEventDesc.equalsAscii( "RegistrationRequired" ) )
+ {
+ eReturn = etRegistrationRequired;
+ }
+ return eReturn;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+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 */, void * pRegistryKey)
+{
+ if (pRegistryKey)
+ {
+ Reference< XRegistryKey > xRegistryKey (
+ reinterpret_cast< XRegistryKey* >( pRegistryKey ));
+ Reference< XRegistryKey > xNewKey;
+
+ xNewKey = xRegistryKey->createKey(
+ OUString::createFromAscii( "/" PRODREG_IMPLNAME "/UNO/SERVICES" ));
+ xNewKey->createKey(
+ OUString::createFromAscii( PRODREG_SERVNAME ));
+
+ return sal_True;
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
+ const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */)
+{
+ void * pResult = 0;
+ if (pServiceManager)
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ if (svt::OProductRegistration::getImplementationName_Static().compareToAscii (pImplementationName) == 0)
+ {
+ xFactory = cppu::createSingleFactory (
+ reinterpret_cast< XMultiServiceFactory* >(pServiceManager),
+ svt::OProductRegistration::getImplementationName_Static(),
+ svt::OProductRegistration::Create,
+ svt::OProductRegistration::getSupportedServiceNames_Static());
+ }
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pResult = xFactory.get();
+ }
+ }
+ return pResult;
+}
+
+} // extern "C"
diff --git a/svtools/source/productregistration/productregistration.hxx b/svtools/source/productregistration/productregistration.hxx
new file mode 100644
index 000000000000..efaa624887b0
--- /dev/null
+++ b/svtools/source/productregistration/productregistration.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 SVTOOLS_PRODUCTREGISTRATION_HXX
+#define SVTOOLS_PRODUCTREGISTRATION_HXX
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <cppuhelper/implbase3.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= OProductRegistration
+ //====================================================================
+ typedef ::cppu::WeakImplHelper3 < ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::task::XJobExecutor
+ , ::com::sun::star::task::XJob
+ > OProductRegistration_Base;
+
+ class OProductRegistration : public OProductRegistration_Base
+ {
+ private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ m_xORB;
+
+ protected:
+ OProductRegistration( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB );
+
+ public:
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ Create( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB );
+
+ // XServiceInfo - static version
+ static ::rtl::OUString SAL_CALL getImplementationName_Static( );
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static( ) throw (::com::sun::star::uno::RuntimeException);
+
+ protected:
+ // 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);
+
+ // XJobExecutor
+ virtual void SAL_CALL trigger( const ::rtl::OUString& sEvent ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArgs ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ private:
+ // types of events which can be handled by this component
+ enum EventType
+ {
+ etRegistrationRequired,
+
+ etUnknown
+ };
+
+ // classifies a event
+ EventType classify( const ::rtl::OUString& _rEventDesc );
+
+ // do the online registration
+ void doOnlineRegistration( );
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // SVTOOLS_PRODUCTREGISTRATION_HXX
+
diff --git a/svtools/source/productregistration/registrationdlg.cxx b/svtools/source/productregistration/registrationdlg.cxx
new file mode 100644
index 000000000000..460cedb060d1
--- /dev/null
+++ b/svtools/source/productregistration/registrationdlg.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_svtools.hxx"
+#include "registrationdlg.hxx"
+
+#if 0 /* @@@ */
+#include <svtools/svtdata.hxx>
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#endif /* @@@ */
+
+#ifndef SVTOOLS_REGISTRATIONDLG_HRC
+#include "registrationdlg.hrc"
+#endif
+#include <vcl/msgbox.hxx>
+#include <tools/debug.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ static void lcl_moveControls( Control** _ppControls, sal_Int32 _nAmount )
+ {
+ if ( _ppControls )
+ while ( *_ppControls )
+ {
+ Point aPos = (*_ppControls)->GetPosPixel();
+ aPos.Y() += _nAmount;
+ (*_ppControls)->SetPosPixel( aPos );
+
+ ++_ppControls;
+ }
+ }
+
+ //====================================================================
+ //= RegistrationDialog
+ //====================================================================
+ //--------------------------------------------------------------------
+ RegistrationDialog::RegistrationDialog( Window* _pWindow, const ResId& _rResId, bool _bEvalVersion )
+ :ModalDialog( _pWindow, _rResId )
+ ,m_eResponse ( urRegisterLater )
+ ,m_aLogo ( this, ResId( FI_LOGO, *_rResId.GetResMgr() ) )
+ ,m_aIntro ( this, ResId( FT_INTRO, *_rResId.GetResMgr() ) )
+ ,m_aNow ( this, ResId( RB_NOW, *_rResId.GetResMgr() ) )
+ ,m_aLater ( this, ResId( RB_LATER, *_rResId.GetResMgr() ) )
+ ,m_aNever ( this, ResId( RB_NEVER, *_rResId.GetResMgr() ) )
+ ,m_aAlreadyDone ( this, ResId( RB_DONE, *_rResId.GetResMgr() ) )
+ ,m_aSeparator ( this, ResId( FL_SEPARATOR, *_rResId.GetResMgr() ) )
+ ,m_aOK ( this, ResId( BTN_OK, *_rResId.GetResMgr() ) )
+ ,m_aHelp ( this, ResId( BTN_HELP, *_rResId.GetResMgr() ) )
+ {
+ if ( _bEvalVersion )
+ { // if we're an eval version, we need to hide two of the options
+ m_aNever.Hide( );
+ m_aAlreadyDone.Hide( );
+
+ // make the explanatory text somewhat smaller
+ Size aIntroSize = m_aIntro.GetSizePixel();
+ aIntroSize.Height() = LogicToPixel( Size( 0, 18 ), MAP_APPFONT ).Height();
+ sal_Int32 nHeightDifference = m_aIntro.GetSizePixel().Height() - aIntroSize.Height();
+ m_aIntro.SetSizePixel( aIntroSize );
+
+ // resize the dialog, and move the controls below the ones we just hided
+ sal_Int32 nAlreadyDoneLower = m_aAlreadyDone.GetPosPixel().Y() + m_aAlreadyDone.GetSizePixel().Height();
+ sal_Int32 nLaterLower = m_aLater.GetPosPixel().Y() + m_aLater.GetSizePixel().Height();
+ sal_Int32 nDifference = nAlreadyDoneLower - nLaterLower;
+
+ sal_Int32 nOverallDifference = nDifference + nHeightDifference;
+
+ // move
+ Control* pVisibleRadios[] = { &m_aNow, &m_aLater, NULL };
+ lcl_moveControls( pVisibleRadios, -nHeightDifference );
+
+ Control* pControlsToMove[] = { &m_aSeparator, &m_aOK, &m_aHelp, NULL };
+ lcl_moveControls( pControlsToMove, -nOverallDifference );
+
+ // resize the dialog
+ Size aSize = GetSizePixel();
+ aSize.Height() -= nOverallDifference;
+ SetSizePixel( aSize );
+ }
+ else
+ {
+ // the explanatory text needs to be completed
+ String sCompleteIntro = m_aIntro.GetText( );
+ sCompleteIntro += String( ResId( STR_COMPLETE_INTRO, *_rResId.GetResMgr() ) );
+ m_aIntro.SetText( sCompleteIntro );
+ }
+
+ FreeResource();
+
+ m_aNow.Check( TRUE );
+ }
+
+ //--------------------------------------------------------------------
+ short RegistrationDialog::Execute()
+ {
+ short nResult = ModalDialog::Execute();
+
+ // as a default, assume that the user wants to be reminded
+ m_eResponse = urRegisterLater;
+
+ if ( RET_OK == nResult )
+ {
+ if ( m_aNow.IsChecked() )
+ m_eResponse = urRegisterNow;
+ else if ( m_aLater.IsChecked() )
+ m_eResponse = urRegisterLater;
+ else if ( m_aNever.IsChecked() )
+ m_eResponse = urRegisterNever;
+ else if ( m_aAlreadyDone.IsChecked() )
+ m_eResponse = urAlreadyRegistered;
+#ifdef DBG_UTIL
+ else
+ {
+ DBG_ERROR( "RegistrationDialog::Execute: invalid dialog state!" );
+ }
+#endif
+ }
+ return nResult;
+ }
+ //--------------------------------------------------------------------
+ long RegistrationDialog::PreNotify( NotifyEvent& rNEvt )
+ {
+ long nHandled;
+ if( rNEvt.GetType() == EVENT_KEYINPUT &&
+ rNEvt.GetKeyEvent()->GetCharCode() &&
+ rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_ESCAPE)
+ {
+ EndDialog(RET_CANCEL);
+ nHandled = 1;
+ }
+ else
+ nHandled = ModalDialog::PreNotify( rNEvt );
+ return nHandled;
+ }
+
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+
diff --git a/svtools/source/productregistration/registrationdlg.hrc b/svtools/source/productregistration/registrationdlg.hrc
new file mode 100644
index 000000000000..cfcde5f8c9b3
--- /dev/null
+++ b/svtools/source/productregistration/registrationdlg.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.
+ *
+ ************************************************************************/
+
+#ifndef SVTOOLS_REGISTRATIONDLG_HRC
+#define SVTOOLS_REGISTRATIONDLG_HRC
+
+#define FI_LOGO 1
+#define FT_INTRO 2
+#define RB_NOW 3
+#define RB_LATER 4
+#define RB_NEVER 5
+#define RB_DONE 6
+#define FL_SEPARATOR 7
+#define BTN_OK 8
+#define BTN_HELP 9
+#define STR_COMPLETE_INTRO 10
+
+#endif // SVTOOLS_REGISTRATIONDLG_HRC
+
diff --git a/svtools/source/productregistration/registrationdlg.hxx b/svtools/source/productregistration/registrationdlg.hxx
new file mode 100644
index 000000000000..16761aff08fc
--- /dev/null
+++ b/svtools/source/productregistration/registrationdlg.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 SVTOOLS_REGISTRATIONDLG_HXX
+#define SVTOOLS_REGISTRATIONDLG_HXX
+
+#include <vcl/fixed.hxx>
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/dialog.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= RegistrationDialog
+ //====================================================================
+ class RegistrationDialog : public ModalDialog
+ {
+ public:
+ enum UserResponse
+ {
+ urRegisterNow,
+ urRegisterLater,
+ urRegisterNever,
+ urAlreadyRegistered
+ };
+
+ private:
+ UserResponse m_eResponse;
+
+ FixedImage m_aLogo;
+ FixedText m_aIntro;
+
+ RadioButton m_aNow;
+ RadioButton m_aLater;
+ RadioButton m_aNever;
+ RadioButton m_aAlreadyDone;
+
+ FixedLine m_aSeparator;
+
+ OKButton m_aOK;
+ HelpButton m_aHelp;
+
+ public:
+ RegistrationDialog( Window* _pWindow, const ResId& _rResId, bool _bEvalVersion );
+
+ virtual short Execute();
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ inline UserResponse getResponse() const { return m_eResponse; }
+ };
+
+
+
+//........................................................................
+}// namespace svt
+//........................................................................
+
+#endif // SVTOOLS_REGISTRATIONDLG_HXX
diff --git a/svtools/source/productregistration/registrationdlg.src b/svtools/source/productregistration/registrationdlg.src
new file mode 100644
index 000000000000..c4cdcbcbe3ec
--- /dev/null
+++ b/svtools/source/productregistration/registrationdlg.src
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SVTOOLS_REGISTRATIONDLG_HRC
+#include "registrationdlg.hrc"
+#endif
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+#ifndef _SVT_HELPID_HRC
+#include <svtools/helpid.hrc>
+#endif
+
+ModalDialog DLG_REGISTRATION_REQUEST
+{
+ HelpID = HID_REGISTRATION_DIALOG;
+ Moveable = TRUE ;
+ Closeable = TRUE;
+ OutputSize = TRUE ;
+ Size = MAP_APPFONT ( 192 , 134 ) ;
+ Text [ en-US ] = "%PRODUCTNAME Registration";
+
+ FixedImage FI_LOGO
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 24 , 24 ) ;
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap
+ {
+ File = "regkey.bmp" ;
+ };
+ MaskColor = Color { Red = 0x0000 ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ };
+ };
+ FixedText FT_INTRO
+ {
+ Pos = MAP_APPFONT ( 33, 6 ) ;
+ Size = MAP_APPFONT ( 153 , 32 ) ;
+ WordBreak = TRUE;
+ Text [ en-US ] = "You now have the opportunity to register as a %PRODUCTNAME user." ;
+ };
+
+ String STR_COMPLETE_INTRO
+ {
+ Text [ en-US ] = " Registration is voluntary and is without obligation." ;
+ };
+
+ RadioButton RB_NOW
+ {
+ Pos = MAP_APPFONT ( 33 , 41 ) ;
+ Size = MAP_APPFONT ( 153 , 10 ) ;
+ Text [ en-US ] = "Register now" ;
+ };
+
+ RadioButton RB_LATER
+ {
+ Pos = MAP_APPFONT ( 33 , 54 ) ;
+ Size = MAP_APPFONT ( 153 , 10 ) ;
+ Text [ en-US ] = "Remind me to register later" ;
+ };
+ RadioButton RB_NEVER
+ {
+ Pos = MAP_APPFONT ( 33 , 67 ) ;
+ Size = MAP_APPFONT ( 153 , 10 ) ;
+ Text [ en-US ] = "Never register" ;
+ };
+ RadioButton RB_DONE
+ {
+ Pos = MAP_APPFONT ( 33 , 80 ) ;
+ Size = MAP_APPFONT ( 153 , 20 ) ;
+ WordBreak = TRUE;
+
+ Text [ en-US ] = "Already registered as %PRODUCTNAME %PRODUCTVERSION user." ;
+ };
+
+ FixedLine FL_SEPARATOR
+ {
+ Pos = MAP_APPFONT ( 6, 107 ) ;
+ Size = MAP_APPFONT ( 180 , 1 ) ;
+ };
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 80, 114 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 136, 114 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+};
+
+ErrorBox ERRBOX_REG_NOSYSBROWSER
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+
+ Message [ en-US ] = "An error occurred in starting the web browser.\nPlease check the %PRODUCTNAME and web browser settings.";
+};
+
+
diff --git a/svtools/source/svhtml/htmlkywd.cxx b/svtools/source/svhtml/htmlkywd.cxx
new file mode 100644
index 000000000000..96377a1b7efb
--- /dev/null
+++ b/svtools/source/svhtml/htmlkywd.cxx
@@ -0,0 +1,1081 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <svtools/svparser.hxx>
+#include "htmlkywd.hxx"
+#include "htmltokn.h"
+
+// die Tabelle muss noch sortiert werden
+struct HTML_TokenEntry
+{
+ union
+ {
+ const sal_Char *sToken;
+ const String *pUToken;
+ };
+ int nToken;
+};
+
+// Flag: RTF-Token Tabelle wurde schon sortiert
+static int __FAR_DATA bSortKeyWords = FALSE;
+
+static HTML_TokenEntry __FAR_DATA aHTMLTokenTab[] = {
+ {{OOO_STRING_SVTOOLS_HTML_area}, HTML_AREA}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_base}, HTML_BASE}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_comment}, HTML_COMMENT},
+ {{OOO_STRING_SVTOOLS_HTML_doctype}, HTML_DOCTYPE},
+ {{OOO_STRING_SVTOOLS_HTML_embed}, HTML_EMBED}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_figureoverlay}, HTML_FIGUREOVERLAY}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_horzrule}, HTML_HORZRULE},
+ {{OOO_STRING_SVTOOLS_HTML_horztab}, HTML_HORZTAB}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_image}, HTML_IMAGE},
+ {{OOO_STRING_SVTOOLS_HTML_image2}, HTML_IMAGE},
+ {{OOO_STRING_SVTOOLS_HTML_input}, HTML_INPUT},
+ {{OOO_STRING_SVTOOLS_HTML_isindex}, HTML_ISINDEX}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_li}, HTML_LI_ON},
+ {{OOO_STRING_SVTOOLS_HTML_linebreak}, HTML_LINEBREAK},
+ {{OOO_STRING_SVTOOLS_HTML_link}, HTML_LINK}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_meta}, HTML_META}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_nextid}, HTML_NEXTID}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_of}, HTML_OF}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_option}, HTML_OPTION},
+ {{OOO_STRING_SVTOOLS_HTML_param}, HTML_PARAM}, // HotJava
+ {{OOO_STRING_SVTOOLS_HTML_range}, HTML_RANGE}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_spacer}, HTML_SPACER}, // Netscape 3.0b5
+ {{OOO_STRING_SVTOOLS_HTML_wbr}, HTML_WBR}, // Netscape
+
+ {{OOO_STRING_SVTOOLS_HTML_abbreviation}, HTML_ABBREVIATION_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_above}, HTML_ABOVE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_acronym}, HTML_ACRONYM_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_address}, HTML_ADDRESS_ON},
+ {{OOO_STRING_SVTOOLS_HTML_anchor}, HTML_ANCHOR_ON},
+ {{OOO_STRING_SVTOOLS_HTML_applet}, HTML_APPLET_ON}, // HotJava
+ {{OOO_STRING_SVTOOLS_HTML_array}, HTML_ARRAY_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_author}, HTML_AUTHOR_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_banner}, HTML_BANNER_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_bar}, HTML_BAR_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_basefont}, HTML_BASEFONT_ON}, // Netscape
+ {{OOO_STRING_SVTOOLS_HTML_below}, HTML_BELOW_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_bigprint}, HTML_BIGPRINT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_blink}, HTML_BLINK_ON}, // Netscape
+ {{OOO_STRING_SVTOOLS_HTML_blockquote}, HTML_BLOCKQUOTE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_blockquote30}, HTML_BLOCKQUOTE30_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_body}, HTML_BODY_ON},
+ {{OOO_STRING_SVTOOLS_HTML_bold}, HTML_BOLD_ON},
+ {{OOO_STRING_SVTOOLS_HTML_boldtext}, HTML_BOLDTEXT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_box}, HTML_BOX_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_caption}, HTML_CAPTION_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_center}, HTML_CENTER_ON}, // Netscape
+ {{OOO_STRING_SVTOOLS_HTML_citiation}, HTML_CITIATION_ON},
+ {{OOO_STRING_SVTOOLS_HTML_col}, HTML_COL_ON}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_colgroup}, HTML_COLGROUP_ON}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_code}, HTML_CODE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_credit}, HTML_CREDIT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_dd}, HTML_DD_ON},
+ {{OOO_STRING_SVTOOLS_HTML_deflist}, HTML_DEFLIST_ON},
+ {{OOO_STRING_SVTOOLS_HTML_deletedtext}, HTML_DELETEDTEXT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_dirlist}, HTML_DIRLIST_ON},
+ {{OOO_STRING_SVTOOLS_HTML_division}, HTML_DIVISION_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_dot}, HTML_DOT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_doubledot}, HTML_DOUBLEDOT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_dt}, HTML_DT_ON},
+ {{OOO_STRING_SVTOOLS_HTML_emphasis}, HTML_EMPHASIS_ON},
+ {{OOO_STRING_SVTOOLS_HTML_figure}, HTML_FIGURE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_font}, HTML_FONT_ON}, // Netscpe
+ {{OOO_STRING_SVTOOLS_HTML_footnote}, HTML_FOOTNOTE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_form}, HTML_FORM_ON},
+ {{OOO_STRING_SVTOOLS_HTML_frame}, HTML_FRAME_ON}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_frameset}, HTML_FRAMESET_ON}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_hat}, HTML_HAT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_head}, HTML_HEAD_ON},
+ {{OOO_STRING_SVTOOLS_HTML_head1}, HTML_HEAD1_ON},
+ {{OOO_STRING_SVTOOLS_HTML_head2}, HTML_HEAD2_ON},
+ {{OOO_STRING_SVTOOLS_HTML_head3}, HTML_HEAD3_ON},
+ {{OOO_STRING_SVTOOLS_HTML_head4}, HTML_HEAD4_ON},
+ {{OOO_STRING_SVTOOLS_HTML_head5}, HTML_HEAD5_ON},
+ {{OOO_STRING_SVTOOLS_HTML_head6}, HTML_HEAD6_ON},
+ {{OOO_STRING_SVTOOLS_HTML_html}, HTML_HTML_ON},
+ {{OOO_STRING_SVTOOLS_HTML_iframe}, HTML_IFRAME_ON}, // IE 3.0b2
+ {{OOO_STRING_SVTOOLS_HTML_ilayer}, HTML_ILAYER_ON},
+ {{OOO_STRING_SVTOOLS_HTML_insertedtext}, HTML_INSERTEDTEXT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_italic}, HTML_ITALIC_ON},
+ {{OOO_STRING_SVTOOLS_HTML_item}, HTML_ITEM_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_keyboard}, HTML_KEYBOARD_ON},
+ {{OOO_STRING_SVTOOLS_HTML_language}, HTML_LANGUAGE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_layer}, HTML_LAYER_ON},
+ {{OOO_STRING_SVTOOLS_HTML_listheader}, HTML_LISTHEADER_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_map}, HTML_MAP_ON}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_math}, HTML_MATH_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_menulist}, HTML_MENULIST_ON},
+ {{OOO_STRING_SVTOOLS_HTML_multicol}, HTML_MULTICOL_ON}, // Netscape 3.0b5
+ {{OOO_STRING_SVTOOLS_HTML_nobr}, HTML_NOBR_ON}, // Netscape
+ {{OOO_STRING_SVTOOLS_HTML_noembed}, HTML_NOEMBED_ON}, // Netscape 2.0 ???
+ {{OOO_STRING_SVTOOLS_HTML_noframe}, HTML_NOFRAMES_ON}, // Netscape 2.0 ???
+ {{OOO_STRING_SVTOOLS_HTML_noframes}, HTML_NOFRAMES_ON}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_noscript}, HTML_NOSCRIPT_ON}, // Netscape 3.0
+ {{OOO_STRING_SVTOOLS_HTML_note}, HTML_NOTE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_object}, HTML_OBJECT_ON},
+ {{OOO_STRING_SVTOOLS_HTML_orderlist}, HTML_ORDERLIST_ON},
+ {{OOO_STRING_SVTOOLS_HTML_parabreak}, HTML_PARABREAK_ON},
+ {{OOO_STRING_SVTOOLS_HTML_person}, HTML_PERSON_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_plaintext}, HTML_PLAINTEXT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_preformtxt}, HTML_PREFORMTXT_ON},
+ {{OOO_STRING_SVTOOLS_HTML_root}, HTML_ROOT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_row}, HTML_ROW_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_sample}, HTML_SAMPLE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_script}, HTML_SCRIPT_ON}, // HTML 3.2
+ {{OOO_STRING_SVTOOLS_HTML_select}, HTML_SELECT_ON},
+ {{OOO_STRING_SVTOOLS_HTML_shortquote}, HTML_SHORTQUOTE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_smallprint}, HTML_SMALLPRINT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_span}, HTML_SPAN_ON}, // Style Sheets
+ {{OOO_STRING_SVTOOLS_HTML_squareroot}, HTML_SQUAREROOT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_strikethrough},HTML_STRIKETHROUGH_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_strong}, HTML_STRONG_ON},
+ {{OOO_STRING_SVTOOLS_HTML_style}, HTML_STYLE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_subscript}, HTML_SUBSCRIPT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_superscript}, HTML_SUPERSCRIPT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_table}, HTML_TABLE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_tabledata}, HTML_TABLEDATA_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_tableheader}, HTML_TABLEHEADER_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_tablerow}, HTML_TABLEROW_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_tbody}, HTML_TBODY_ON}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_teletype}, HTML_TELETYPE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_text}, HTML_TEXT_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_textarea}, HTML_TEXTAREA_ON},
+ {{OOO_STRING_SVTOOLS_HTML_textflow}, HTML_TEXTFLOW_ON},
+ {{OOO_STRING_SVTOOLS_HTML_tfoot}, HTML_TFOOT_ON}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_thead}, HTML_THEAD_ON}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_tilde}, HTML_TILDE_ON}, // HTML 3.0
+ {{OOO_STRING_SVTOOLS_HTML_title}, HTML_TITLE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_underline}, HTML_UNDERLINE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_unorderlist}, HTML_UNORDERLIST_ON},
+ {{OOO_STRING_SVTOOLS_HTML_variable}, HTML_VARIABLE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_vector}, HTML_VECTOR_ON}, // HTML 3.0
+
+ {{OOO_STRING_SVTOOLS_HTML_xmp}, HTML_XMP_ON},
+ {{OOO_STRING_SVTOOLS_HTML_listing}, HTML_LISTING_ON},
+
+ {{OOO_STRING_SVTOOLS_HTML_definstance}, HTML_DEFINSTANCE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_strike}, HTML_STRIKE_ON},
+
+ {{OOO_STRING_SVTOOLS_HTML_bgsound}, HTML_BGSOUND},
+ {{OOO_STRING_SVTOOLS_HTML_comment2}, HTML_COMMENT2_ON},
+ {{OOO_STRING_SVTOOLS_HTML_marquee}, HTML_MARQUEE_ON},
+ {{OOO_STRING_SVTOOLS_HTML_plaintext2}, HTML_PLAINTEXT2_ON},
+
+ {{OOO_STRING_SVTOOLS_HTML_sdfield}, HTML_SDFIELD_ON}
+};
+
+
+extern "C"
+{
+
+static int
+#if defined( WNT )
+ __cdecl
+#endif
+#if defined( ICC ) && defined( OS2 )
+ _Optlink
+#endif
+ HTMLKeyCompare( const void *pFirst, const void *pSecond)
+{
+ int nRet = 0;
+ if( -1 == ((HTML_TokenEntry*)pFirst)->nToken )
+ {
+ if( -1 == ((HTML_TokenEntry*)pSecond)->nToken )
+ nRet = ((HTML_TokenEntry*)pFirst)->pUToken->CompareTo(
+ *((HTML_TokenEntry*)pSecond)->pUToken );
+ else
+ nRet = ((HTML_TokenEntry*)pFirst)->pUToken->CompareToAscii(
+ ((HTML_TokenEntry*)pSecond)->sToken );
+ }
+ else
+ {
+ if( -1 == ((HTML_TokenEntry*)pSecond)->nToken )
+ nRet = -1 * ((HTML_TokenEntry*)pSecond)->pUToken->CompareToAscii(
+ ((HTML_TokenEntry*)pFirst)->sToken );
+ else
+ nRet = strcmp( ((HTML_TokenEntry*)pFirst)->sToken,
+ ((HTML_TokenEntry*)pSecond)->sToken );
+ }
+
+ return nRet;
+}
+
+}
+
+int GetHTMLToken( const String& rName )
+{
+ if( !bSortKeyWords )
+ {
+ qsort( (void*) aHTMLTokenTab,
+ sizeof( aHTMLTokenTab ) / sizeof( HTML_TokenEntry ),
+ sizeof( HTML_TokenEntry ),
+ HTMLKeyCompare );
+ bSortKeyWords = TRUE;
+ }
+
+ int nRet = 0;
+
+ if( !rName.CompareToAscii( OOO_STRING_SVTOOLS_HTML_comment, 3UL) )
+ return HTML_COMMENT;
+
+ void* pFound;
+ HTML_TokenEntry aSrch;
+ aSrch.pUToken = &rName;
+ aSrch.nToken = -1;
+
+ if( 0 != ( pFound = bsearch( (sal_Char *) &aSrch,
+ (void*) aHTMLTokenTab,
+ sizeof( aHTMLTokenTab ) / sizeof( HTML_TokenEntry ),
+ sizeof( HTML_TokenEntry ),
+ HTMLKeyCompare )))
+ nRet = ((HTML_TokenEntry*)pFound)->nToken;
+ return nRet;
+}
+
+/* */
+
+struct HTML_CharEntry
+{
+ union
+ {
+ const sal_Char *sName;
+ const String *pUName;
+ };
+ sal_Unicode cChar;
+};
+
+// Flag: RTF-Token Tabelle wurde schon sortiert
+static int __FAR_DATA bSortCharKeyWords = FALSE;
+
+static HTML_CharEntry __FAR_DATA aHTMLCharNameTab[] = {
+ {{OOO_STRING_SVTOOLS_HTML_C_lt}, 60},
+ {{OOO_STRING_SVTOOLS_HTML_C_gt}, 62},
+ {{OOO_STRING_SVTOOLS_HTML_C_amp}, 38},
+ {{OOO_STRING_SVTOOLS_HTML_C_quot}, 34},
+
+ {{OOO_STRING_SVTOOLS_HTML_C_Agrave}, 192},
+ {{OOO_STRING_SVTOOLS_HTML_C_Aacute}, 193},
+ {{OOO_STRING_SVTOOLS_HTML_C_Acirc}, 194},
+ {{OOO_STRING_SVTOOLS_HTML_C_Atilde}, 195},
+ {{OOO_STRING_SVTOOLS_HTML_C_Auml}, 196},
+ {{OOO_STRING_SVTOOLS_HTML_C_Aring}, 197},
+ {{OOO_STRING_SVTOOLS_HTML_C_AElig}, 198},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ccedil}, 199},
+ {{OOO_STRING_SVTOOLS_HTML_C_Egrave}, 200},
+ {{OOO_STRING_SVTOOLS_HTML_C_Eacute}, 201},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ecirc}, 202},
+ {{OOO_STRING_SVTOOLS_HTML_C_Euml}, 203},
+ {{OOO_STRING_SVTOOLS_HTML_C_Igrave}, 204},
+ {{OOO_STRING_SVTOOLS_HTML_C_Iacute}, 205},
+ {{OOO_STRING_SVTOOLS_HTML_C_Icirc}, 206},
+ {{OOO_STRING_SVTOOLS_HTML_C_Iuml}, 207},
+ {{OOO_STRING_SVTOOLS_HTML_C_ETH}, 208},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ntilde}, 209},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ograve}, 210},
+ {{OOO_STRING_SVTOOLS_HTML_C_Oacute}, 211},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ocirc}, 212},
+ {{OOO_STRING_SVTOOLS_HTML_C_Otilde}, 213},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ouml}, 214},
+ {{OOO_STRING_SVTOOLS_HTML_C_Oslash}, 216},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ugrave}, 217},
+ {{OOO_STRING_SVTOOLS_HTML_C_Uacute}, 218},
+ {{OOO_STRING_SVTOOLS_HTML_C_Ucirc}, 219},
+ {{OOO_STRING_SVTOOLS_HTML_C_Uuml}, 220},
+ {{OOO_STRING_SVTOOLS_HTML_C_Yacute}, 221},
+
+ {{OOO_STRING_SVTOOLS_HTML_C_THORN}, 222},
+ {{OOO_STRING_SVTOOLS_HTML_C_szlig}, 223},
+
+ {{OOO_STRING_SVTOOLS_HTML_S_agrave}, 224},
+ {{OOO_STRING_SVTOOLS_HTML_S_aacute}, 225},
+ {{OOO_STRING_SVTOOLS_HTML_S_acirc}, 226},
+ {{OOO_STRING_SVTOOLS_HTML_S_atilde}, 227},
+ {{OOO_STRING_SVTOOLS_HTML_S_auml}, 228},
+ {{OOO_STRING_SVTOOLS_HTML_S_aring}, 229},
+ {{OOO_STRING_SVTOOLS_HTML_S_aelig}, 230},
+ {{OOO_STRING_SVTOOLS_HTML_S_ccedil}, 231},
+ {{OOO_STRING_SVTOOLS_HTML_S_egrave}, 232},
+ {{OOO_STRING_SVTOOLS_HTML_S_eacute}, 233},
+ {{OOO_STRING_SVTOOLS_HTML_S_ecirc}, 234},
+ {{OOO_STRING_SVTOOLS_HTML_S_euml}, 235},
+ {{OOO_STRING_SVTOOLS_HTML_S_igrave}, 236},
+ {{OOO_STRING_SVTOOLS_HTML_S_iacute}, 237},
+ {{OOO_STRING_SVTOOLS_HTML_S_icirc}, 238},
+ {{OOO_STRING_SVTOOLS_HTML_S_iuml}, 239},
+ {{OOO_STRING_SVTOOLS_HTML_S_eth}, 240},
+ {{OOO_STRING_SVTOOLS_HTML_S_ntilde}, 241},
+ {{OOO_STRING_SVTOOLS_HTML_S_ograve}, 242},
+ {{OOO_STRING_SVTOOLS_HTML_S_oacute}, 243},
+ {{OOO_STRING_SVTOOLS_HTML_S_ocirc}, 244},
+ {{OOO_STRING_SVTOOLS_HTML_S_otilde}, 245},
+ {{OOO_STRING_SVTOOLS_HTML_S_ouml}, 246},
+ {{OOO_STRING_SVTOOLS_HTML_S_oslash}, 248},
+ {{OOO_STRING_SVTOOLS_HTML_S_ugrave}, 249},
+ {{OOO_STRING_SVTOOLS_HTML_S_uacute}, 250},
+ {{OOO_STRING_SVTOOLS_HTML_S_ucirc}, 251},
+ {{OOO_STRING_SVTOOLS_HTML_S_uuml}, 252},
+ {{OOO_STRING_SVTOOLS_HTML_S_yacute}, 253},
+ {{OOO_STRING_SVTOOLS_HTML_S_thorn}, 254},
+ {{OOO_STRING_SVTOOLS_HTML_S_yuml}, 255},
+
+// Sonderzeichen
+ {{OOO_STRING_SVTOOLS_HTML_S_acute}, 180},
+ {{OOO_STRING_SVTOOLS_HTML_S_brvbar}, 166},
+ {{OOO_STRING_SVTOOLS_HTML_S_cedil}, 184},
+ {{OOO_STRING_SVTOOLS_HTML_S_cent}, 162},
+ {{OOO_STRING_SVTOOLS_HTML_S_copy}, 169},
+ {{OOO_STRING_SVTOOLS_HTML_S_curren}, 164},
+ {{OOO_STRING_SVTOOLS_HTML_S_deg}, 176},
+ {{OOO_STRING_SVTOOLS_HTML_S_divide}, 247},
+ {{OOO_STRING_SVTOOLS_HTML_S_frac12}, 189},
+ {{OOO_STRING_SVTOOLS_HTML_S_frac14}, 188},
+ {{OOO_STRING_SVTOOLS_HTML_S_frac34}, 190},
+ {{OOO_STRING_SVTOOLS_HTML_S_iexcl}, 161},
+ {{OOO_STRING_SVTOOLS_HTML_S_iquest}, 191},
+ {{OOO_STRING_SVTOOLS_HTML_S_laquo}, 171},
+ {{OOO_STRING_SVTOOLS_HTML_S_macr}, 175},
+ {{OOO_STRING_SVTOOLS_HTML_S_micro}, 181},
+ {{OOO_STRING_SVTOOLS_HTML_S_middot}, 183},
+ {{OOO_STRING_SVTOOLS_HTML_S_not}, 172},
+ {{OOO_STRING_SVTOOLS_HTML_S_ordf}, 170},
+ {{OOO_STRING_SVTOOLS_HTML_S_ordm}, 186},
+ {{OOO_STRING_SVTOOLS_HTML_S_para}, 182},
+ {{OOO_STRING_SVTOOLS_HTML_S_plusmn}, 177},
+ {{OOO_STRING_SVTOOLS_HTML_S_pound}, 163},
+ {{OOO_STRING_SVTOOLS_HTML_S_raquo}, 187},
+ {{OOO_STRING_SVTOOLS_HTML_S_reg}, 174},
+ {{OOO_STRING_SVTOOLS_HTML_S_sect}, 167},
+ {{OOO_STRING_SVTOOLS_HTML_S_sup1}, 185},
+ {{OOO_STRING_SVTOOLS_HTML_S_sup2}, 178},
+ {{OOO_STRING_SVTOOLS_HTML_S_sup3}, 179},
+ {{OOO_STRING_SVTOOLS_HTML_S_times}, 215},
+ {{OOO_STRING_SVTOOLS_HTML_S_uml}, 168},
+ {{OOO_STRING_SVTOOLS_HTML_S_yen}, 165},
+
+// Netscape kennt noch ein paar in Grossbuchstaben ...
+ {{OOO_STRING_SVTOOLS_HTML_C_LT}, 60},
+ {{OOO_STRING_SVTOOLS_HTML_C_GT}, 62},
+ {{OOO_STRING_SVTOOLS_HTML_C_AMP}, 38},
+ {{OOO_STRING_SVTOOLS_HTML_C_QUOT}, 34},
+ {{OOO_STRING_SVTOOLS_HTML_S_COPY}, 169},
+ {{OOO_STRING_SVTOOLS_HTML_S_REG}, 174},
+
+// Sonderzeichen, die zu Tokens konvertiert werden !!!
+ {{OOO_STRING_SVTOOLS_HTML_S_nbsp}, 1},
+ {{OOO_STRING_SVTOOLS_HTML_S_shy}, 2},
+
+
+// HTML4
+ {{OOO_STRING_SVTOOLS_HTML_S_OElig}, 338},
+ {{OOO_STRING_SVTOOLS_HTML_S_oelig}, 339},
+ {{OOO_STRING_SVTOOLS_HTML_S_Scaron}, 352},
+ {{OOO_STRING_SVTOOLS_HTML_S_scaron}, 353},
+ {{OOO_STRING_SVTOOLS_HTML_S_Yuml}, 376},
+ {{OOO_STRING_SVTOOLS_HTML_S_fnof}, 402},
+ {{OOO_STRING_SVTOOLS_HTML_S_circ}, 710},
+ {{OOO_STRING_SVTOOLS_HTML_S_tilde}, 732},
+ {{OOO_STRING_SVTOOLS_HTML_S_Alpha}, 913},
+ {{OOO_STRING_SVTOOLS_HTML_S_Beta}, 914},
+ {{OOO_STRING_SVTOOLS_HTML_S_Gamma}, 915},
+ {{OOO_STRING_SVTOOLS_HTML_S_Delta}, 916},
+ {{OOO_STRING_SVTOOLS_HTML_S_Epsilon}, 917},
+ {{OOO_STRING_SVTOOLS_HTML_S_Zeta}, 918},
+ {{OOO_STRING_SVTOOLS_HTML_S_Eta}, 919},
+ {{OOO_STRING_SVTOOLS_HTML_S_Theta}, 920},
+ {{OOO_STRING_SVTOOLS_HTML_S_Iota}, 921},
+ {{OOO_STRING_SVTOOLS_HTML_S_Kappa}, 922},
+ {{OOO_STRING_SVTOOLS_HTML_S_Lambda}, 923},
+ {{OOO_STRING_SVTOOLS_HTML_S_Mu}, 924},
+ {{OOO_STRING_SVTOOLS_HTML_S_Nu}, 925},
+ {{OOO_STRING_SVTOOLS_HTML_S_Xi}, 926},
+ {{OOO_STRING_SVTOOLS_HTML_S_Omicron}, 927},
+ {{OOO_STRING_SVTOOLS_HTML_S_Pi}, 928},
+ {{OOO_STRING_SVTOOLS_HTML_S_Rho}, 929},
+ {{OOO_STRING_SVTOOLS_HTML_S_Sigma}, 931},
+ {{OOO_STRING_SVTOOLS_HTML_S_Tau}, 932},
+ {{OOO_STRING_SVTOOLS_HTML_S_Upsilon}, 933},
+ {{OOO_STRING_SVTOOLS_HTML_S_Phi}, 934},
+ {{OOO_STRING_SVTOOLS_HTML_S_Chi}, 935},
+ {{OOO_STRING_SVTOOLS_HTML_S_Psi}, 936},
+ {{OOO_STRING_SVTOOLS_HTML_S_Omega}, 937},
+ {{OOO_STRING_SVTOOLS_HTML_S_alpha}, 945},
+ {{OOO_STRING_SVTOOLS_HTML_S_beta}, 946},
+ {{OOO_STRING_SVTOOLS_HTML_S_gamma}, 947},
+ {{OOO_STRING_SVTOOLS_HTML_S_delta}, 948},
+ {{OOO_STRING_SVTOOLS_HTML_S_epsilon}, 949},
+ {{OOO_STRING_SVTOOLS_HTML_S_zeta}, 950},
+ {{OOO_STRING_SVTOOLS_HTML_S_eta}, 951},
+ {{OOO_STRING_SVTOOLS_HTML_S_theta}, 952},
+ {{OOO_STRING_SVTOOLS_HTML_S_iota}, 953},
+ {{OOO_STRING_SVTOOLS_HTML_S_kappa}, 954},
+ {{OOO_STRING_SVTOOLS_HTML_S_lambda}, 955},
+ {{OOO_STRING_SVTOOLS_HTML_S_mu}, 956},
+ {{OOO_STRING_SVTOOLS_HTML_S_nu}, 957},
+ {{OOO_STRING_SVTOOLS_HTML_S_xi}, 958},
+ {{OOO_STRING_SVTOOLS_HTML_S_omicron}, 959},
+ {{OOO_STRING_SVTOOLS_HTML_S_pi}, 960},
+ {{OOO_STRING_SVTOOLS_HTML_S_rho}, 961},
+ {{OOO_STRING_SVTOOLS_HTML_S_sigmaf}, 962},
+ {{OOO_STRING_SVTOOLS_HTML_S_sigma}, 963},
+ {{OOO_STRING_SVTOOLS_HTML_S_tau}, 964},
+ {{OOO_STRING_SVTOOLS_HTML_S_upsilon}, 965},
+ {{OOO_STRING_SVTOOLS_HTML_S_phi}, 966},
+ {{OOO_STRING_SVTOOLS_HTML_S_chi}, 967},
+ {{OOO_STRING_SVTOOLS_HTML_S_psi}, 968},
+ {{OOO_STRING_SVTOOLS_HTML_S_omega}, 969},
+ {{OOO_STRING_SVTOOLS_HTML_S_thetasym}, 977},
+ {{OOO_STRING_SVTOOLS_HTML_S_upsih}, 978},
+ {{OOO_STRING_SVTOOLS_HTML_S_piv}, 982},
+ {{OOO_STRING_SVTOOLS_HTML_S_ensp}, 8194},
+ {{OOO_STRING_SVTOOLS_HTML_S_emsp}, 8195},
+ {{OOO_STRING_SVTOOLS_HTML_S_thinsp}, 8201},
+ {{OOO_STRING_SVTOOLS_HTML_S_zwnj}, 8204},
+ {{OOO_STRING_SVTOOLS_HTML_S_zwj}, 8205},
+ {{OOO_STRING_SVTOOLS_HTML_S_lrm}, 8206},
+ {{OOO_STRING_SVTOOLS_HTML_S_rlm}, 8207},
+ {{OOO_STRING_SVTOOLS_HTML_S_ndash}, 8211},
+ {{OOO_STRING_SVTOOLS_HTML_S_mdash}, 8212},
+ {{OOO_STRING_SVTOOLS_HTML_S_lsquo}, 8216},
+ {{OOO_STRING_SVTOOLS_HTML_S_rsquo}, 8217},
+ {{OOO_STRING_SVTOOLS_HTML_S_sbquo}, 8218},
+ {{OOO_STRING_SVTOOLS_HTML_S_ldquo}, 8220},
+ {{OOO_STRING_SVTOOLS_HTML_S_rdquo}, 8221},
+ {{OOO_STRING_SVTOOLS_HTML_S_bdquo}, 8222},
+ {{OOO_STRING_SVTOOLS_HTML_S_dagger}, 8224},
+ {{OOO_STRING_SVTOOLS_HTML_S_Dagger}, 8225},
+ {{OOO_STRING_SVTOOLS_HTML_S_bull}, 8226},
+ {{OOO_STRING_SVTOOLS_HTML_S_hellip}, 8230},
+ {{OOO_STRING_SVTOOLS_HTML_S_permil}, 8240},
+ {{OOO_STRING_SVTOOLS_HTML_S_prime}, 8242},
+ {{OOO_STRING_SVTOOLS_HTML_S_Prime}, 8243},
+ {{OOO_STRING_SVTOOLS_HTML_S_lsaquo}, 8249},
+ {{OOO_STRING_SVTOOLS_HTML_S_rsaquo}, 8250},
+ {{OOO_STRING_SVTOOLS_HTML_S_oline}, 8254},
+ {{OOO_STRING_SVTOOLS_HTML_S_frasl}, 8260},
+ {{OOO_STRING_SVTOOLS_HTML_S_euro}, 8364},
+ {{OOO_STRING_SVTOOLS_HTML_S_image}, 8465},
+ {{OOO_STRING_SVTOOLS_HTML_S_weierp}, 8472},
+ {{OOO_STRING_SVTOOLS_HTML_S_real}, 8476},
+ {{OOO_STRING_SVTOOLS_HTML_S_trade}, 8482},
+ {{OOO_STRING_SVTOOLS_HTML_S_alefsym}, 8501},
+ {{OOO_STRING_SVTOOLS_HTML_S_larr}, 8592},
+ {{OOO_STRING_SVTOOLS_HTML_S_uarr}, 8593},
+ {{OOO_STRING_SVTOOLS_HTML_S_rarr}, 8594},
+ {{OOO_STRING_SVTOOLS_HTML_S_darr}, 8595},
+ {{OOO_STRING_SVTOOLS_HTML_S_harr}, 8596},
+ {{OOO_STRING_SVTOOLS_HTML_S_crarr}, 8629},
+ {{OOO_STRING_SVTOOLS_HTML_S_lArr}, 8656},
+ {{OOO_STRING_SVTOOLS_HTML_S_uArr}, 8657},
+ {{OOO_STRING_SVTOOLS_HTML_S_rArr}, 8658},
+ {{OOO_STRING_SVTOOLS_HTML_S_dArr}, 8659},
+ {{OOO_STRING_SVTOOLS_HTML_S_hArr}, 8660},
+ {{OOO_STRING_SVTOOLS_HTML_S_forall}, 8704},
+ {{OOO_STRING_SVTOOLS_HTML_S_part}, 8706},
+ {{OOO_STRING_SVTOOLS_HTML_S_exist}, 8707},
+ {{OOO_STRING_SVTOOLS_HTML_S_empty}, 8709},
+ {{OOO_STRING_SVTOOLS_HTML_S_nabla}, 8711},
+ {{OOO_STRING_SVTOOLS_HTML_S_isin}, 8712},
+ {{OOO_STRING_SVTOOLS_HTML_S_notin}, 8713},
+ {{OOO_STRING_SVTOOLS_HTML_S_ni}, 8715},
+ {{OOO_STRING_SVTOOLS_HTML_S_prod}, 8719},
+ {{OOO_STRING_SVTOOLS_HTML_S_sum}, 8721},
+ {{OOO_STRING_SVTOOLS_HTML_S_minus}, 8722},
+ {{OOO_STRING_SVTOOLS_HTML_S_lowast}, 8727},
+ {{OOO_STRING_SVTOOLS_HTML_S_radic}, 8730},
+ {{OOO_STRING_SVTOOLS_HTML_S_prop}, 8733},
+ {{OOO_STRING_SVTOOLS_HTML_S_infin}, 8734},
+ {{OOO_STRING_SVTOOLS_HTML_S_ang}, 8736},
+ {{OOO_STRING_SVTOOLS_HTML_S_and}, 8743},
+ {{OOO_STRING_SVTOOLS_HTML_S_or}, 8744},
+ {{OOO_STRING_SVTOOLS_HTML_S_cap}, 8745},
+ {{OOO_STRING_SVTOOLS_HTML_S_cup}, 8746},
+ {{OOO_STRING_SVTOOLS_HTML_S_int}, 8747},
+ {{OOO_STRING_SVTOOLS_HTML_S_there4}, 8756},
+ {{OOO_STRING_SVTOOLS_HTML_S_sim}, 8764},
+ {{OOO_STRING_SVTOOLS_HTML_S_cong}, 8773},
+ {{OOO_STRING_SVTOOLS_HTML_S_asymp}, 8776},
+ {{OOO_STRING_SVTOOLS_HTML_S_ne}, 8800},
+ {{OOO_STRING_SVTOOLS_HTML_S_equiv}, 8801},
+ {{OOO_STRING_SVTOOLS_HTML_S_le}, 8804},
+ {{OOO_STRING_SVTOOLS_HTML_S_ge}, 8805},
+ {{OOO_STRING_SVTOOLS_HTML_S_sub}, 8834},
+ {{OOO_STRING_SVTOOLS_HTML_S_sup}, 8835},
+ {{OOO_STRING_SVTOOLS_HTML_S_nsub}, 8836},
+ {{OOO_STRING_SVTOOLS_HTML_S_sube}, 8838},
+ {{OOO_STRING_SVTOOLS_HTML_S_supe}, 8839},
+ {{OOO_STRING_SVTOOLS_HTML_S_oplus}, 8853},
+ {{OOO_STRING_SVTOOLS_HTML_S_otimes}, 8855},
+ {{OOO_STRING_SVTOOLS_HTML_S_perp}, 8869},
+ {{OOO_STRING_SVTOOLS_HTML_S_sdot}, 8901},
+ {{OOO_STRING_SVTOOLS_HTML_S_lceil}, 8968},
+ {{OOO_STRING_SVTOOLS_HTML_S_rceil}, 8969},
+ {{OOO_STRING_SVTOOLS_HTML_S_lfloor}, 8970},
+ {{OOO_STRING_SVTOOLS_HTML_S_rfloor}, 8971},
+ {{OOO_STRING_SVTOOLS_HTML_S_lang}, 9001},
+ {{OOO_STRING_SVTOOLS_HTML_S_rang}, 9002},
+ {{OOO_STRING_SVTOOLS_HTML_S_loz}, 9674},
+ {{OOO_STRING_SVTOOLS_HTML_S_spades}, 9824},
+ {{OOO_STRING_SVTOOLS_HTML_S_clubs}, 9827},
+ {{OOO_STRING_SVTOOLS_HTML_S_hearts}, 9829},
+ {{OOO_STRING_SVTOOLS_HTML_S_diams}, 9830}
+};
+
+extern "C"
+{
+
+static int
+#if defined( WNT )
+ __cdecl
+#endif
+#if defined( ICC ) && defined( OS2 )
+ _Optlink
+#endif
+ HTMLCharNameCompare( const void *pFirst, const void *pSecond)
+{
+ int nRet = 0;
+ if( USHRT_MAX == ((HTML_CharEntry*)pFirst)->cChar )
+ {
+ if( USHRT_MAX == ((HTML_CharEntry*)pSecond)->cChar )
+ nRet = ((HTML_CharEntry*)pFirst)->pUName->CompareTo(
+ *((HTML_CharEntry*)pSecond)->pUName );
+ else
+ nRet = ((HTML_CharEntry*)pFirst)->pUName->CompareToAscii(
+ ((HTML_CharEntry*)pSecond)->sName );
+ }
+ else
+ {
+ if( USHRT_MAX == ((HTML_CharEntry*)pSecond)->cChar )
+ nRet = -1 * ((HTML_CharEntry*)pSecond)->pUName->CompareToAscii(
+ ((HTML_CharEntry*)pFirst)->sName );
+ else
+ nRet = strcmp( ((HTML_CharEntry*)pFirst)->sName,
+ ((HTML_CharEntry*)pSecond)->sName );
+ }
+
+ return nRet;
+}
+
+}
+
+sal_Unicode GetHTMLCharName( const String& rName )
+{
+ if( !bSortCharKeyWords )
+ {
+ qsort( (void*) aHTMLCharNameTab,
+ sizeof( aHTMLCharNameTab ) / sizeof( HTML_CharEntry ),
+ sizeof( HTML_CharEntry ),
+ HTMLCharNameCompare );
+ bSortCharKeyWords = TRUE;
+ }
+
+ sal_Unicode cRet = 0;
+ void* pFound;
+ HTML_CharEntry aSrch;
+ aSrch.pUName = &rName;
+ aSrch.cChar = USHRT_MAX;
+
+ if( 0 != ( pFound = bsearch( (sal_Char *) &aSrch,
+ (void*) aHTMLCharNameTab,
+ sizeof( aHTMLCharNameTab) / sizeof( HTML_CharEntry ),
+ sizeof( HTML_CharEntry ),
+ HTMLCharNameCompare )))
+ cRet = ((HTML_CharEntry*)pFound)->cChar;
+ return cRet;
+}
+
+/* */
+
+// Flag: Optionen-Tabelle wurde schon sortiert
+static int __FAR_DATA bSortOptionKeyWords = FALSE;
+
+static HTML_TokenEntry __FAR_DATA aHTMLOptionTab[] = {
+
+// Attribute ohne Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_box}, HTML_O_BOX},
+ {{OOO_STRING_SVTOOLS_HTML_O_checked}, HTML_O_CHECKED},
+ {{OOO_STRING_SVTOOLS_HTML_O_compact}, HTML_O_COMPACT},
+ {{OOO_STRING_SVTOOLS_HTML_O_continue}, HTML_O_CONTINUE},
+ {{OOO_STRING_SVTOOLS_HTML_O_controls}, HTML_O_CONTROLS}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_declare}, HTML_O_DECLARE},
+ {{OOO_STRING_SVTOOLS_HTML_O_disabled}, HTML_O_DISABLED},
+ {{OOO_STRING_SVTOOLS_HTML_O_folded}, HTML_O_FOLDED}, // Netscape internal
+ {{OOO_STRING_SVTOOLS_HTML_O_ismap}, HTML_O_ISMAP},
+ {{OOO_STRING_SVTOOLS_HTML_O_mayscript}, HTML_O_MAYSCRIPT},
+ {{OOO_STRING_SVTOOLS_HTML_O_multiple}, HTML_O_MULTIPLE},
+ {{OOO_STRING_SVTOOLS_HTML_O_noflow}, HTML_O_NOFLOW},
+ {{OOO_STRING_SVTOOLS_HTML_O_nohref}, HTML_O_NOHREF}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_noresize}, HTML_O_NORESIZE}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_noshade}, HTML_O_NOSHADE}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_nowrap}, HTML_O_NOWRAP},
+ {{OOO_STRING_SVTOOLS_HTML_O_plain}, HTML_O_PLAIN},
+ {{OOO_STRING_SVTOOLS_HTML_O_sdfixed}, HTML_O_SDFIXED},
+ {{OOO_STRING_SVTOOLS_HTML_O_selected}, HTML_O_SELECTED},
+ {{OOO_STRING_SVTOOLS_HTML_O_shapes}, HTML_O_SHAPES},
+
+// Attribute mit einem String als Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_above}, HTML_O_ABOVE},
+ {{OOO_STRING_SVTOOLS_HTML_O_accept}, HTML_O_ACCEPT},
+ {{OOO_STRING_SVTOOLS_HTML_O_accesskey}, HTML_O_ACCESSKEY},
+ {{OOO_STRING_SVTOOLS_HTML_O_add_date}, HTML_O_ADD_DATE}, // Netscape internal
+ {{OOO_STRING_SVTOOLS_HTML_O_alt}, HTML_O_ALT},
+ {{OOO_STRING_SVTOOLS_HTML_O_axes}, HTML_O_AXES},
+ {{OOO_STRING_SVTOOLS_HTML_O_axis}, HTML_O_AXIS},
+ {{OOO_STRING_SVTOOLS_HTML_O_below}, HTML_O_BELOW},
+ {{OOO_STRING_SVTOOLS_HTML_O_char}, HTML_O_CHAR}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_class}, HTML_O_CLASS},
+ {{OOO_STRING_SVTOOLS_HTML_O_clip}, HTML_O_CLIP},
+ {{OOO_STRING_SVTOOLS_HTML_O_code}, HTML_O_CODE}, // HotJava
+ {{OOO_STRING_SVTOOLS_HTML_O_codetype}, HTML_O_CODETYPE},
+ {{OOO_STRING_SVTOOLS_HTML_O_colspec}, HTML_O_COLSPEC},
+ {{OOO_STRING_SVTOOLS_HTML_O_content}, HTML_O_CONTENT},
+ {{OOO_STRING_SVTOOLS_HTML_O_coords}, HTML_O_COORDS}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_dp}, HTML_O_DP},
+ {{OOO_STRING_SVTOOLS_HTML_O_enctype}, HTML_O_ENCTYPE},
+ {{OOO_STRING_SVTOOLS_HTML_O_error}, HTML_O_ERROR},
+ {{OOO_STRING_SVTOOLS_HTML_O_face}, HTML_O_FACE}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_frameborder}, HTML_O_FRAMEBORDER}, // IExplorer 3.0
+ {{OOO_STRING_SVTOOLS_HTML_O_httpequiv}, HTML_O_HTTPEQUIV},
+ {{OOO_STRING_SVTOOLS_HTML_O_language}, HTML_O_LANGUAGE}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_last_modified}, HTML_O_LAST_MODIFIED}, // Netscape internal
+ {{OOO_STRING_SVTOOLS_HTML_O_last_visit}, HTML_O_LAST_VISIT}, // Netscape internal
+ {{OOO_STRING_SVTOOLS_HTML_O_md}, HTML_O_MD},
+ {{OOO_STRING_SVTOOLS_HTML_O_n}, HTML_O_N},
+ {{OOO_STRING_SVTOOLS_HTML_O_name}, HTML_O_NAME},
+ {{OOO_STRING_SVTOOLS_HTML_O_notation}, HTML_O_NOTATION},
+ {{OOO_STRING_SVTOOLS_HTML_O_prompt}, HTML_O_PROMPT},
+ {{OOO_STRING_SVTOOLS_HTML_O_shape}, HTML_O_SHAPE},
+ {{OOO_STRING_SVTOOLS_HTML_O_standby}, HTML_O_STANDBY},
+ {{OOO_STRING_SVTOOLS_HTML_O_style}, HTML_O_STYLE},
+ {{OOO_STRING_SVTOOLS_HTML_O_title}, HTML_O_TITLE},
+ {{OOO_STRING_SVTOOLS_HTML_O_value}, HTML_O_VALUE},
+ {{OOO_STRING_SVTOOLS_HTML_O_SDval}, HTML_O_SDVAL}, // StarDiv NumberValue
+ {{OOO_STRING_SVTOOLS_HTML_O_SDnum}, HTML_O_SDNUM}, // StarDiv NumberFormat
+ {{OOO_STRING_SVTOOLS_HTML_O_sdlibrary}, HTML_O_SDLIBRARY},
+ {{OOO_STRING_SVTOOLS_HTML_O_sdmodule}, HTML_O_SDMODULE},
+
+// Attribute mit einem SGML-Identifier als Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_from}, HTML_O_FROM},
+ {{OOO_STRING_SVTOOLS_HTML_O_id}, HTML_O_ID},
+ {{OOO_STRING_SVTOOLS_HTML_O_target}, HTML_O_TARGET}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_to}, HTML_O_TO},
+ {{OOO_STRING_SVTOOLS_HTML_O_until}, HTML_O_UNTIL},
+
+// Attribute mit einem URI als Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_action}, HTML_O_ACTION},
+ {{OOO_STRING_SVTOOLS_HTML_O_archive}, HTML_O_ARCHIVE},
+ {{OOO_STRING_SVTOOLS_HTML_O_background}, HTML_O_BACKGROUND},
+ {{OOO_STRING_SVTOOLS_HTML_O_classid}, HTML_O_CLASSID},
+ {{OOO_STRING_SVTOOLS_HTML_O_codebase}, HTML_O_CODEBASE}, // HotJava
+ {{OOO_STRING_SVTOOLS_HTML_O_data}, HTML_O_DATA},
+ {{OOO_STRING_SVTOOLS_HTML_O_dynsrc}, HTML_O_DYNSRC}, // IExplorer 3.0b1
+ {{OOO_STRING_SVTOOLS_HTML_O_dynsync}, HTML_O_DYNSYNC}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_imagemap}, HTML_O_IMAGEMAP},
+ {{OOO_STRING_SVTOOLS_HTML_O_href}, HTML_O_HREF},
+ {{OOO_STRING_SVTOOLS_HTML_O_lowsrc}, HTML_O_LOWSRC}, // Netscape 3.0
+ {{OOO_STRING_SVTOOLS_HTML_O_script}, HTML_O_SCRIPT},
+ {{OOO_STRING_SVTOOLS_HTML_O_src}, HTML_O_SRC},
+ {{OOO_STRING_SVTOOLS_HTML_O_usemap}, HTML_O_USEMAP}, // Netscape 2.0
+
+// Attribute mit Entity-Namen als Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_dingbat}, HTML_O_DINGBAT},
+ {{OOO_STRING_SVTOOLS_HTML_O_sym}, HTML_O_SYM},
+
+// Attribute mit einer Farbe als Wert (alle Netscape)
+ {{OOO_STRING_SVTOOLS_HTML_O_alink}, HTML_O_ALINK},
+ {{OOO_STRING_SVTOOLS_HTML_O_bgcolor}, HTML_O_BGCOLOR},
+ {{OOO_STRING_SVTOOLS_HTML_O_bordercolor}, HTML_O_BORDERCOLOR}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_bordercolorlight}, HTML_O_BORDERCOLORLIGHT}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_bordercolordark}, HTML_O_BORDERCOLORDARK}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_color}, HTML_O_COLOR},
+ {{OOO_STRING_SVTOOLS_HTML_O_link}, HTML_O_LINK},
+ {{OOO_STRING_SVTOOLS_HTML_O_text}, HTML_O_TEXT},
+ {{OOO_STRING_SVTOOLS_HTML_O_vlink}, HTML_O_VLINK},
+
+// Attribute mit einem numerischen Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_border}, HTML_O_BORDER},
+ {{OOO_STRING_SVTOOLS_HTML_O_cellspacing},HTML_O_CELLSPACING}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_cellpadding},HTML_O_CELLPADDING}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_charoff}, HTML_O_CHAROFF}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_colspan}, HTML_O_COLSPAN},
+ {{OOO_STRING_SVTOOLS_HTML_O_framespacing}, HTML_O_FRAMESPACING}, // IExplorer 3.0
+ {{OOO_STRING_SVTOOLS_HTML_O_gutter}, HTML_O_GUTTER}, // Netscape 3.0b5
+ {{OOO_STRING_SVTOOLS_HTML_O_indent}, HTML_O_INDENT},
+ {{OOO_STRING_SVTOOLS_HTML_O_height}, HTML_O_HEIGHT},
+ {{OOO_STRING_SVTOOLS_HTML_O_hspace}, HTML_O_HSPACE}, // Netscape
+ {{OOO_STRING_SVTOOLS_HTML_O_left}, HTML_O_LEFT},
+ {{OOO_STRING_SVTOOLS_HTML_O_leftmargin}, HTML_O_LEFTMARGIN}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_loop}, HTML_O_LOOP}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_marginheight},HTML_O_MARGINHEIGHT}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_marginwidth},HTML_O_MARGINWIDTH}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_max}, HTML_O_MAX},
+ {{OOO_STRING_SVTOOLS_HTML_O_maxlength}, HTML_O_MAXLENGTH},
+ {{OOO_STRING_SVTOOLS_HTML_O_min}, HTML_O_MIN},
+ {{OOO_STRING_SVTOOLS_HTML_O_pagex}, HTML_O_PAGEX},
+ {{OOO_STRING_SVTOOLS_HTML_O_pagey}, HTML_O_PAGEY},
+ {{OOO_STRING_SVTOOLS_HTML_O_pointsize}, HTML_O_POINTSIZE},
+ {{OOO_STRING_SVTOOLS_HTML_O_rowspan}, HTML_O_ROWSPAN},
+ {{OOO_STRING_SVTOOLS_HTML_O_scrollamount}, HTML_O_SCROLLAMOUNT}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_scrolldelay}, HTML_O_SCROLLDELAY}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_seqnum}, HTML_O_SEQNUM},
+ {{OOO_STRING_SVTOOLS_HTML_O_skip}, HTML_O_SKIP},
+ {{OOO_STRING_SVTOOLS_HTML_O_span}, HTML_O_SPAN}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_tabindex}, HTML_O_TABINDEX},
+ {{OOO_STRING_SVTOOLS_HTML_O_top}, HTML_O_TOP},
+ {{OOO_STRING_SVTOOLS_HTML_O_topmargin}, HTML_O_TOPMARGIN}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_vspace}, HTML_O_VSPACE}, // Netscape
+ {{OOO_STRING_SVTOOLS_HTML_O_weight}, HTML_O_WEIGHT},
+ {{OOO_STRING_SVTOOLS_HTML_O_width}, HTML_O_WIDTH},
+ {{OOO_STRING_SVTOOLS_HTML_O_x}, HTML_O_X},
+ {{OOO_STRING_SVTOOLS_HTML_O_y}, HTML_O_Y},
+ {{OOO_STRING_SVTOOLS_HTML_O_zindex}, HTML_O_ZINDEX},
+
+// Attribute mit Enum-Werten
+ {{OOO_STRING_SVTOOLS_HTML_O_bgproperties}, HTML_O_BGPROPERTIES}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_behavior}, HTML_O_BEHAVIOR}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_clear}, HTML_O_CLEAR},
+ {{OOO_STRING_SVTOOLS_HTML_O_dir}, HTML_O_DIR}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_direction}, HTML_O_DIRECTION}, // IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_format}, HTML_O_FORMAT},
+ {{OOO_STRING_SVTOOLS_HTML_O_frame}, HTML_O_FRAME}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_lang}, HTML_O_LANG},
+ {{OOO_STRING_SVTOOLS_HTML_O_method}, HTML_O_METHOD},
+ {{OOO_STRING_SVTOOLS_HTML_O_palette}, HTML_O_PALETTE},
+ {{OOO_STRING_SVTOOLS_HTML_O_rel}, HTML_O_REL},
+ {{OOO_STRING_SVTOOLS_HTML_O_rev}, HTML_O_REV},
+ {{OOO_STRING_SVTOOLS_HTML_O_rules}, HTML_O_RULES}, // HTML 3 Table Model Draft
+ {{OOO_STRING_SVTOOLS_HTML_O_scrolling}, HTML_O_SCROLLING}, // Netscape 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_sdreadonly}, HTML_O_SDREADONLY},
+ {{OOO_STRING_SVTOOLS_HTML_O_subtype}, HTML_O_SUBTYPE},
+ {{OOO_STRING_SVTOOLS_HTML_O_type}, HTML_O_TYPE},
+ {{OOO_STRING_SVTOOLS_HTML_O_valign}, HTML_O_VALIGN},
+ {{OOO_STRING_SVTOOLS_HTML_O_valuetype}, HTML_O_VALUETYPE},
+ {{OOO_STRING_SVTOOLS_HTML_O_wrap}, HTML_O_WRAP},
+ {{OOO_STRING_SVTOOLS_HTML_O_visibility}, HTML_O_VISIBILITY},
+
+// Attribute mit Script-Code als Wert
+ {{OOO_STRING_SVTOOLS_HTML_O_onblur}, HTML_O_ONBLUR}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onchange}, HTML_O_ONCHANGE}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onclick}, HTML_O_ONCLICK}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onfocus}, HTML_O_ONFOCUS}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onload}, HTML_O_ONLOAD}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onmouseover}, HTML_O_ONMOUSEOVER}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onreset}, HTML_O_ONRESET}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onselect}, HTML_O_ONSELECT}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onsubmit}, HTML_O_ONSUBMIT}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onunload}, HTML_O_ONUNLOAD}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onabort}, HTML_O_ONABORT}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onerror}, HTML_O_ONERROR}, // JavaScript
+ {{OOO_STRING_SVTOOLS_HTML_O_onmouseout}, HTML_O_ONMOUSEOUT}, // JavaScript
+
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonblur}, HTML_O_SDONBLUR}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonchange}, HTML_O_SDONCHANGE}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonclick}, HTML_O_SDONCLICK}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonfocus}, HTML_O_SDONFOCUS}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonload}, HTML_O_SDONLOAD}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonmouseover}, HTML_O_SDONMOUSEOVER}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonreset}, HTML_O_SDONRESET}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonselect}, HTML_O_SDONSELECT}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonsubmit}, HTML_O_SDONSUBMIT}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonunload}, HTML_O_SDONUNLOAD}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonabort}, HTML_O_SDONABORT}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonerror}, HTML_O_SDONERROR}, // StarBasic
+ {{OOO_STRING_SVTOOLS_HTML_O_SDonmouseout}, HTML_O_SDONMOUSEOUT}, // StarBasic
+
+// Attribute mit Kontext-abhaengigen Werten
+ {{OOO_STRING_SVTOOLS_HTML_O_align}, HTML_O_ALIGN},
+ {{OOO_STRING_SVTOOLS_HTML_O_cols}, HTML_O_COLS}, // Netscape 2.0 vs HTML 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_rows}, HTML_O_ROWS}, // Netscape 2.0 vs HTML 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_size}, HTML_O_SIZE},
+ {{OOO_STRING_SVTOOLS_HTML_O_start}, HTML_O_START}, // Netscape 2.0 vs IExplorer 2.0
+ {{OOO_STRING_SVTOOLS_HTML_O_units}, HTML_O_UNITS}
+};
+
+int GetHTMLOption( const String& rName )
+{
+ if( !bSortOptionKeyWords )
+ {
+ qsort( (void*) aHTMLOptionTab,
+ sizeof( aHTMLOptionTab ) / sizeof( HTML_TokenEntry ),
+ sizeof( HTML_TokenEntry ),
+ HTMLKeyCompare );
+ bSortOptionKeyWords = TRUE;
+ }
+
+ int nRet = HTML_O_UNKNOWN;
+ void* pFound;
+ HTML_TokenEntry aSrch;
+ aSrch.pUToken = &rName;
+ aSrch.nToken = -1;
+
+ if( 0 != ( pFound = bsearch( (sal_Char *) &aSrch,
+ (void*) aHTMLOptionTab,
+ sizeof( aHTMLOptionTab ) / sizeof( HTML_TokenEntry ),
+ sizeof( HTML_TokenEntry ),
+ HTMLKeyCompare )))
+ nRet = ((HTML_TokenEntry*)pFound)->nToken;
+ return nRet;
+}
+
+/* */
+
+// Flag: Farb-Tabelle wurde schon sortiert
+struct HTML_ColorEntry
+{
+ union
+ {
+ const sal_Char* sName;
+ const String *pUName;
+ };
+ ULONG nColor;
+};
+
+static int __FAR_DATA bSortColorKeyWords = FALSE;
+
+#define HTML_NO_COLOR 0xffffffffUL
+
+// die Farbnamen werden nicht exportiert
+// Sie stammen aus "http://www.uio.no/~mnbjerke/colors_w.html"
+// und scheinen im Gegensatz zu denen aus
+// "http://www.infi.net/wwwimages/colorindex.html"
+// zu stimmen
+static HTML_ColorEntry __FAR_DATA aHTMLColorNameTab[] = {
+ { { "ALICEBLUE" }, 0x00f0f8ffUL },
+ { { "ANTIQUEWHITE" }, 0x00faebd7UL },
+ { { "AQUA" }, 0x0000ffffUL },
+ { { "AQUAMARINE" }, 0x007fffd4UL },
+ { { "AZURE" }, 0x00f0ffffUL },
+ { { "BEIGE" }, 0x00f5f5dcUL },
+ { { "BISQUE" }, 0x00ffe4c4UL },
+ { { "BLACK" }, 0x00000000UL },
+ { { "BLANCHEDALMOND" }, 0x00ffebcdUL },
+ { { "BLUE" }, 0x000000ffUL },
+ { { "BLUEVIOLET" }, 0x008a2be2UL },
+ { { "BROWN" }, 0x00a52a2aUL },
+ { { "BURLYWOOD" }, 0x00deb887UL },
+ { { "CADETBLUE" }, 0x005f9ea0UL },
+ { { "CHARTREUSE" }, 0x007fff00UL },
+ { { "CHOCOLATE" }, 0x00d2691eUL },
+ { { "CORAL" }, 0x00ff7f50UL },
+ { { "CORNFLOWERBLUE" }, 0x006495edUL },
+ { { "CORNSILK" }, 0x00fff8dcUL },
+ { { "CRIMSON" }, 0x00dc143cUL },
+ { { "CYAN" }, 0x0000ffffUL },
+ { { "DARKBLUE" }, 0x0000008bUL },
+ { { "DARKCYAN" }, 0x00008b8bUL },
+ { { "DARKGOLDENROD" }, 0x00b8860bUL },
+ { { "DARKGRAY" }, 0x00a9a9a9UL },
+ { { "DARKGREEN" }, 0x00006400UL },
+ { { "DARKKHAKI" }, 0x00bdb76bUL },
+ { { "DARKMAGENTA" }, 0x008b008bUL },
+ { { "DARKOLIVEGREEN" }, 0x00556b2fUL },
+ { { "DARKORANGE" }, 0x00ff8c00UL },
+ { { "DARKORCHID" }, 0x009932ccUL },
+ { { "DARKRED" }, 0x008b0000UL },
+ { { "DARKSALMON" }, 0x00e9967aUL },
+ { { "DARKSEAGREEN" }, 0x008fbc8fUL },
+ { { "DARKSLATEBLUE" }, 0x00483d8bUL },
+ { { "DARKSLATEGRAY" }, 0x002f4f4fUL },
+ { { "DARKTURQUOISE" }, 0x0000ced1UL },
+ { { "DARKVIOLET" }, 0x009400d3UL },
+ { { "DEEPPINK" }, 0x00ff1493UL },
+ { { "DEEPSKYBLUE" }, 0x0000bfffUL },
+ { { "DIMGRAY" }, 0x00696969UL },
+ { { "DODGERBLUE" }, 0x001e90ffUL },
+ { { "FIREBRICK" }, 0x00b22222UL },
+ { { "FLORALWHITE" }, 0x00fffaf0UL },
+ { { "FORESTGREEN" }, 0x00228b22UL },
+ { { "FUCHSIA" }, 0x00ff00ffUL },
+ { { "GAINSBORO" }, 0x00dcdcdcUL },
+ { { "GHOSTWHITE" }, 0x00f8f8ffUL },
+ { { "GOLD" }, 0x00ffd700UL },
+ { { "GOLDENROD" }, 0x00daa520UL },
+ { { "GRAY" }, 0x00808080UL },
+ { { "GREEN" }, 0x00008000UL },
+ { { "GREENYELLOW" }, 0x00adff2fUL },
+ { { "HONEYDEW" }, 0x00f0fff0UL },
+ { { "HOTPINK" }, 0x00ff69b4UL },
+ { { "INDIANRED" }, 0x00cd5c5cUL },
+ { { "INDIGO" }, 0x004b0082UL },
+ { { "IVORY" }, 0x00fffff0UL },
+ { { "KHAKI" }, 0x00f0e68cUL },
+ { { "LAVENDER" }, 0x00e6e6faUL },
+ { { "LAVENDERBLUSH" }, 0x00fff0f5UL },
+ { { "LAWNGREEN" }, 0x007cfc00UL },
+ { { "LEMONCHIFFON" }, 0x00fffacdUL },
+ { { "LIGHTBLUE" }, 0x00add8e6UL },
+ { { "LIGHTCORAL" }, 0x00f08080UL },
+ { { "LIGHTCYAN" }, 0x00e0ffffUL },
+ { { "LIGHTGOLDENRODYELLOW" }, 0x00fafad2UL },
+ { { "LIGHTGREEN" }, 0x0090ee90UL },
+ { { "LIGHTGREY" }, 0x00d3d3d3UL },
+ { { "LIGHTPINK" }, 0x00ffb6c1UL },
+ { { "LIGHTSALMON" }, 0x00ffa07aUL },
+ { { "LIGHTSEAGREEN" }, 0x0020b2aaUL },
+ { { "LIGHTSKYBLUE" }, 0x0087cefaUL },
+ { { "LIGHTSLATEGRAY" }, 0x00778899UL },
+ { { "LIGHTSTEELBLUE" }, 0x00b0c4deUL },
+ { { "LIGHTYELLOW" }, 0x00ffffe0UL },
+ { { "LIME" }, 0x0000ff00UL },
+ { { "LIMEGREEN" }, 0x0032cd32UL },
+ { { "LINEN" }, 0x00faf0e6UL },
+ { { "MAGENTA" }, 0x00ff00ffUL },
+ { { "MAROON" }, 0x00800000UL },
+ { { "MEDIUMAQUAMARINE" }, 0x0066cdaaUL },
+ { { "MEDIUMBLUE" }, 0x000000cdUL },
+ { { "MEDIUMORCHID" }, 0x00ba55d3UL },
+ { { "MEDIUMPURPLE" }, 0x009370dbUL },
+ { { "MEDIUMSEAGREEN" }, 0x003cb371UL },
+ { { "MEDIUMSLATEBLUE" }, 0x007b68eeUL },
+ { { "MEDIUMSPRINGGREEN" }, 0x0000fa9aUL },
+ { { "MEDIUMTURQUOISE" }, 0x0048d1ccUL },
+ { { "MEDIUMVIOLETRED" }, 0x00c71585UL },
+ { { "MIDNIGHTBLUE" }, 0x00191970UL },
+ { { "MINTCREAM" }, 0x00f5fffaUL },
+ { { "MISTYROSE" }, 0x00ffe4e1UL },
+ { { "MOCCASIN" }, 0x00ffe4b5UL },
+ { { "NAVAJOWHITE" }, 0x00ffdeadUL },
+ { { "NAVY" }, 0x00000080UL },
+ { { "OLDLACE" }, 0x00fdf5e6UL },
+ { { "OLIVE" }, 0x00808000UL },
+ { { "OLIVEDRAB" }, 0x006b8e23UL },
+ { { "ORANGE" }, 0x00ffa500UL },
+ { { "ORANGERED" }, 0x00ff4500UL },
+ { { "ORCHID" }, 0x00da70d6UL },
+ { { "PALEGOLDENROD" }, 0x00eee8aaUL },
+ { { "PALEGREEN" }, 0x0098fb98UL },
+ { { "PALETURQUOISE" }, 0x00afeeeeUL },
+ { { "PALEVIOLETRED" }, 0x00db7093UL },
+ { { "PAPAYAWHIP" }, 0x00ffefd5UL },
+ { { "PEACHPUFF" }, 0x00ffdab9UL },
+ { { "PERU" }, 0x00cd853fUL },
+ { { "PINK" }, 0x00ffc0cbUL },
+ { { "PLUM" }, 0x00dda0ddUL },
+ { { "POWDERBLUE" }, 0x00b0e0e6UL },
+ { { "PURPLE" }, 0x00800080UL },
+ { { "RED" }, 0x00ff0000UL },
+ { { "ROSYBROWN" }, 0x00bc8f8fUL },
+ { { "ROYALBLUE" }, 0x004169e1UL },
+ { { "SADDLEBROWN" }, 0x008b4513UL },
+ { { "SALMON" }, 0x00fa8072UL },
+ { { "SANDYBROWN" }, 0x00f4a460UL },
+ { { "SEAGREEN" }, 0x002e8b57UL },
+ { { "SEASHELL" }, 0x00fff5eeUL },
+ { { "SIENNA" }, 0x00a0522dUL },
+ { { "SILVER" }, 0x00c0c0c0UL },
+ { { "SKYBLUE" }, 0x0087ceebUL },
+ { { "SLATEBLUE" }, 0x006a5acdUL },
+ { { "SLATEGRAY" }, 0x00708090UL },
+ { { "SNOW" }, 0x00fffafaUL },
+ { { "SPRINGGREEN" }, 0x0000ff7fUL },
+ { { "STEELBLUE" }, 0x004682b4UL },
+ { { "TAN" }, 0x00d2b48cUL },
+ { { "TEAL" }, 0x00008080UL },
+ { { "THISTLE" }, 0x00d8bfd8UL },
+ { { "TOMATO" }, 0x00ff6347UL },
+ { { "TURQUOISE" }, 0x0040e0d0UL },
+ { { "VIOLET" }, 0x00ee82eeUL },
+ { { "WHEAT" }, 0x00f5deb3UL },
+ { { "WHITE" }, 0x00ffffffUL },
+ { { "WHITESMOKE" }, 0x00f5f5f5UL },
+ { { "YELLOW" }, 0x00ffff00UL },
+ { { "YELLOWGREEN" }, 0x009acd32UL }
+};
+
+extern "C"
+{
+
+static int
+#if defined( WNT )
+ __cdecl
+#endif
+#if defined( ICC ) && defined( OS2 )
+ _Optlink
+#endif
+ HTMLColorNameCompare( const void *pFirst, const void *pSecond)
+{
+ int nRet = 0;
+ if( HTML_NO_COLOR == ((HTML_ColorEntry*)pFirst)->nColor )
+ {
+ if( HTML_NO_COLOR == ((HTML_ColorEntry*)pSecond)->nColor )
+ nRet = ((HTML_ColorEntry*)pFirst)->pUName->CompareTo(
+ *((HTML_ColorEntry*)pSecond)->pUName );
+ else
+ nRet = ((HTML_ColorEntry*)pFirst)->pUName->CompareToAscii(
+ ((HTML_ColorEntry*)pSecond)->sName );
+ }
+ else
+ {
+ if( HTML_NO_COLOR == ((HTML_ColorEntry*)pSecond)->nColor )
+ nRet = -1 * ((HTML_ColorEntry*)pSecond)->pUName->CompareToAscii(
+ ((HTML_ColorEntry*)pFirst)->sName );
+ else
+ nRet = strcmp( ((HTML_ColorEntry*)pFirst)->sName,
+ ((HTML_ColorEntry*)pSecond)->sName );
+ }
+
+ return nRet;
+}
+
+}
+
+ULONG GetHTMLColor( const String& rName )
+{
+ if( !bSortColorKeyWords )
+ {
+ qsort( (void*) aHTMLColorNameTab,
+ sizeof( aHTMLColorNameTab ) / sizeof( HTML_ColorEntry ),
+ sizeof( HTML_ColorEntry ),
+ HTMLColorNameCompare );
+ bSortColorKeyWords = TRUE;
+ }
+
+ ULONG nRet = ULONG_MAX;
+ void* pFound;
+ HTML_ColorEntry aSrch;
+ aSrch.pUName = &rName;
+ aSrch.nColor = HTML_NO_COLOR;
+
+ if( 0 != ( pFound = bsearch( (sal_Char *) &aSrch,
+ (void*) aHTMLColorNameTab,
+ sizeof( aHTMLColorNameTab) / sizeof( HTML_ColorEntry ),
+ sizeof( HTML_ColorEntry ),
+ HTMLColorNameCompare )))
+ nRet = ((HTML_ColorEntry*)pFound)->nColor;
+
+ return nRet;
+}
+
diff --git a/svtools/source/svhtml/htmlout.cxx b/svtools/source/svhtml/htmlout.cxx
new file mode 100644
index 000000000000..af0d0dff9667
--- /dev/null
+++ b/svtools/source/svhtml/htmlout.cxx
@@ -0,0 +1,980 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <tools/urlobj.hxx>
+#include <svl/zformat.hxx>
+#include <svl/macitem.hxx>
+#include <tools/cachestr.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/zforlist.hxx>
+
+#include <svtools/htmlout.hxx>
+#include "htmlkywd.hxx"
+#include <svtools/imap.hxx>
+#include <svtools/imaprect.hxx>
+#include <svtools/imapcirc.hxx>
+#include <svtools/imappoly.hxx>
+#include "svl/urihelper.hxx"
+
+#ifndef RTL_CONSTASCII_STRINGPARAM
+#define RTL_CONSTASCII_STRINGPARAM( c ) c, sizeof(c)-1
+#endif
+
+#if defined(UNX)
+const sal_Char HTMLOutFuncs::sNewLine = '\012';
+#else
+const sal_Char __FAR_DATA HTMLOutFuncs::sNewLine[] = "\015\012";
+#endif
+
+#define TXTCONV_BUFFER_SIZE 20
+
+HTMLOutContext::HTMLOutContext( rtl_TextEncoding eDestEnc )
+{
+ m_eDestEnc = RTL_TEXTENCODING_DONTKNOW == eDestEnc
+ ? gsl_getSystemTextEncoding()
+ : eDestEnc;
+
+ m_hConv = rtl_createUnicodeToTextConverter( eDestEnc );
+ DBG_ASSERT( m_hConv,
+ "HTMLOutContext::HTMLOutContext: no converter for source encoding" );
+ m_hContext = m_hConv ? rtl_createUnicodeToTextContext( m_hConv )
+ : (rtl_TextToUnicodeContext)1;
+}
+
+HTMLOutContext::~HTMLOutContext()
+{
+ rtl_destroyUnicodeToTextContext( m_hConv, m_hContext );
+ rtl_destroyUnicodeToTextConverter( m_hConv );
+}
+
+const sal_Char *lcl_svhtml_GetEntityForChar( sal_Unicode c,
+ rtl_TextEncoding eDestEnc )
+{
+ const sal_Char* pStr = 0;
+
+ // Note: We currently handle special cases for ISO-8859-2 here simply because
+ // the code was already submitted. But we should also handle other code pages
+ // as well as the code becomes available.
+
+ if( eDestEnc == RTL_TEXTENCODING_ISO_8859_2 || eDestEnc == RTL_TEXTENCODING_MS_1250 )
+ {
+ // Don't handle the following characters for Easter European (ISO-8859-2).
+ switch ( c )
+ {
+ case 164: // curren
+ case 184: // ccedil
+ case 193: // Aacute
+ case 194: // Acirc
+ case 196: // Auml
+ case 199: // Ccedil
+ case 201: // Eacute
+ case 203: // Euml
+ case 205: // Iacute
+ case 206: // Icirc
+ case 211: // Oacute
+ case 212: // Ocirc
+ case 214: // Ouml
+ case 215: // times
+ case 218: // Uacute
+ case 220: // Uuml
+ case 221: // Yacute
+ case 225: // aacute
+ case 226: // acirc
+ case 228: // auml
+ case 233: // eacute
+ case 235: // euml
+ case 237: // iacute
+ case 238: // icirc
+ case 243: // oacute
+ case 244: // ocirc
+ case 246: // ouml
+ case 247: // divide
+ case 250: // uacute
+ case 252: // uuml
+ case 253: // yacute
+ case 352: // Scaron
+ case 353: // scaron
+ return pStr;
+ }
+ }
+
+ // TODO: handle more special cases for other code pages.
+
+ switch( c )
+ {
+// case '\x0a': return HTMLOutFuncs::Out_Tag( rStream, OOO_STRING_SVTOOLS_HTML_linebreak );
+
+ case '<': pStr = OOO_STRING_SVTOOLS_HTML_C_lt; break;
+ case '>': pStr = OOO_STRING_SVTOOLS_HTML_C_gt; break;
+ case '&': pStr = OOO_STRING_SVTOOLS_HTML_C_amp; break;
+ case '"': pStr = OOO_STRING_SVTOOLS_HTML_C_quot; break;
+
+ case 161: pStr = OOO_STRING_SVTOOLS_HTML_S_iexcl; break;
+ case 162: pStr = OOO_STRING_SVTOOLS_HTML_S_cent; break;
+ case 163: pStr = OOO_STRING_SVTOOLS_HTML_S_pound; break;
+ case 164: pStr = OOO_STRING_SVTOOLS_HTML_S_curren; break;
+ case 165: pStr = OOO_STRING_SVTOOLS_HTML_S_yen; break;
+ case 166: pStr = OOO_STRING_SVTOOLS_HTML_S_brvbar; break;
+ case 167: pStr = OOO_STRING_SVTOOLS_HTML_S_sect; break;
+ case 168: pStr = OOO_STRING_SVTOOLS_HTML_S_uml; break;
+ case 169: pStr = OOO_STRING_SVTOOLS_HTML_S_copy; break;
+ case 170: pStr = OOO_STRING_SVTOOLS_HTML_S_ordf; break;
+ case 171: pStr = OOO_STRING_SVTOOLS_HTML_S_laquo; break;
+ case 172: pStr = OOO_STRING_SVTOOLS_HTML_S_not; break;
+ case 174: pStr = OOO_STRING_SVTOOLS_HTML_S_reg; break;
+ case 175: pStr = OOO_STRING_SVTOOLS_HTML_S_macr; break;
+ case 176: pStr = OOO_STRING_SVTOOLS_HTML_S_deg; break;
+ case 177: pStr = OOO_STRING_SVTOOLS_HTML_S_plusmn; break;
+ case 178: pStr = OOO_STRING_SVTOOLS_HTML_S_sup2; break;
+ case 179: pStr = OOO_STRING_SVTOOLS_HTML_S_sup3; break;
+ case 180: pStr = OOO_STRING_SVTOOLS_HTML_S_acute; break;
+ case 181: pStr = OOO_STRING_SVTOOLS_HTML_S_micro; break;
+ case 182: pStr = OOO_STRING_SVTOOLS_HTML_S_para; break;
+ case 183: pStr = OOO_STRING_SVTOOLS_HTML_S_middot; break;
+ case 184: pStr = OOO_STRING_SVTOOLS_HTML_S_cedil; break;
+ case 185: pStr = OOO_STRING_SVTOOLS_HTML_S_sup1; break;
+ case 186: pStr = OOO_STRING_SVTOOLS_HTML_S_ordm; break;
+ case 187: pStr = OOO_STRING_SVTOOLS_HTML_S_raquo; break;
+ case 188: pStr = OOO_STRING_SVTOOLS_HTML_S_frac14; break;
+ case 189: pStr = OOO_STRING_SVTOOLS_HTML_S_frac12; break;
+ case 190: pStr = OOO_STRING_SVTOOLS_HTML_S_frac34; break;
+ case 191: pStr = OOO_STRING_SVTOOLS_HTML_S_iquest; break;
+
+ case 192: pStr = OOO_STRING_SVTOOLS_HTML_C_Agrave; break;
+ case 193: pStr = OOO_STRING_SVTOOLS_HTML_C_Aacute; break;
+ case 194: pStr = OOO_STRING_SVTOOLS_HTML_C_Acirc; break;
+ case 195: pStr = OOO_STRING_SVTOOLS_HTML_C_Atilde; break;
+ case 196: pStr = OOO_STRING_SVTOOLS_HTML_C_Auml; break;
+ case 197: pStr = OOO_STRING_SVTOOLS_HTML_C_Aring; break;
+ case 198: pStr = OOO_STRING_SVTOOLS_HTML_C_AElig; break;
+ case 199: pStr = OOO_STRING_SVTOOLS_HTML_C_Ccedil; break;
+ case 200: pStr = OOO_STRING_SVTOOLS_HTML_C_Egrave; break;
+ case 201: pStr = OOO_STRING_SVTOOLS_HTML_C_Eacute; break;
+ case 202: pStr = OOO_STRING_SVTOOLS_HTML_C_Ecirc; break;
+ case 203: pStr = OOO_STRING_SVTOOLS_HTML_C_Euml; break;
+ case 204: pStr = OOO_STRING_SVTOOLS_HTML_C_Igrave; break;
+ case 205: pStr = OOO_STRING_SVTOOLS_HTML_C_Iacute; break;
+ case 206: pStr = OOO_STRING_SVTOOLS_HTML_C_Icirc; break;
+ case 207: pStr = OOO_STRING_SVTOOLS_HTML_C_Iuml; break;
+ case 208: pStr = OOO_STRING_SVTOOLS_HTML_C_ETH; break;
+ case 209: pStr = OOO_STRING_SVTOOLS_HTML_C_Ntilde; break;
+ case 210: pStr = OOO_STRING_SVTOOLS_HTML_C_Ograve; break;
+ case 211: pStr = OOO_STRING_SVTOOLS_HTML_C_Oacute; break;
+ case 212: pStr = OOO_STRING_SVTOOLS_HTML_C_Ocirc; break;
+ case 213: pStr = OOO_STRING_SVTOOLS_HTML_C_Otilde; break;
+ case 214: pStr = OOO_STRING_SVTOOLS_HTML_C_Ouml; break;
+ case 215: pStr = OOO_STRING_SVTOOLS_HTML_S_times; break;
+ case 216: pStr = OOO_STRING_SVTOOLS_HTML_C_Oslash; break;
+ case 217: pStr = OOO_STRING_SVTOOLS_HTML_C_Ugrave; break;
+ case 218: pStr = OOO_STRING_SVTOOLS_HTML_C_Uacute; break;
+ case 219: pStr = OOO_STRING_SVTOOLS_HTML_C_Ucirc; break;
+ case 220: pStr = OOO_STRING_SVTOOLS_HTML_C_Uuml; break;
+ case 221: pStr = OOO_STRING_SVTOOLS_HTML_C_Yacute; break;
+
+ case 222: pStr = OOO_STRING_SVTOOLS_HTML_C_THORN; break;
+ case 223: pStr = OOO_STRING_SVTOOLS_HTML_C_szlig; break;
+
+ case 224: pStr = OOO_STRING_SVTOOLS_HTML_S_agrave; break;
+ case 225: pStr = OOO_STRING_SVTOOLS_HTML_S_aacute; break;
+ case 226: pStr = OOO_STRING_SVTOOLS_HTML_S_acirc; break;
+ case 227: pStr = OOO_STRING_SVTOOLS_HTML_S_atilde; break;
+ case 228: pStr = OOO_STRING_SVTOOLS_HTML_S_auml; break;
+ case 229: pStr = OOO_STRING_SVTOOLS_HTML_S_aring; break;
+ case 230: pStr = OOO_STRING_SVTOOLS_HTML_S_aelig; break;
+ case 231: pStr = OOO_STRING_SVTOOLS_HTML_S_ccedil; break;
+ case 232: pStr = OOO_STRING_SVTOOLS_HTML_S_egrave; break;
+ case 233: pStr = OOO_STRING_SVTOOLS_HTML_S_eacute; break;
+ case 234: pStr = OOO_STRING_SVTOOLS_HTML_S_ecirc; break;
+ case 235: pStr = OOO_STRING_SVTOOLS_HTML_S_euml; break;
+ case 236: pStr = OOO_STRING_SVTOOLS_HTML_S_igrave; break;
+ case 237: pStr = OOO_STRING_SVTOOLS_HTML_S_iacute; break;
+ case 238: pStr = OOO_STRING_SVTOOLS_HTML_S_icirc; break;
+ case 239: pStr = OOO_STRING_SVTOOLS_HTML_S_iuml; break;
+ case 240: pStr = OOO_STRING_SVTOOLS_HTML_S_eth; break;
+ case 241: pStr = OOO_STRING_SVTOOLS_HTML_S_ntilde; break;
+ case 242: pStr = OOO_STRING_SVTOOLS_HTML_S_ograve; break;
+ case 243: pStr = OOO_STRING_SVTOOLS_HTML_S_oacute; break;
+ case 244: pStr = OOO_STRING_SVTOOLS_HTML_S_ocirc; break;
+ case 245: pStr = OOO_STRING_SVTOOLS_HTML_S_otilde; break;
+ case 246: pStr = OOO_STRING_SVTOOLS_HTML_S_ouml; break;
+ case 247: pStr = OOO_STRING_SVTOOLS_HTML_S_divide; break;
+ case 248: pStr = OOO_STRING_SVTOOLS_HTML_S_oslash; break;
+ case 249: pStr = OOO_STRING_SVTOOLS_HTML_S_ugrave; break;
+ case 250: pStr = OOO_STRING_SVTOOLS_HTML_S_uacute; break;
+ case 251: pStr = OOO_STRING_SVTOOLS_HTML_S_ucirc; break;
+ case 252: pStr = OOO_STRING_SVTOOLS_HTML_S_uuml; break;
+ case 253: pStr = OOO_STRING_SVTOOLS_HTML_S_yacute; break;
+ case 254: pStr = OOO_STRING_SVTOOLS_HTML_S_thorn; break;
+ case 255: pStr = OOO_STRING_SVTOOLS_HTML_S_yuml; break;
+
+ case 338: pStr = OOO_STRING_SVTOOLS_HTML_S_OElig; break;
+ case 339: pStr = OOO_STRING_SVTOOLS_HTML_S_oelig; break;
+ case 352: pStr = OOO_STRING_SVTOOLS_HTML_S_Scaron; break;
+ case 353: pStr = OOO_STRING_SVTOOLS_HTML_S_scaron; break;
+ case 376: pStr = OOO_STRING_SVTOOLS_HTML_S_Yuml; break;
+ case 402: pStr = OOO_STRING_SVTOOLS_HTML_S_fnof; break;
+ case 710: pStr = OOO_STRING_SVTOOLS_HTML_S_circ; break;
+ case 732: pStr = OOO_STRING_SVTOOLS_HTML_S_tilde; break;
+
+ // Greek chars are handled later,
+ // since they should *not* be transformed to entities
+ // when generating Greek text (== using Greek encoding)
+
+ case 8194: pStr = OOO_STRING_SVTOOLS_HTML_S_ensp; break;
+ case 8195: pStr = OOO_STRING_SVTOOLS_HTML_S_emsp; break;
+ case 8201: pStr = OOO_STRING_SVTOOLS_HTML_S_thinsp; break;
+ case 8204: pStr = OOO_STRING_SVTOOLS_HTML_S_zwnj; break;
+ case 8205: pStr = OOO_STRING_SVTOOLS_HTML_S_zwj; break;
+ case 8206: pStr = OOO_STRING_SVTOOLS_HTML_S_lrm; break;
+ case 8207: pStr = OOO_STRING_SVTOOLS_HTML_S_rlm; break;
+ case 8211: pStr = OOO_STRING_SVTOOLS_HTML_S_ndash; break;
+ case 8212: pStr = OOO_STRING_SVTOOLS_HTML_S_mdash; break;
+ case 8216: pStr = OOO_STRING_SVTOOLS_HTML_S_lsquo; break;
+ case 8217: pStr = OOO_STRING_SVTOOLS_HTML_S_rsquo; break;
+ case 8218: pStr = OOO_STRING_SVTOOLS_HTML_S_sbquo; break;
+ case 8220: pStr = OOO_STRING_SVTOOLS_HTML_S_ldquo; break;
+ case 8221: pStr = OOO_STRING_SVTOOLS_HTML_S_rdquo; break;
+ case 8222: pStr = OOO_STRING_SVTOOLS_HTML_S_bdquo; break;
+ case 8224: pStr = OOO_STRING_SVTOOLS_HTML_S_dagger; break;
+ case 8225: pStr = OOO_STRING_SVTOOLS_HTML_S_Dagger; break;
+ case 8226: pStr = OOO_STRING_SVTOOLS_HTML_S_bull; break;
+ case 8230: pStr = OOO_STRING_SVTOOLS_HTML_S_hellip; break;
+ case 8240: pStr = OOO_STRING_SVTOOLS_HTML_S_permil; break;
+ case 8242: pStr = OOO_STRING_SVTOOLS_HTML_S_prime; break;
+ case 8243: pStr = OOO_STRING_SVTOOLS_HTML_S_Prime; break;
+ case 8249: pStr = OOO_STRING_SVTOOLS_HTML_S_lsaquo; break;
+ case 8250: pStr = OOO_STRING_SVTOOLS_HTML_S_rsaquo; break;
+ case 8254: pStr = OOO_STRING_SVTOOLS_HTML_S_oline; break;
+ case 8260: pStr = OOO_STRING_SVTOOLS_HTML_S_frasl; break;
+ case 8364: pStr = OOO_STRING_SVTOOLS_HTML_S_euro; break;
+ case 8465: pStr = OOO_STRING_SVTOOLS_HTML_S_image; break;
+ case 8472: pStr = OOO_STRING_SVTOOLS_HTML_S_weierp; break;
+ case 8476: pStr = OOO_STRING_SVTOOLS_HTML_S_real; break;
+ case 8482: pStr = OOO_STRING_SVTOOLS_HTML_S_trade; break;
+ case 8501: pStr = OOO_STRING_SVTOOLS_HTML_S_alefsym; break;
+ case 8592: pStr = OOO_STRING_SVTOOLS_HTML_S_larr; break;
+ case 8593: pStr = OOO_STRING_SVTOOLS_HTML_S_uarr; break;
+ case 8594: pStr = OOO_STRING_SVTOOLS_HTML_S_rarr; break;
+ case 8595: pStr = OOO_STRING_SVTOOLS_HTML_S_darr; break;
+ case 8596: pStr = OOO_STRING_SVTOOLS_HTML_S_harr; break;
+ case 8629: pStr = OOO_STRING_SVTOOLS_HTML_S_crarr; break;
+ case 8656: pStr = OOO_STRING_SVTOOLS_HTML_S_lArr; break;
+ case 8657: pStr = OOO_STRING_SVTOOLS_HTML_S_uArr; break;
+ case 8658: pStr = OOO_STRING_SVTOOLS_HTML_S_rArr; break;
+ case 8659: pStr = OOO_STRING_SVTOOLS_HTML_S_dArr; break;
+ case 8660: pStr = OOO_STRING_SVTOOLS_HTML_S_hArr; break;
+ case 8704: pStr = OOO_STRING_SVTOOLS_HTML_S_forall; break;
+ case 8706: pStr = OOO_STRING_SVTOOLS_HTML_S_part; break;
+ case 8707: pStr = OOO_STRING_SVTOOLS_HTML_S_exist; break;
+ case 8709: pStr = OOO_STRING_SVTOOLS_HTML_S_empty; break;
+ case 8711: pStr = OOO_STRING_SVTOOLS_HTML_S_nabla; break;
+ case 8712: pStr = OOO_STRING_SVTOOLS_HTML_S_isin; break;
+ case 8713: pStr = OOO_STRING_SVTOOLS_HTML_S_notin; break;
+ case 8715: pStr = OOO_STRING_SVTOOLS_HTML_S_ni; break;
+ case 8719: pStr = OOO_STRING_SVTOOLS_HTML_S_prod; break;
+ case 8721: pStr = OOO_STRING_SVTOOLS_HTML_S_sum; break;
+ case 8722: pStr = OOO_STRING_SVTOOLS_HTML_S_minus; break;
+ case 8727: pStr = OOO_STRING_SVTOOLS_HTML_S_lowast; break;
+ case 8730: pStr = OOO_STRING_SVTOOLS_HTML_S_radic; break;
+ case 8733: pStr = OOO_STRING_SVTOOLS_HTML_S_prop; break;
+ case 8734: pStr = OOO_STRING_SVTOOLS_HTML_S_infin; break;
+ case 8736: pStr = OOO_STRING_SVTOOLS_HTML_S_ang; break;
+ case 8743: pStr = OOO_STRING_SVTOOLS_HTML_S_and; break;
+ case 8744: pStr = OOO_STRING_SVTOOLS_HTML_S_or; break;
+ case 8745: pStr = OOO_STRING_SVTOOLS_HTML_S_cap; break;
+ case 8746: pStr = OOO_STRING_SVTOOLS_HTML_S_cup; break;
+ case 8747: pStr = OOO_STRING_SVTOOLS_HTML_S_int; break;
+ case 8756: pStr = OOO_STRING_SVTOOLS_HTML_S_there4; break;
+ case 8764: pStr = OOO_STRING_SVTOOLS_HTML_S_sim; break;
+ case 8773: pStr = OOO_STRING_SVTOOLS_HTML_S_cong; break;
+ case 8776: pStr = OOO_STRING_SVTOOLS_HTML_S_asymp; break;
+ case 8800: pStr = OOO_STRING_SVTOOLS_HTML_S_ne; break;
+ case 8801: pStr = OOO_STRING_SVTOOLS_HTML_S_equiv; break;
+ case 8804: pStr = OOO_STRING_SVTOOLS_HTML_S_le; break;
+ case 8805: pStr = OOO_STRING_SVTOOLS_HTML_S_ge; break;
+ case 8834: pStr = OOO_STRING_SVTOOLS_HTML_S_sub; break;
+ case 8835: pStr = OOO_STRING_SVTOOLS_HTML_S_sup; break;
+ case 8836: pStr = OOO_STRING_SVTOOLS_HTML_S_nsub; break;
+ case 8838: pStr = OOO_STRING_SVTOOLS_HTML_S_sube; break;
+ case 8839: pStr = OOO_STRING_SVTOOLS_HTML_S_supe; break;
+ case 8853: pStr = OOO_STRING_SVTOOLS_HTML_S_oplus; break;
+ case 8855: pStr = OOO_STRING_SVTOOLS_HTML_S_otimes; break;
+ case 8869: pStr = OOO_STRING_SVTOOLS_HTML_S_perp; break;
+ case 8901: pStr = OOO_STRING_SVTOOLS_HTML_S_sdot; break;
+ case 8968: pStr = OOO_STRING_SVTOOLS_HTML_S_lceil; break;
+ case 8969: pStr = OOO_STRING_SVTOOLS_HTML_S_rceil; break;
+ case 8970: pStr = OOO_STRING_SVTOOLS_HTML_S_lfloor; break;
+ case 8971: pStr = OOO_STRING_SVTOOLS_HTML_S_rfloor; break;
+ case 9001: pStr = OOO_STRING_SVTOOLS_HTML_S_lang; break;
+ case 9002: pStr = OOO_STRING_SVTOOLS_HTML_S_rang; break;
+ case 9674: pStr = OOO_STRING_SVTOOLS_HTML_S_loz; break;
+ case 9824: pStr = OOO_STRING_SVTOOLS_HTML_S_spades; break;
+ case 9827: pStr = OOO_STRING_SVTOOLS_HTML_S_clubs; break;
+ case 9829: pStr = OOO_STRING_SVTOOLS_HTML_S_hearts; break;
+ case 9830: pStr = OOO_STRING_SVTOOLS_HTML_S_diams; break;
+ }
+
+ // Greek chars: if we do not produce a Greek encoding,
+ // transform them into entities
+ if( !pStr &&
+ ( eDestEnc != RTL_TEXTENCODING_ISO_8859_7 ) &&
+ ( eDestEnc != RTL_TEXTENCODING_MS_1253 ) )
+ {
+ switch( c )
+ {
+ case 913: pStr = OOO_STRING_SVTOOLS_HTML_S_Alpha; break;
+ case 914: pStr = OOO_STRING_SVTOOLS_HTML_S_Beta; break;
+ case 915: pStr = OOO_STRING_SVTOOLS_HTML_S_Gamma; break;
+ case 916: pStr = OOO_STRING_SVTOOLS_HTML_S_Delta; break;
+ case 917: pStr = OOO_STRING_SVTOOLS_HTML_S_Epsilon; break;
+ case 918: pStr = OOO_STRING_SVTOOLS_HTML_S_Zeta; break;
+ case 919: pStr = OOO_STRING_SVTOOLS_HTML_S_Eta; break;
+ case 920: pStr = OOO_STRING_SVTOOLS_HTML_S_Theta; break;
+ case 921: pStr = OOO_STRING_SVTOOLS_HTML_S_Iota; break;
+ case 922: pStr = OOO_STRING_SVTOOLS_HTML_S_Kappa; break;
+ case 923: pStr = OOO_STRING_SVTOOLS_HTML_S_Lambda; break;
+ case 924: pStr = OOO_STRING_SVTOOLS_HTML_S_Mu; break;
+ case 925: pStr = OOO_STRING_SVTOOLS_HTML_S_Nu; break;
+ case 926: pStr = OOO_STRING_SVTOOLS_HTML_S_Xi; break;
+ case 927: pStr = OOO_STRING_SVTOOLS_HTML_S_Omicron; break;
+ case 928: pStr = OOO_STRING_SVTOOLS_HTML_S_Pi; break;
+ case 929: pStr = OOO_STRING_SVTOOLS_HTML_S_Rho; break;
+ case 931: pStr = OOO_STRING_SVTOOLS_HTML_S_Sigma; break;
+ case 932: pStr = OOO_STRING_SVTOOLS_HTML_S_Tau; break;
+ case 933: pStr = OOO_STRING_SVTOOLS_HTML_S_Upsilon; break;
+ case 934: pStr = OOO_STRING_SVTOOLS_HTML_S_Phi; break;
+ case 935: pStr = OOO_STRING_SVTOOLS_HTML_S_Chi; break;
+ case 936: pStr = OOO_STRING_SVTOOLS_HTML_S_Psi; break;
+ case 937: pStr = OOO_STRING_SVTOOLS_HTML_S_Omega; break;
+ case 945: pStr = OOO_STRING_SVTOOLS_HTML_S_alpha; break;
+ case 946: pStr = OOO_STRING_SVTOOLS_HTML_S_beta; break;
+ case 947: pStr = OOO_STRING_SVTOOLS_HTML_S_gamma; break;
+ case 948: pStr = OOO_STRING_SVTOOLS_HTML_S_delta; break;
+ case 949: pStr = OOO_STRING_SVTOOLS_HTML_S_epsilon; break;
+ case 950: pStr = OOO_STRING_SVTOOLS_HTML_S_zeta; break;
+ case 951: pStr = OOO_STRING_SVTOOLS_HTML_S_eta; break;
+ case 952: pStr = OOO_STRING_SVTOOLS_HTML_S_theta; break;
+ case 953: pStr = OOO_STRING_SVTOOLS_HTML_S_iota; break;
+ case 954: pStr = OOO_STRING_SVTOOLS_HTML_S_kappa; break;
+ case 955: pStr = OOO_STRING_SVTOOLS_HTML_S_lambda; break;
+ case 956: pStr = OOO_STRING_SVTOOLS_HTML_S_mu; break;
+ case 957: pStr = OOO_STRING_SVTOOLS_HTML_S_nu; break;
+ case 958: pStr = OOO_STRING_SVTOOLS_HTML_S_xi; break;
+ case 959: pStr = OOO_STRING_SVTOOLS_HTML_S_omicron; break;
+ case 960: pStr = OOO_STRING_SVTOOLS_HTML_S_pi; break;
+ case 961: pStr = OOO_STRING_SVTOOLS_HTML_S_rho; break;
+ case 962: pStr = OOO_STRING_SVTOOLS_HTML_S_sigmaf; break;
+ case 963: pStr = OOO_STRING_SVTOOLS_HTML_S_sigma; break;
+ case 964: pStr = OOO_STRING_SVTOOLS_HTML_S_tau; break;
+ case 965: pStr = OOO_STRING_SVTOOLS_HTML_S_upsilon; break;
+ case 966: pStr = OOO_STRING_SVTOOLS_HTML_S_phi; break;
+ case 967: pStr = OOO_STRING_SVTOOLS_HTML_S_chi; break;
+ case 968: pStr = OOO_STRING_SVTOOLS_HTML_S_psi; break;
+ case 969: pStr = OOO_STRING_SVTOOLS_HTML_S_omega; break;
+ case 977: pStr = OOO_STRING_SVTOOLS_HTML_S_thetasym;break;
+ case 978: pStr = OOO_STRING_SVTOOLS_HTML_S_upsih; break;
+ case 982: pStr = OOO_STRING_SVTOOLS_HTML_S_piv; break;
+ }
+ }
+
+ return pStr;
+}
+
+void lcl_ConvertCharToHTML( sal_Unicode c, ByteString& rDest,
+ HTMLOutContext& rContext,
+ String *pNonConvertableChars )
+{
+ DBG_ASSERT( RTL_TEXTENCODING_DONTKNOW != rContext.m_eDestEnc,
+ "wrong destination encoding" );
+ const sal_Char *pStr = 0;
+ switch( c )
+ {
+ case 0xA0: // is a hard blank
+//!! the TextConverter has a problem with this character - so change it to
+// a hard space - that's the same as our 5.2
+ case 0x2011: // is a hard hyphen
+ pStr = OOO_STRING_SVTOOLS_HTML_S_nbsp;
+ break;
+ case 0xAD: // is a soft hyphen
+ pStr = OOO_STRING_SVTOOLS_HTML_S_shy;
+ break;
+ default:
+ // There may be an entity for the character.
+ // The new HTML4 entities above 255 are not used for UTF-8,
+ // because Netscape 4 does support UTF-8 but does not support
+ // these entities.
+ if( c < 128 || RTL_TEXTENCODING_UTF8 != rContext.m_eDestEnc )
+ pStr = lcl_svhtml_GetEntityForChar( c, rContext.m_eDestEnc );
+ break;
+ }
+
+ sal_Char cBuffer[TXTCONV_BUFFER_SIZE];
+ sal_uInt32 nInfo = 0;
+ sal_Size nSrcChars;
+ const sal_uInt32 nFlags = RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE|
+ RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE|
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
+ if( pStr )
+ {
+ sal_Size nLen = rtl_convertUnicodeToText(
+ rContext.m_hConv, rContext.m_hContext, &c, 0,
+ cBuffer, TXTCONV_BUFFER_SIZE,
+ nFlags|RTL_UNICODETOTEXT_FLAGS_FLUSH,
+ &nInfo, &nSrcChars );
+ DBG_ASSERT( (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR|RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) == 0, "HTMLOut: error while flushing" );
+ sal_Char *pBuffer = cBuffer;
+ while( nLen-- )
+ rDest += *pBuffer++;
+ ((rDest += '&') += pStr) += ';';
+ }
+ else
+ {
+ sal_Size nLen = rtl_convertUnicodeToText( rContext.m_hConv,
+ rContext.m_hContext, &c, 1,
+ cBuffer, TXTCONV_BUFFER_SIZE,
+ nFlags,
+ &nInfo, &nSrcChars );
+ if( nLen > 0 && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR|RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) == 0 )
+ {
+ sal_Char *pBuffer = cBuffer;
+ while( nLen-- )
+ rDest += *pBuffer++;
+ }
+ else
+ {
+ // If the character could not be converted to the destination
+ // character set, the UNICODE character is exported as character
+ // entity.
+ nLen = rtl_convertUnicodeToText(
+ rContext.m_hConv, rContext.m_hContext, &c, 0,
+ cBuffer, TXTCONV_BUFFER_SIZE,
+ nFlags|RTL_UNICODETOTEXT_FLAGS_FLUSH,
+ &nInfo, &nSrcChars );
+ DBG_ASSERT( (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR|RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) == 0, "HTMLOut: error while flushing" );
+ sal_Char *pBuffer = cBuffer;
+ while( nLen-- )
+ rDest += *pBuffer++;
+
+ (((rDest += '&') += '#') +=
+ ByteString::CreateFromInt64( (sal_uInt32)c )) += ';';
+ if( pNonConvertableChars &&
+ STRING_NOTFOUND == pNonConvertableChars->Search( c ) )
+ pNonConvertableChars->Append( c );
+ }
+ }
+}
+
+sal_Bool lcl_FlushToAscii( ByteString& rDest, HTMLOutContext& rContext )
+{
+ sal_Unicode c = 0;
+ sal_Char cBuffer[TXTCONV_BUFFER_SIZE];
+ sal_uInt32 nInfo = 0;
+ sal_Size nSrcChars;
+ const sal_uInt32 nFlags = RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE|
+ RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE|
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|
+ RTL_UNICODETOTEXT_FLAGS_FLUSH|
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
+ sal_Size nLen = rtl_convertUnicodeToText(
+ rContext.m_hConv, rContext.m_hContext, &c, 0,
+ cBuffer, TXTCONV_BUFFER_SIZE, nFlags,
+ &nInfo, &nSrcChars );
+ DBG_ASSERT( (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR|RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) == 0, "HTMLOut: error while flushing" );
+ sal_Bool bRet = nLen > 0;
+ sal_Char *pBuffer = cBuffer;
+ while( nLen-- )
+ rDest += *pBuffer++;
+ return bRet;
+}
+
+void HTMLOutFuncs::ConvertStringToHTML( const String& rSrc,
+ ByteString& rDest,
+ rtl_TextEncoding eDestEnc,
+ String *pNonConvertableChars )
+{
+ HTMLOutContext aContext( eDestEnc );
+ for( sal_uInt32 i=0UL, nLen = rSrc.Len(); i < nLen; i++ )
+ lcl_ConvertCharToHTML( rSrc.GetChar( (xub_StrLen)i ), rDest, aContext,
+ pNonConvertableChars );
+ lcl_FlushToAscii( rDest, aContext );
+}
+
+SvStream& HTMLOutFuncs::Out_AsciiTag( SvStream& rStream, const sal_Char *pStr,
+ BOOL bOn, rtl_TextEncoding )
+{
+ sal_Char sStt[3] = "</";
+ if( bOn )
+ sStt[1] = 0;
+ return (rStream << sStt << pStr << '>');
+}
+
+SvStream& HTMLOutFuncs::Out_Char( SvStream& rStream, sal_Unicode c,
+ HTMLOutContext& rContext,
+ String *pNonConvertableChars )
+{
+ ByteString sOut;
+ lcl_ConvertCharToHTML( c, sOut, rContext, pNonConvertableChars );
+ rStream << sOut.GetBuffer();
+ return rStream;
+}
+
+SvStream& HTMLOutFuncs::Out_String( SvStream& rStream, const String& rStr,
+ rtl_TextEncoding eDestEnc,
+ String *pNonConvertableChars )
+{
+ HTMLOutContext aContext( eDestEnc );
+ xub_StrLen nLen = rStr.Len();
+ for( xub_StrLen n = 0; n < nLen; n++ )
+ HTMLOutFuncs::Out_Char( rStream, rStr.GetChar( (xub_StrLen)n ),
+ aContext, pNonConvertableChars );
+ HTMLOutFuncs::FlushToAscii( rStream, aContext );
+ return rStream;
+}
+
+SvStream& HTMLOutFuncs::FlushToAscii( SvStream& rStream,
+ HTMLOutContext& rContext )
+{
+ ByteString sOut;
+ if( lcl_FlushToAscii( sOut, rContext ) )
+ rStream << sOut.GetBuffer();
+
+ return rStream;
+}
+
+SvStream& HTMLOutFuncs::Out_Hex( SvStream& rStream, ULONG nHex, BYTE nLen,
+ rtl_TextEncoding )
+{ // in einen Stream aus
+ sal_Char aNToABuf[] = "0000000000000000";
+
+ DBG_ASSERT( nLen < sizeof(aNToABuf), "zu viele Stellen" );
+ if( nLen>=sizeof(aNToABuf) )
+ nLen = (sizeof(aNToABuf)-1);
+
+ // Pointer an das Bufferende setzen
+ sal_Char *pStr = aNToABuf + (sizeof(aNToABuf)-1);
+ for( BYTE n = 0; n < nLen; ++n )
+ {
+ *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
+ if( *pStr > '9' )
+ *pStr += 39;
+ nHex >>= 4;
+ }
+ return rStream << pStr;
+}
+
+
+SvStream& HTMLOutFuncs::Out_Color( SvStream& rStream, const Color& rColor,
+ rtl_TextEncoding )
+{
+ rStream << "\"#";
+ if( rColor.GetColor() == COL_AUTO )
+ {
+ rStream << "000000";
+ }
+ else
+ {
+ Out_Hex( rStream, rColor.GetRed(), 2 );
+ Out_Hex( rStream, rColor.GetGreen(), 2 );
+ Out_Hex( rStream, rColor.GetBlue(), 2 );
+ }
+ rStream << '\"';
+
+ return rStream;
+}
+
+SvStream& HTMLOutFuncs::Out_ImageMap( SvStream& rStream,
+ const String& rBaseURL,
+ const ImageMap& rIMap,
+ const String& rName,
+ const HTMLOutEvent *pEventTable,
+ BOOL bOutStarBasic,
+ const sal_Char *pDelim,
+ const sal_Char *pIndentArea,
+ const sal_Char *pIndentMap,
+ rtl_TextEncoding eDestEnc,
+ String *pNonConvertableChars )
+{
+ if( RTL_TEXTENCODING_DONTKNOW == eDestEnc )
+ eDestEnc = gsl_getSystemTextEncoding();
+
+ const String& rOutName = rName.Len() ? rName : rIMap.GetName();
+ DBG_ASSERT( rOutName.Len(), "Kein ImageMap-Name" );
+ if( !rOutName.Len() )
+ return rStream;
+
+ ByteString sOut( '<' );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_map ) );
+ sOut.Append( ' ' );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_name) );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM("=\"") );
+ rStream << sOut.GetBuffer();
+ sOut.Erase();
+ Out_String( rStream, rOutName, eDestEnc, pNonConvertableChars );
+ rStream << "\">";
+
+ for( USHORT i=0U; i<rIMap.GetIMapObjectCount(); i++ )
+ {
+ const IMapObject* pObj = rIMap.GetIMapObject( i );
+ DBG_ASSERT( pObj, "Wo ist das ImageMap-Object?" );
+
+ if( pObj )
+ {
+ const sal_Char *pShape = 0;
+ ByteString aCoords;
+ switch( pObj->GetType() )
+ {
+ case( IMAP_OBJ_RECTANGLE ):
+ {
+ const IMapRectangleObject* pRectObj =
+ (const IMapRectangleObject *)pObj;
+ pShape = OOO_STRING_SVTOOLS_HTML_SH_rect;
+ Rectangle aRect( pRectObj->GetRectangle() );
+ ((((((aCoords =
+ ByteString::CreateFromInt32(aRect.Left())) += ',')
+ += ByteString::CreateFromInt32(aRect.Top())) += ',')
+ += ByteString::CreateFromInt32(aRect.Right())) += ',')
+ += ByteString::CreateFromInt32(aRect.Bottom());
+ }
+ break;
+ case( IMAP_OBJ_CIRCLE ):
+ {
+ const IMapCircleObject* pCirc =
+ (const IMapCircleObject *)pObj;
+ pShape= OOO_STRING_SVTOOLS_HTML_SH_circ;
+ Point aCenter( pCirc->GetCenter() );
+ long nOff = pCirc->GetRadius();
+ ((((aCoords =
+ ByteString::CreateFromInt32(aCenter.X())) += ',')
+ += ByteString::CreateFromInt32(aCenter.Y())) += ',')
+ += ByteString::CreateFromInt32(nOff);
+ }
+ break;
+ case( IMAP_OBJ_POLYGON ):
+ {
+ const IMapPolygonObject* pPolyObj =
+ (const IMapPolygonObject *)pObj;
+ pShape= OOO_STRING_SVTOOLS_HTML_SH_poly;
+ Polygon aPoly( pPolyObj->GetPolygon() );
+ USHORT nCount = aPoly.GetSize();
+ if( nCount>0 )
+ {
+ const Point& rPoint = aPoly[0];
+ ((aCoords =
+ ByteString::CreateFromInt32(rPoint.X())) += ',')
+ += ByteString::CreateFromInt32(rPoint.Y());
+ }
+ for( USHORT j=1; j<nCount; j++ )
+ {
+ const Point& rPoint = aPoly[j];
+ (((aCoords += ',')
+ += ByteString::CreateFromInt32(rPoint.X())) += ',')
+ += ByteString::CreateFromInt32(rPoint.Y());
+ }
+ }
+ break;
+ default:
+ DBG_ASSERT( pShape, "unbekanntes IMapObject" );
+ break;
+ }
+
+ if( pShape )
+ {
+ if( pDelim )
+ rStream << pDelim;
+ if( pIndentArea )
+ rStream << pIndentArea;
+
+ ((((((((((sOut = '<') += OOO_STRING_SVTOOLS_HTML_area) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_shape) += '=') += pShape) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_coords) += "=\"") += aCoords) += "\" ";
+ rStream << sOut.GetBuffer();
+
+ String aURL( pObj->GetURL() );
+ if( aURL.Len() && pObj->IsActive() )
+ {
+ aURL = URIHelper::simpleNormalizedMakeRelative(
+ rBaseURL, aURL );
+ (sOut = OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
+ rStream << sOut.GetBuffer();
+ Out_String( rStream, aURL, eDestEnc, pNonConvertableChars ) << '\"';
+ }
+ else
+ rStream << OOO_STRING_SVTOOLS_HTML_O_nohref;
+
+ const String& rObjName = pObj->GetName();
+ if( rObjName.Len() )
+ {
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ rStream << sOut.GetBuffer();
+ Out_String( rStream, rObjName, eDestEnc, pNonConvertableChars ) << '\"';
+ }
+
+ const String& rTarget = pObj->GetTarget();
+ if( rTarget.Len() && pObj->IsActive() )
+ {
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
+ rStream << sOut.GetBuffer();
+ Out_String( rStream, rTarget, eDestEnc, pNonConvertableChars ) << '\"';
+ }
+
+ String rDesc( pObj->GetAltText() );
+ if( rDesc.Len() == 0 )
+ rDesc = pObj->GetDesc();
+
+ if( rDesc.Len() )
+ {
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_alt) += "=\"";
+ rStream << sOut.GetBuffer();
+ Out_String( rStream, rDesc, eDestEnc, pNonConvertableChars ) << '\"';
+ }
+
+ const SvxMacroTableDtor& rMacroTab = pObj->GetMacroTable();
+ if( pEventTable && rMacroTab.Count() )
+ Out_Events( rStream, rMacroTab, pEventTable,
+ bOutStarBasic, eDestEnc, pNonConvertableChars );
+
+ rStream << '>';
+ }
+ }
+
+ }
+
+ if( pDelim )
+ rStream << pDelim;
+ if( pIndentMap )
+ rStream << pIndentMap;
+ Out_AsciiTag( rStream, OOO_STRING_SVTOOLS_HTML_map, FALSE );
+
+ return rStream;
+}
+
+SvStream& HTMLOutFuncs::OutScript( SvStream& rStrm,
+ const String& rBaseURL,
+ const String& rSource,
+ const String& rLanguage,
+ ScriptType eScriptType,
+ const String& rSrc,
+ const String *pSBLibrary,
+ const String *pSBModule,
+ rtl_TextEncoding eDestEnc,
+ String *pNonConvertableChars )
+{
+ if( RTL_TEXTENCODING_DONTKNOW == eDestEnc )
+ eDestEnc = gsl_getSystemTextEncoding();
+
+ // Script wird komplett nicht eingerueckt!
+ ByteString sOut( '<' );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_script) );
+
+ if( rLanguage.Len() )
+ {
+ sOut.Append( ' ' );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_language) );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM("=\"") );
+ rStrm << sOut.GetBuffer();
+ Out_String( rStrm, rLanguage, eDestEnc, pNonConvertableChars );
+ sOut = '\"';
+ }
+
+ if( rSrc.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rStrm << sOut.GetBuffer();
+ Out_String( rStrm, URIHelper::simpleNormalizedMakeRelative(rBaseURL, rSrc), eDestEnc, pNonConvertableChars );
+ sOut = '\"';
+ }
+
+ if( STARBASIC != eScriptType && pSBLibrary )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_sdlibrary) += "=\"";
+ rStrm << sOut.GetBuffer();
+ Out_String( rStrm, *pSBLibrary, eDestEnc, pNonConvertableChars );
+ sOut = '\"';
+ }
+
+ if( STARBASIC != eScriptType && pSBModule )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_sdmodule) += "=\"";
+ rStrm << sOut.GetBuffer();
+ Out_String( rStrm, *pSBModule, eDestEnc, pNonConvertableChars );
+ sOut = '\"';
+ }
+
+ sOut += '>';
+
+ rStrm << sOut.GetBuffer();
+
+ if( rSource.Len() || pSBLibrary || pSBModule )
+ {
+ rStrm << sNewLine;
+
+ if( JAVASCRIPT != eScriptType )
+ {
+ rStrm << "<!--"
+ << sNewLine;
+ }
+
+ if( STARBASIC == eScriptType )
+ {
+ if( pSBLibrary )
+ {
+ sOut.Assign( RTL_CONSTASCII_STRINGPARAM("' ") );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_SB_library) );
+ sOut.Append( ' ' );
+ ByteString sTmp( *pSBLibrary, eDestEnc );
+ sOut.Append( sTmp );
+ rStrm << sOut.GetBuffer() << sNewLine;
+ }
+
+ if( pSBModule )
+ {
+ sOut.Assign( RTL_CONSTASCII_STRINGPARAM("' ") );
+ sOut.Append( RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_SB_module) );
+ sOut.Append( ' ' );
+ ByteString sTmp( *pSBModule, eDestEnc );
+ sOut.Append( sTmp );
+ rStrm << sOut.GetBuffer() << sNewLine;
+ }
+ }
+
+ if( rSource.Len() )
+ {
+ // Wir schreiben das Modul mm ANSI-Zeichensatz, aber mit
+ // System-Zeilenumbruechen raus.
+ ByteString sSource( rSource, eDestEnc );
+ sSource.ConvertLineEnd( GetSystemLineEnd() );
+ rStrm << sSource.GetBuffer();
+ }
+ rStrm << sNewLine;
+
+ if( JAVASCRIPT != eScriptType )
+ {
+ // MIB/MM: Wenn es kein StarBasic ist, kann ein // natuerlich
+ // falsch sein. Da der Kommentar aber beim Einlesen wider
+ // entfernt wird, schickt uns das nicht weiter ...
+ rStrm << (STARBASIC == eScriptType ? "' -->" : "// -->")
+ << sNewLine;
+ }
+ }
+
+ HTMLOutFuncs::Out_AsciiTag( rStrm, OOO_STRING_SVTOOLS_HTML_script, FALSE );
+
+ return rStrm;
+}
+
+
+SvStream& HTMLOutFuncs::Out_Events( SvStream& rStrm,
+ const SvxMacroTableDtor& rMacroTable,
+ const HTMLOutEvent *pEventTable,
+ BOOL bOutStarBasic,
+ rtl_TextEncoding eDestEnc,
+ String *pNonConvertableChars )
+{
+ USHORT i=0;
+ while( pEventTable[i].pBasicName || pEventTable[i].pJavaName )
+ {
+ const SvxMacro *pMacro =
+ rMacroTable.Get( pEventTable[i].nEvent );
+
+ if( pMacro && pMacro->GetMacName().Len() &&
+ ( JAVASCRIPT == pMacro->GetScriptType() || bOutStarBasic ))
+ {
+ const sal_Char *pStr = STARBASIC == pMacro->GetScriptType()
+ ? pEventTable[i].pBasicName
+ : pEventTable[i].pJavaName;
+
+ if( pStr )
+ {
+ ByteString sOut( ' ' );
+ (sOut += pStr) += "=\"";
+ rStrm << sOut.GetBuffer();
+
+ Out_String( rStrm, pMacro->GetMacName(), eDestEnc, pNonConvertableChars ) << '\"';
+ }
+ }
+ i++;
+ }
+
+ return rStrm;
+}
+
+ByteString& HTMLOutFuncs::CreateTableDataOptionsValNum( ByteString& aStrTD,
+ BOOL bValue,
+ double fVal, ULONG nFormat, SvNumberFormatter& rFormatter,
+ rtl_TextEncoding eDestEnc, String* pNonConvertableChars )
+{
+ if ( bValue )
+ {
+ // printf / scanf ist zu ungenau
+ String aValStr;
+ rFormatter.GetInputLineString( fVal, 0, aValStr );
+ ByteString sTmp( aValStr, eDestEnc );
+ ((((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_SDval) += "=\"") += sTmp) += '\"';
+ }
+ if ( bValue || nFormat )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_SDnum) += "=\"";
+ (aStrTD += ByteString::CreateFromInt32(
+ Application::GetSettings().GetLanguage() ))
+ += ';'; // Language fuer Format 0
+ if ( nFormat )
+ {
+ ByteString aNumStr;
+ LanguageType nLang;
+ const SvNumberformat* pFormatEntry = rFormatter.GetEntry( nFormat );
+ if ( pFormatEntry )
+ {
+ ConvertStringToHTML( pFormatEntry->GetFormatstring(), aNumStr,
+ eDestEnc, pNonConvertableChars );
+ nLang = pFormatEntry->GetLanguage();
+ }
+ else
+ nLang = LANGUAGE_SYSTEM;
+ ((aStrTD += ByteString::CreateFromInt32(nLang)) += ';') += aNumStr;
+ }
+ aStrTD += '\"';
+ }
+ return aStrTD;
+}
+
+BOOL HTMLOutFuncs::PrivateURLToInternalImg( String& rURL )
+{
+ if( rURL.Len() > 14UL &&
+ rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_private_image, 14UL ) == COMPARE_EQUAL )
+ {
+ rURL.Erase( 0UL, 14UL );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
diff --git a/svtools/source/svhtml/htmlsupp.cxx b/svtools/source/svhtml/htmlsupp.cxx
new file mode 100644
index 000000000000..4c08d9c41ec9
--- /dev/null
+++ b/svtools/source/svhtml/htmlsupp.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_svtools.hxx"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <tools/urlobj.hxx>
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#endif
+
+#include <svtools/parhtml.hxx>
+#include "htmltokn.h"
+#include "htmlkywd.hxx"
+
+/* */
+
+// Tabellen zum Umwandeln von Options-Werten in Strings
+
+static HTMLOptionEnum __READONLY_DATA aScriptLangOptEnums[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_LG_starbasic, HTML_SL_STARBASIC },
+ { OOO_STRING_SVTOOLS_HTML_LG_javascript, HTML_SL_JAVASCRIPT },
+ { OOO_STRING_SVTOOLS_HTML_LG_javascript11,HTML_SL_JAVASCRIPT },
+ { OOO_STRING_SVTOOLS_HTML_LG_livescript, HTML_SL_JAVASCRIPT },
+// { OOO_STRING_SVTOOLS_HTML_LG_unused_javascript, HTML_SL_UNUSEDJS },
+// { OOO_STRING_SVTOOLS_HTML_LG_vbscript, HTML_SL_VBSCRIPT },
+// { OOO_STRING_SVTOOLS_HTML_LG_starone, HTML_SL_STARONE },
+ { 0, 0 }
+};
+
+BOOL HTMLParser::ParseScriptOptions( String& rLangString, const String& rBaseURL,
+ HTMLScriptLanguage& rLang,
+ String& rSrc,
+ String& rLibrary,
+ String& rModule )
+{
+ const HTMLOptions *pScriptOptions = GetOptions();
+
+ rLangString.Erase();
+ rLang = HTML_SL_JAVASCRIPT;
+ rSrc.Erase();
+ rLibrary.Erase();
+ rModule.Erase();
+
+ for( USHORT i = pScriptOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pScriptOptions)[ --i ];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_LANGUAGE:
+ {
+ rLangString = pOption->GetString();
+ USHORT nLang;
+ if( pOption->GetEnum( nLang, aScriptLangOptEnums ) )
+ rLang = (HTMLScriptLanguage)nLang;
+ else
+ rLang = HTML_SL_UNKNOWN;
+ }
+ break;
+
+ case HTML_O_SRC:
+ rSrc = INetURLObject::GetAbsURL( rBaseURL, pOption->GetString() );
+ break;
+ case HTML_O_SDLIBRARY:
+ rLibrary = pOption->GetString();
+ break;
+
+ case HTML_O_SDMODULE:
+ rModule = pOption->GetString();
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+void HTMLParser::RemoveSGMLComment( String &rString, BOOL bFull )
+{
+ sal_Unicode c = 0;
+ while( rString.Len() &&
+ ( ' '==(c=rString.GetChar(0)) || '\t'==c || '\r'==c || '\n'==c ) )
+ rString.Erase( 0, 1 );
+
+ while( rString.Len() &&
+ ( ' '==(c=rString.GetChar( rString.Len()-1))
+ || '\t'==c || '\r'==c || '\n'==c ) )
+ rString.Erase( rString.Len()-1 );
+
+
+ // SGML-Kommentare entfernen
+ if( rString.Len() >= 4 &&
+ rString.CompareToAscii( "<!--", 4 ) == COMPARE_EQUAL )
+ {
+ xub_StrLen nPos = 3;
+ if( bFull )
+ {
+ // die gesamte Zeile !
+ nPos = 4;
+ while( nPos < rString.Len() &&
+ ( ( c = rString.GetChar( nPos )) != '\r' && c != '\n' ) )
+ ++nPos;
+ if( c == '\r' && nPos+1 < rString.Len() &&
+ '\n' == rString.GetChar( nPos+1 ))
+ ++nPos;
+ else if( c != '\n' )
+ nPos = 3;
+ }
+ rString.Erase( 0, ++nPos );
+ }
+
+ if( rString.Len() >=3 &&
+ rString.Copy(rString.Len()-3).CompareToAscii("-->")
+ == COMPARE_EQUAL )
+ {
+ rString.Erase( rString.Len()-3 );
+ if( bFull )
+ {
+ // auch noch ein "//" oder "'" und ggf CR/LF davor
+ rString.EraseTrailingChars();
+ xub_StrLen nDel = 0, nLen = rString.Len();
+ if( nLen >= 2 &&
+ rString.Copy(nLen-2).CompareToAscii("//") == COMPARE_EQUAL )
+ {
+ nDel = 2;
+ }
+ else if( nLen && '\'' == rString.GetChar(nLen-1) )
+ {
+ nDel = 1;
+ }
+ if( nDel && nLen >= nDel+1 )
+ {
+ c = rString.GetChar( nLen-(nDel+1) );
+ if( '\r'==c || '\n'==c )
+ {
+ nDel++;
+ if( '\n'==c && nLen >= nDel+1 &&
+ '\r'==rString.GetChar( nLen-(nDel+1) ) )
+ nDel++;
+ }
+ }
+ rString.Erase( nLen-nDel );
+ }
+ }
+}
+
diff --git a/svtools/source/svhtml/makefile.mk b/svtools/source/svhtml/makefile.mk
new file mode 100644
index 000000000000..7a8552f2b672
--- /dev/null
+++ b/svtools/source/svhtml/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=svtools
+TARGET=svhtml
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/htmlkywd.obj \
+ $(SLO)$/htmlsupp.obj \
+ $(SLO)$/htmlout.obj \
+ $(SLO)$/parhtml.obj
+
+# ==========================================================================
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/svhtml/parhtml.cxx b/svtools/source/svhtml/parhtml.cxx
new file mode 100644
index 000000000000..ade58688dc55
--- /dev/null
+++ b/svtools/source/svhtml/parhtml.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_svtools.hxx"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <tools/color.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#endif
+
+#include <tools/tenccvt.hxx>
+#include <tools/datetime.hxx>
+#include <svl/inettype.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+#include <svtools/parhtml.hxx>
+#include "htmltokn.h"
+#include "htmlkywd.hxx"
+
+
+using namespace ::com::sun::star;
+
+
+const sal_Int32 MAX_LEN( 1024L );
+//static sal_Unicode sTmpBuffer[ MAX_LEN+1 ];
+const sal_Int32 MAX_MACRO_LEN( 1024 );
+
+const sal_Int32 MAX_ENTITY_LEN( 8L );
+
+/* */
+
+// Tabellen zum Umwandeln von Options-Werten in Strings
+
+// <INPUT TYPE=xxx>
+static HTMLOptionEnum __READONLY_DATA aInputTypeOptEnums[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_IT_text, HTML_IT_TEXT },
+ { OOO_STRING_SVTOOLS_HTML_IT_password, HTML_IT_PASSWORD },
+ { OOO_STRING_SVTOOLS_HTML_IT_checkbox, HTML_IT_CHECKBOX },
+ { OOO_STRING_SVTOOLS_HTML_IT_radio, HTML_IT_RADIO },
+ { OOO_STRING_SVTOOLS_HTML_IT_range, HTML_IT_RANGE },
+ { OOO_STRING_SVTOOLS_HTML_IT_scribble, HTML_IT_SCRIBBLE },
+ { OOO_STRING_SVTOOLS_HTML_IT_file, HTML_IT_FILE },
+ { OOO_STRING_SVTOOLS_HTML_IT_hidden, HTML_IT_HIDDEN },
+ { OOO_STRING_SVTOOLS_HTML_IT_submit, HTML_IT_SUBMIT },
+ { OOO_STRING_SVTOOLS_HTML_IT_image, HTML_IT_IMAGE },
+ { OOO_STRING_SVTOOLS_HTML_IT_reset, HTML_IT_RESET },
+ { OOO_STRING_SVTOOLS_HTML_IT_button, HTML_IT_BUTTON },
+ { 0, 0 }
+};
+
+// <TABLE FRAME=xxx>
+static HTMLOptionEnum __READONLY_DATA aTableFrameOptEnums[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_TF_void, HTML_TF_VOID },
+ { OOO_STRING_SVTOOLS_HTML_TF_above, HTML_TF_ABOVE },
+ { OOO_STRING_SVTOOLS_HTML_TF_below, HTML_TF_BELOW },
+ { OOO_STRING_SVTOOLS_HTML_TF_hsides, HTML_TF_HSIDES },
+ { OOO_STRING_SVTOOLS_HTML_TF_lhs, HTML_TF_LHS },
+ { OOO_STRING_SVTOOLS_HTML_TF_rhs, HTML_TF_RHS },
+ { OOO_STRING_SVTOOLS_HTML_TF_vsides, HTML_TF_VSIDES },
+ { OOO_STRING_SVTOOLS_HTML_TF_box, HTML_TF_BOX },
+ { OOO_STRING_SVTOOLS_HTML_TF_border, HTML_TF_BOX },
+ { 0, 0 }
+};
+
+// <TABLE RULES=xxx>
+static HTMLOptionEnum __READONLY_DATA aTableRulesOptEnums[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_TR_none, HTML_TR_NONE },
+ { OOO_STRING_SVTOOLS_HTML_TR_groups, HTML_TR_GROUPS },
+ { OOO_STRING_SVTOOLS_HTML_TR_rows, HTML_TR_ROWS },
+ { OOO_STRING_SVTOOLS_HTML_TR_cols, HTML_TR_COLS },
+ { OOO_STRING_SVTOOLS_HTML_TR_all, HTML_TR_ALL },
+ { 0, 0 }
+};
+
+
+SV_IMPL_PTRARR(HTMLOptions,HTMLOptionPtr)
+
+/* */
+
+USHORT HTMLOption::GetEnum( const HTMLOptionEnum *pOptEnums, USHORT nDflt ) const
+{
+ USHORT nValue = nDflt;
+
+ while( pOptEnums->pName )
+ if( aValue.EqualsIgnoreCaseAscii( pOptEnums->pName ) )
+ break;
+ else
+ pOptEnums++;
+
+ if( pOptEnums->pName )
+ nValue = pOptEnums->nValue;
+
+ return nValue;
+}
+
+BOOL HTMLOption::GetEnum( USHORT &rEnum, const HTMLOptionEnum *pOptEnums ) const
+{
+ while( pOptEnums->pName )
+ {
+ if( aValue.EqualsIgnoreCaseAscii( pOptEnums->pName ) )
+ break;
+ else
+ pOptEnums++;
+ }
+
+ const sal_Char *pName = pOptEnums->pName;
+ if( pName )
+ rEnum = pOptEnums->nValue;
+
+ return (pName != 0);
+}
+
+HTMLOption::HTMLOption( USHORT nTok, const String& rToken,
+ const String& rValue )
+ : aValue(rValue)
+ , aToken(rToken)
+ , nToken( nTok )
+{
+ DBG_ASSERT( nToken>=HTML_OPTION_START && nToken<HTML_OPTION_END,
+ "HTMLOption: unbekanntes Token" );
+}
+
+sal_uInt32 HTMLOption::GetNumber() const
+{
+ DBG_ASSERT( (nToken>=HTML_OPTION_NUMBER_START &&
+ nToken<HTML_OPTION_NUMBER_END) ||
+ (nToken>=HTML_OPTION_CONTEXT_START &&
+ nToken<HTML_OPTION_CONTEXT_END) ||
+ nToken==HTML_O_VALUE,
+ "GetNumber: Option ist nicht numerisch" );
+ String aTmp( aValue );
+ aTmp.EraseLeadingChars();
+ sal_Int32 nTmp = aTmp.ToInt32();
+ return nTmp >= 0 ? (sal_uInt32)nTmp : 0;
+}
+
+INT32 HTMLOption::GetSNumber() const
+{
+ DBG_ASSERT( (nToken>=HTML_OPTION_NUMBER_START && nToken<HTML_OPTION_NUMBER_END) ||
+ (nToken>=HTML_OPTION_CONTEXT_START && nToken<HTML_OPTION_CONTEXT_END),
+ "GetSNumber: Option ist nicht numerisch" );
+ String aTmp( aValue );
+ aTmp.EraseLeadingChars();
+ return aTmp.ToInt32();
+}
+
+void HTMLOption::GetNumbers( SvULongs &rLongs, BOOL bSpaceDelim ) const
+{
+ if( rLongs.Count() )
+ rLongs.Remove( 0, rLongs.Count() );
+
+ if( bSpaceDelim )
+ {
+ // das ist ein sehr stark vereinfachter Scanner. Er sucht einfach
+ // alle Tiffern aus dem String
+ BOOL bInNum = FALSE;
+ ULONG nNum = 0;
+ for( xub_StrLen i=0; i<aValue.Len(); i++ )
+ {
+ register sal_Unicode c = aValue.GetChar( i );
+ if( c>='0' && c<='9' )
+ {
+ nNum *= 10;
+ nNum += (c - '0');
+ bInNum = TRUE;
+ }
+ else if( bInNum )
+ {
+ rLongs.Insert( nNum, rLongs.Count() );
+ bInNum = FALSE;
+ nNum = 0;
+ }
+ }
+ if( bInNum )
+ {
+ rLongs.Insert( nNum, rLongs.Count() );
+ }
+ }
+ else
+ {
+ // hier wird auf die korrekte Trennung der Zahlen durch ',' geachtet
+ // und auch mal eine 0 eingefuegt
+ xub_StrLen nPos = 0;
+ while( nPos < aValue.Len() )
+ {
+ register sal_Unicode c;
+ while( nPos < aValue.Len() &&
+ ((c=aValue.GetChar(nPos)) == ' ' || c == '\t' ||
+ c == '\n' || c== '\r' ) )
+ nPos++;
+
+ if( nPos==aValue.Len() )
+ rLongs.Insert( ULONG(0), rLongs.Count() );
+ else
+ {
+ xub_StrLen nEnd = aValue.Search( (sal_Unicode)',', nPos );
+ if( STRING_NOTFOUND==nEnd )
+ {
+ sal_Int32 nTmp = aValue.Copy(nPos).ToInt32();
+ rLongs.Insert( nTmp >= 0 ? (sal_uInt32)nTmp : 0,
+ rLongs.Count() );
+ nPos = aValue.Len();
+ }
+ else
+ {
+ sal_Int32 nTmp =
+ aValue.Copy(nPos,nEnd-nPos).ToInt32();
+ rLongs.Insert( nTmp >= 0 ? (sal_uInt32)nTmp : 0,
+ rLongs.Count() );
+ nPos = nEnd+1;
+ }
+ }
+ }
+ }
+}
+
+void HTMLOption::GetColor( Color& rColor ) const
+{
+ DBG_ASSERT( (nToken>=HTML_OPTION_COLOR_START && nToken<HTML_OPTION_COLOR_END) || nToken==HTML_O_SIZE,
+ "GetColor: Option spezifiziert keine Farbe" );
+
+ String aTmp( aValue );
+ aTmp.ToUpperAscii();
+ ULONG nColor = ULONG_MAX;
+ if( '#'!=aTmp.GetChar( 0 ) )
+ nColor = GetHTMLColor( aTmp );
+
+ if( ULONG_MAX == nColor )
+ {
+ nColor = 0;
+ xub_StrLen nPos = 0;
+ for( sal_uInt32 i=0; i<6; i++ )
+ {
+ // MIB 26.06.97: Wie auch immer Netscape Farbwerte ermittelt,
+ // maximal drei Zeichen, die kleiner als '0' sind werden
+ // ignoriert. Bug #40901# stimmt damit. Mal schauen, was sich
+ // irgendwelche HTML-Autoren noch so einfallen lassen...
+ register sal_Unicode c = nPos<aTmp.Len() ? aTmp.GetChar( nPos++ )
+ : '0';
+ if( c < '0' )
+ {
+ c = nPos<aTmp.Len() ? aTmp.GetChar(nPos++) : '0';
+ if( c < '0' )
+ c = nPos<aTmp.Len() ? aTmp.GetChar(nPos++) : '0';
+ }
+ nColor *= 16;
+ if( c >= '0' && c <= '9' )
+ nColor += (c - 48);
+ else if( c >= 'A' && c <= 'F' )
+ nColor += (c - 55);
+ }
+ }
+
+ rColor.SetRed( (BYTE)((nColor & 0x00ff0000) >> 16) );
+ rColor.SetGreen( (BYTE)((nColor & 0x0000ff00) >> 8));
+ rColor.SetBlue( (BYTE)(nColor & 0x000000ff) );
+}
+
+HTMLInputType HTMLOption::GetInputType() const
+{
+ DBG_ASSERT( nToken==HTML_O_TYPE, "GetInputType: Option nicht TYPE" );
+ return (HTMLInputType)GetEnum( aInputTypeOptEnums, HTML_IT_TEXT );
+}
+
+HTMLTableFrame HTMLOption::GetTableFrame() const
+{
+ DBG_ASSERT( nToken==HTML_O_FRAME, "GetTableFrame: Option nicht FRAME" );
+ return (HTMLTableFrame)GetEnum( aTableFrameOptEnums, HTML_TF_VOID );
+}
+
+HTMLTableRules HTMLOption::GetTableRules() const
+{
+ DBG_ASSERT( nToken==HTML_O_RULES, "GetTableRules: Option nicht RULES" );
+ return (HTMLTableRules)GetEnum( aTableRulesOptEnums, HTML_TR_NONE );
+}
+
+/* */
+
+HTMLParser::HTMLParser( SvStream& rIn, int bReadNewDoc )
+ : SvParser( rIn )
+{
+ bNewDoc = bReadNewDoc;
+ bReadListing = bReadXMP = bReadPRE = bReadTextArea =
+ bReadScript = bReadStyle =
+ bEndTokenFound = bIsInBody = bReadNextChar =
+ bReadComment = FALSE;
+ bIsInHeader = TRUE;
+ pOptions = new HTMLOptions;
+}
+
+HTMLParser::~HTMLParser()
+{
+ if( pOptions && pOptions->Count() )
+ pOptions->DeleteAndDestroy( 0, pOptions->Count() );
+ delete pOptions;
+}
+
+SvParserState __EXPORT HTMLParser::CallParser()
+{
+ eState = SVPAR_WORKING;
+ nNextCh = GetNextChar();
+ SaveState( 0 );
+
+ nPre_LinePos = 0;
+ bPre_IgnoreNewPara = FALSE;
+
+ AddRef();
+ Continue( 0 );
+ if( SVPAR_PENDING != eState )
+ ReleaseRef(); // dann brauchen wir den Parser nicht mehr!
+
+ return eState;
+}
+
+void HTMLParser::Continue( int nToken )
+{
+ if( !nToken )
+ nToken = GetNextToken();
+
+ while( IsParserWorking() )
+ {
+ SaveState( nToken );
+ nToken = FilterToken( nToken );
+
+ if( nToken )
+ NextToken( nToken );
+
+ if( IsParserWorking() )
+ SaveState( 0 ); // bis hierhin abgearbeitet,
+ // weiter mit neuem Token!
+ nToken = GetNextToken();
+ }
+}
+
+int HTMLParser::FilterToken( int nToken )
+{
+ switch( nToken )
+ {
+ case sal_Unicode(EOF):
+ nToken = 0;
+ break; // nicht verschicken
+
+ case HTML_HEAD_OFF:
+ bIsInBody = TRUE;
+ case HTML_HEAD_ON:
+ bIsInHeader = HTML_HEAD_ON == nToken;
+ break;
+
+ case HTML_BODY_ON:
+ case HTML_FRAMESET_ON:
+ bIsInHeader = FALSE;
+ bIsInBody = HTML_BODY_ON == nToken;
+ break;
+
+ case HTML_BODY_OFF:
+ bIsInBody = bReadPRE = bReadListing = bReadXMP = FALSE;
+ break;
+
+ case HTML_HTML_OFF:
+ nToken = 0;
+ bReadPRE = bReadListing = bReadXMP = FALSE;
+ break; // HTML_ON wurde auch nicht verschickt !
+
+ case HTML_PREFORMTXT_ON:
+ StartPRE();
+ break;
+
+ case HTML_PREFORMTXT_OFF:
+ FinishPRE();
+ break;
+
+ case HTML_LISTING_ON:
+ StartListing();
+ break;
+
+ case HTML_LISTING_OFF:
+ FinishListing();
+ break;
+
+ case HTML_XMP_ON:
+ StartXMP();
+ break;
+
+ case HTML_XMP_OFF:
+ FinishXMP();
+ break;
+
+ default:
+ if( bReadPRE )
+ nToken = FilterPRE( nToken );
+ else if( bReadListing )
+ nToken = FilterListing( nToken );
+ else if( bReadXMP )
+ nToken = FilterXMP( nToken );
+
+ break;
+ }
+
+ return nToken;
+}
+
+#define HTML_ISDIGIT( c ) (c >= '0' && c <= '9')
+#define HTML_ISALPHA( c ) ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') )
+#define HTML_ISALNUM( c ) ( HTML_ISALPHA(c) || HTML_ISDIGIT(c) )
+#define HTML_ISSPACE( c ) ( ' ' == c || (c >= 0x09 && c <= 0x0d) )
+#define HTML_ISPRINTABLE( c ) ( c >= 32 && c != 127)
+// --> OD 2006-07-26 #138464#
+#define HTML_ISHEXDIGIT( c ) ( HTML_ISDIGIT(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') )
+// <--
+
+int HTMLParser::ScanText( const sal_Unicode cBreak )
+{
+ ::rtl::OUStringBuffer sTmpBuffer( MAX_LEN );
+ int bWeiter = TRUE;
+ int bEqSignFound = FALSE;
+ sal_Unicode cQuote = 0U;
+
+ while( bWeiter && IsParserWorking() )
+ {
+ int bNextCh = TRUE;
+ switch( nNextCh )
+ {
+ case '&':
+ bEqSignFound = FALSE;
+ if( bReadXMP )
+ sTmpBuffer.append( (sal_Unicode)'&' );
+ else
+ {
+ ULONG nStreamPos = rInput.Tell();
+ ULONG nLinePos = GetLinePos();
+
+ sal_Unicode cChar = 0U;
+ if( '#' == (nNextCh = GetNextChar()) )
+ {
+ nNextCh = GetNextChar();
+ // --> OD 2006-07-26 #138464#
+ // consider hexadecimal digits
+ const sal_Bool bIsHex( 'x' == nNextCh );
+ const sal_Bool bIsDecOrHex( bIsHex || HTML_ISDIGIT(nNextCh) );
+ if ( bIsDecOrHex )
+ {
+ if ( bIsHex )
+ {
+ nNextCh = GetNextChar();
+ while ( HTML_ISHEXDIGIT(nNextCh) )
+ {
+ cChar = cChar * 16U +
+ ( nNextCh <= '9'
+ ? sal_Unicode( nNextCh - '0' )
+ : ( nNextCh <= 'F'
+ ? sal_Unicode( nNextCh - 'A' + 10 )
+ : sal_Unicode( nNextCh - 'a' + 10 ) ) );
+ nNextCh = GetNextChar();
+ }
+ }
+ else
+ {
+ do
+ {
+ cChar = cChar * 10U + sal_Unicode( nNextCh - '0');
+ nNextCh = GetNextChar();
+ }
+ while( HTML_ISDIGIT(nNextCh) );
+ }
+
+ if( RTL_TEXTENCODING_DONTKNOW != eSrcEnc &&
+ RTL_TEXTENCODING_UCS2 != eSrcEnc &&
+ RTL_TEXTENCODING_UTF8 != eSrcEnc &&
+ cChar < 256 )
+ {
+ sal_Unicode cOrig = cChar;
+ cChar = ByteString::ConvertToUnicode(
+ (sal_Char)cChar, eSrcEnc );
+ if( 0U == cChar )
+ {
+ // #73398#: If the character could not be
+ // converted, because a conversion is not
+ // available, do no conversion at all.
+ cChar = cOrig;
+ }
+ }
+ }
+ // <--
+ else
+ nNextCh = 0U;
+ }
+ else if( HTML_ISALPHA( nNextCh ) )
+ {
+ ::rtl::OUStringBuffer sEntityBuffer( MAX_ENTITY_LEN );
+ xub_StrLen nPos = 0L;
+ do
+ {
+ sEntityBuffer.append( nNextCh );
+ nPos++;
+ nNextCh = GetNextChar();
+ }
+ while( nPos < MAX_ENTITY_LEN && HTML_ISALNUM( nNextCh ) &&
+ !rInput.IsEof() );
+
+ if( IsParserWorking() && !rInput.IsEof() )
+ {
+ String sEntity( sEntityBuffer.getStr(), nPos );
+ cChar = GetHTMLCharName( sEntity );
+
+ // nicht gefunden ( == 0 ), dann Klartext
+ // oder ein Zeichen das als Attribut eingefuegt
+ // wird
+ if( 0U == cChar && ';' != nNextCh )
+ {
+ DBG_ASSERT( rInput.Tell() - nStreamPos ==
+ (ULONG)(nPos+1L)*GetCharSize(),
+ "UTF-8 geht hier schief" );
+ for( xub_StrLen i=nPos-1L; i>1L; i-- )
+ {
+ nNextCh = sEntityBuffer[i];
+ sEntityBuffer.setLength( i );
+ sEntity.Assign( sEntityBuffer.getStr(), i );
+ cChar = GetHTMLCharName( sEntity );
+ if( cChar )
+ {
+ rInput.SeekRel( -(long)
+ ((nPos-i)*GetCharSize()) );
+ nlLinePos -= sal_uInt32(nPos-i);
+ nPos = i;
+ ClearTxtConvContext();
+ break;
+ }
+ }
+ }
+
+ if( !cChar ) // unbekanntes Zeichen?
+ {
+ // dann im Stream zurueck, das '&' als Zeichen
+ // einfuegen und mit dem nachfolgenden Zeichen
+ // wieder aufsetzen
+ sTmpBuffer.append( (sal_Unicode)'&' );
+
+// rInput.SeekRel( -(long)(++nPos*GetCharSize()) );
+// nlLinePos -= nPos;
+ DBG_ASSERT( rInput.Tell()-nStreamPos ==
+ (ULONG)(nPos+1)*GetCharSize(),
+ "Falsche Stream-Position" );
+ DBG_ASSERT( nlLinePos-nLinePos ==
+ (ULONG)(nPos+1),
+ "Falsche Zeilen-Position" );
+ rInput.Seek( nStreamPos );
+ nlLinePos = nLinePos;
+ ClearTxtConvContext();
+ break;
+ }
+
+ // 1 == Non Breaking Space
+ // 2 == SoftHyphen
+
+ if( cChar < 3U )
+ {
+ if( '>' == cBreak )
+ {
+ // Wenn der Inhalt eines Tags gelesen wird,
+ // muessen wir ein Space bzw. - daraus machen
+ switch( cChar )
+ {
+ case 1U: cChar = ' '; break;
+ case 2U: cChar = '-'; break;
+ default:
+ DBG_ASSERT( cChar==1U,
+ "\0x00 sollte doch schon laengt abgefangen sein!" );
+ break;
+ }
+ }
+ else
+ {
+ // Wenn kein Tag gescannt wird, enstprechendes
+ // Token zurueckgeben
+ aToken +=
+ String( sTmpBuffer.makeStringAndClear() );
+ if( cChar )
+ {
+ if( aToken.Len() )
+ {
+ // mit dem Zeichen wieder aufsetzen
+ nNextCh = '&';
+// rInput.SeekRel( -(long)(++nPos*GetCharSize()) );
+// nlLinePos -= nPos;
+ DBG_ASSERT( rInput.Tell()-nStreamPos ==
+ (ULONG)(nPos+1)*GetCharSize(),
+ "Falsche Stream-Position" );
+ DBG_ASSERT( nlLinePos-nLinePos ==
+ (ULONG)(nPos+1),
+ "Falsche Zeilen-Position" );
+ rInput.Seek( nStreamPos );
+ nlLinePos = nLinePos;
+ ClearTxtConvContext();
+ return HTML_TEXTTOKEN;
+ }
+
+ // Hack: _GetNextChar soll nicht das
+ // naechste Zeichen lesen
+ if( ';' != nNextCh )
+ aToken += ' ';
+ if( 1U == cChar )
+ return HTML_NONBREAKSPACE;
+ if( 2U == cChar )
+ return HTML_SOFTHYPH;
+ }
+ aToken += (sal_Unicode)'&';
+ aToken +=
+ String(sEntityBuffer.makeStringAndClear());
+ break;
+ }
+ }
+ }
+ else
+ nNextCh = 0U;
+ }
+ // MIB 03/02/2000: &{...};-JavaScript-Macros are not
+ // supported any longer.
+ else if( IsParserWorking() )
+ {
+ sTmpBuffer.append( (sal_Unicode)'&' );
+ bNextCh = FALSE;
+ break;
+ }
+
+ bNextCh = (';' == nNextCh);
+ if( cBreak=='>' && (cChar=='\\' || cChar=='\'' ||
+ cChar=='\"' || cChar==' ') )
+ {
+ // ' und " mussen innerhalb von Tags mit einem
+ // gekennzeichnet werden, um sie von ' und " als Klammern
+ // um Optionen zu unterscheiden. Logischerweise muss
+ // deshalb auch ein \ gekeenzeichnet werden. Ausserdem
+ // schuetzen wir ein Space, weil es kein Trennzeichen
+ // zwischen Optionen ist.
+ sTmpBuffer.append( (sal_Unicode)'\\' );
+ if( MAX_LEN == sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ }
+ if( IsParserWorking() )
+ {
+ if( cChar )
+ sTmpBuffer.append( cChar );
+ }
+ else if( SVPAR_PENDING==eState && '>'!=cBreak )
+ {
+ // Mit dem '&' Zeichen wieder aufsetzen, der Rest
+ // wird als Texttoken zurueckgegeben.
+ if( aToken.Len() || sTmpBuffer.getLength() )
+ {
+ // Der bisherige Text wird von _GetNextChar()
+ // zurueckgegeben und beim naechsten Aufruf wird
+ // ein neues Zeichen gelesen. Also muessen wir uns
+ // noch vor das & stellen.
+ nNextCh = 0U;
+ rInput.Seek( nStreamPos-(sal_uInt32)GetCharSize() );
+ nlLinePos = nLinePos-1;
+ ClearTxtConvContext();
+ bReadNextChar = TRUE;
+ }
+ bNextCh = FALSE;
+ }
+ }
+ break;
+ case '=':
+ if( '>'==cBreak && !cQuote )
+ bEqSignFound = TRUE;
+ sTmpBuffer.append( nNextCh );
+ break;
+
+ case '\\':
+ if( '>'==cBreak )
+ {
+ // Innerhalb von Tags kennzeichnen
+ sTmpBuffer.append( (sal_Unicode)'\\' );
+ if( MAX_LEN == sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ }
+ sTmpBuffer.append( (sal_Unicode)'\\' );
+ break;
+
+ case '\"':
+ case '\'':
+ if( '>'==cBreak )
+ {
+ if( bEqSignFound )
+ cQuote = nNextCh;
+ else if( cQuote && (cQuote==nNextCh ) )
+ cQuote = 0U;
+ }
+ sTmpBuffer.append( nNextCh );
+ bEqSignFound = FALSE;
+ break;
+
+ case sal_Unicode(EOF):
+ if( rInput.IsEof() )
+ {
+// MIB 20.11.98: Das macht hier keinen Sinn, oder doch: Zumindest wird
+// abc&auml;<EOF> nicht angezeigt, also lassen wir das in Zukunft.
+// if( '>' != cBreak )
+// eState = SVPAR_ACCEPTED;
+ bWeiter = FALSE;
+ }
+ else
+ {
+ sTmpBuffer.append( nNextCh );
+ }
+ break;
+
+ case '<':
+ bEqSignFound = FALSE;
+ if( '>'==cBreak )
+ sTmpBuffer.append( nNextCh );
+ else
+ bWeiter = FALSE; // Abbrechen, String zusammen
+ break;
+
+ case '\f':
+ if( '>' == cBreak )
+ {
+ // Beim Scannen von Optionen wie ein Space behandeln
+ sTmpBuffer.append( (sal_Unicode)' ' );
+ }
+ else
+ {
+ // sonst wird es ein eigenes Token
+ bWeiter = FALSE;
+ }
+ break;
+
+ case '\r':
+ case '\n':
+ if( '>'==cBreak )
+ {
+ // #26979# cr/lf in Tag wird in _GetNextToken() behandeln
+ sTmpBuffer.append( nNextCh );
+ break;
+ }
+ else if( bReadListing || bReadXMP || bReadPRE || bReadTextArea )
+ {
+ bWeiter = FALSE;
+ break;
+ }
+ // Bug 18984: CR-LF -> Blank
+ // Folge von CR/LF/BLANK/TAB nur in ein Blank wandeln
+ // kein break!!
+ case '\t':
+ if( '\t'==nNextCh && bReadPRE && '>'!=cBreak )
+ {
+ // In <PRE>: Tabs nach oben durchreichen
+ bWeiter = FALSE;
+ break;
+ }
+ // kein break
+ case '\x0b':
+ if( '\x0b'==nNextCh && (bReadPRE || bReadXMP ||bReadListing) &&
+ '>'!=cBreak )
+ {
+ break;
+ }
+ nNextCh = ' ';
+ // kein break;
+ case ' ':
+ sTmpBuffer.append( nNextCh );
+ if( '>'!=cBreak && (!bReadListing && !bReadXMP &&
+ !bReadPRE && !bReadTextArea) )
+ {
+ // alle Folgen von Blanks/Tabs/CR/LF zu einem Blank umwandeln
+ do {
+ if( sal_Unicode(EOF) == (nNextCh = GetNextChar()) &&
+ rInput.IsEof() )
+ {
+ if( aToken.Len() || sTmpBuffer.getLength() > 1L )
+ {
+ // ausser den Blanks wurde noch etwas geselen
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ return HTML_TEXTTOKEN;
+ }
+ else
+ // nur Blanks gelesen: dann darf kein Text
+ // mehr zurueckgegeben werden und _GetNextToken
+ // muss auf EOF laufen
+ return 0;
+ }
+ } while ( ' ' == nNextCh || '\t' == nNextCh ||
+ '\r' == nNextCh || '\n' == nNextCh ||
+ '\x0b' == nNextCh );
+ bNextCh = FALSE;
+ }
+ break;
+
+ default:
+ bEqSignFound = FALSE;
+ if( (nNextCh==cBreak && !cQuote) ||
+ (ULONG(aToken.Len()) + MAX_LEN) > ULONG(STRING_MAXLEN & ~1 ))
+ bWeiter = FALSE;
+ else
+ {
+ do {
+ // alle anderen Zeichen kommen in den Text
+ sTmpBuffer.append( nNextCh );
+ if( MAX_LEN == sTmpBuffer.getLength() )
+ {
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ if( (ULONG(aToken.Len()) + MAX_LEN) >
+ ULONG(STRING_MAXLEN & ~1 ) )
+ {
+ nNextCh = GetNextChar();
+ return HTML_TEXTTOKEN;
+ }
+ }
+ if( ( sal_Unicode(EOF) == (nNextCh = GetNextChar()) &&
+ rInput.IsEof() ) ||
+ !IsParserWorking() )
+ {
+ if( sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ return HTML_TEXTTOKEN;
+ }
+ } while( HTML_ISALPHA( nNextCh ) || HTML_ISDIGIT( nNextCh ) );
+ bNextCh = FALSE;
+ }
+ }
+
+ if( MAX_LEN == sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ if( bWeiter && bNextCh )
+ nNextCh = GetNextChar();
+ }
+
+ if( sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ return HTML_TEXTTOKEN;
+}
+
+int HTMLParser::_GetNextRawToken()
+{
+ ::rtl::OUStringBuffer sTmpBuffer( MAX_LEN );
+
+ if( bEndTokenFound )
+ {
+ // beim letzten Aufruf haben wir das End-Token bereits gefunden,
+ // deshalb muessen wir es nicht noch einmal suchen
+ bReadScript = FALSE;
+ bReadStyle = FALSE;
+ aEndToken.Erase();
+ bEndTokenFound = FALSE;
+
+ return 0;
+ }
+
+ // per default geben wir HTML_RAWDATA zurueck
+ int bWeiter = TRUE;
+ int nToken = HTML_RAWDATA;
+ SaveState( 0 );
+ while( bWeiter && IsParserWorking() )
+ {
+ int bNextCh = TRUE;
+ switch( nNextCh )
+ {
+ case '<':
+ {
+ // Vielleicht haben wir das Ende erreicht
+
+ // das bisher gelesene erstmal retten
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ // und die Position im Stream merken
+ ULONG nStreamPos = rInput.Tell();
+ ULONG nLineNr = GetLineNr();
+ ULONG nLinePos = GetLinePos();
+
+ // Start eines End-Token?
+ int bOffState = FALSE;
+ if( '/' == (nNextCh = GetNextChar()) )
+ {
+ bOffState = TRUE;
+ nNextCh = GetNextChar();
+ }
+ else if( '!' == nNextCh )
+ {
+ sTmpBuffer.append( nNextCh );
+ nNextCh = GetNextChar();
+ }
+
+ // jetzt die Buchstaben danach lesen
+ while( (HTML_ISALPHA(nNextCh) || '-'==nNextCh) &&
+ IsParserWorking() && sTmpBuffer.getLength() < MAX_LEN )
+ {
+ sTmpBuffer.append( nNextCh );
+ nNextCh = GetNextChar();
+ }
+
+ String aTok( sTmpBuffer.getStr(),
+ sal::static_int_cast< xub_StrLen >(
+ sTmpBuffer.getLength()) );
+ aTok.ToUpperAscii();
+ BOOL bDone = FALSE;
+ if( bReadScript || aEndToken.Len() )
+ {
+ if( !bReadComment )
+ {
+ if( aTok.CompareToAscii( OOO_STRING_SVTOOLS_HTML_comment, 3 )
+ == COMPARE_EQUAL )
+ {
+ bReadComment = TRUE;
+ }
+ else
+ {
+ // ein Script muss mit "</SCRIPT>" aufhoehren, wobei
+ // wir es mit dem ">" aus sicherheitsgruenden
+ // erstmal nicht so genau nehmen
+ bDone = bOffState && // '>'==nNextCh &&
+ COMPARE_EQUAL == ( bReadScript
+ ? aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_script)
+ : aTok.CompareTo(aEndToken) );
+ }
+ }
+ if( bReadComment && '>'==nNextCh && aTok.Len() >= 2 &&
+ aTok.Copy( aTok.Len()-2 ).EqualsAscii( "--" ) )
+ {
+ // hier ist ein Kommentar der Art <!-----> zuende
+ bReadComment = FALSE;
+ }
+ }
+ else
+ {
+ // ein Style-Sheet kann mit </STYLE>, </HEAD> oder
+ // <BODY> aughoehren
+ if( bOffState )
+ bDone = aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_style)
+ == COMPARE_EQUAL ||
+ aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_head)
+ == COMPARE_EQUAL;
+ else
+ bDone =
+ aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_body) == COMPARE_EQUAL;
+ }
+
+ if( bDone )
+ {
+ // das war's, jetzt muessen wir gegebenenfalls den
+ // bisher gelesenen String zurueckgeben und dnach normal
+ // weitermachen
+
+ bWeiter = FALSE;
+
+ // nToken==0 heisst, dass _GetNextToken gleich weiterliest
+ if( !aToken.Len() && (bReadStyle || bReadScript) )
+ {
+ // wir koennen sofort die Umgebung beeden und
+ // das End-Token parsen
+ bReadScript = FALSE;
+ bReadStyle = FALSE;
+ aEndToken.Erase();
+ nToken = 0;
+ }
+ else
+ {
+ // wir muessen bReadScript/bReadStyle noch am
+ // Leben lassen und koennen erst beim naechsten
+ // mal das End-Token Parsen
+ bEndTokenFound = TRUE;
+ }
+
+ // jetzt fahren wir im Stream auf das '<' zurueck
+ rInput.Seek( nStreamPos );
+ SetLineNr( nLineNr );
+ SetLinePos( nLinePos );
+ ClearTxtConvContext();
+ nNextCh = '<';
+
+ // den String wollen wir nicht an das Token haengen
+ sTmpBuffer.setLength( 0L );
+ }
+ else
+ {
+ // "</" merken, alles andere steht noch im buffer
+ aToken += (sal_Unicode)'<';
+ if( bOffState )
+ aToken += (sal_Unicode)'/';
+
+ bNextCh = FALSE;
+ }
+ }
+ break;
+ case '-':
+ sTmpBuffer.append( nNextCh );
+ if( bReadComment )
+ {
+ BOOL bTwoMinus = FALSE;
+ nNextCh = GetNextChar();
+ while( '-' == nNextCh && IsParserWorking() )
+ {
+ bTwoMinus = TRUE;
+
+ if( MAX_LEN == sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ sTmpBuffer.append( nNextCh );
+ nNextCh = GetNextChar();
+ }
+
+ if( '>' == nNextCh && IsParserWorking() && bTwoMinus )
+ bReadComment = FALSE;
+
+ bNextCh = FALSE;
+ }
+ break;
+
+ case '\r':
+ // \r\n? beendet das aktuelle Text-Token (auch wenn es leer ist)
+ nNextCh = GetNextChar();
+ if( nNextCh=='\n' )
+ nNextCh = GetNextChar();
+ bWeiter = FALSE;
+ break;
+ case '\n':
+ // \n beendet das aktuelle Text-Token (auch wenn es leer ist)
+ nNextCh = GetNextChar();
+ bWeiter = FALSE;
+ break;
+ case sal_Unicode(EOF):
+ // eof beendet das aktuelle Text-Token und tut so, als ob
+ // ein End-Token gelesen wurde
+ if( rInput.IsEof() )
+ {
+ bWeiter = FALSE;
+ if( aToken.Len() || sTmpBuffer.getLength() )
+ {
+ bEndTokenFound = TRUE;
+ }
+ else
+ {
+ bReadScript = FALSE;
+ bReadStyle = FALSE;
+ aEndToken.Erase();
+ nToken = 0;
+ }
+ break;
+ }
+ // kein break
+ default:
+ // alle anderen Zeichen landen im Buffer
+ sTmpBuffer.append( nNextCh );
+ break;
+ }
+
+ if( (!bWeiter && sTmpBuffer.getLength() > 0L) ||
+ MAX_LEN == sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ if( bWeiter && bNextCh )
+ nNextCh = GetNextChar();
+ }
+
+ if( IsParserWorking() )
+ SaveState( 0 );
+ else
+ nToken = 0;
+
+ return nToken;
+}
+
+// scanne das naechste Token,
+int __EXPORT HTMLParser::_GetNextToken()
+{
+ int nRet = 0;
+ sSaveToken.Erase();
+
+ // die Optionen loeschen
+ if( pOptions->Count() )
+ pOptions->DeleteAndDestroy( 0, pOptions->Count() );
+
+ if( !IsParserWorking() ) // wenn schon Fehler, dann nicht weiter!
+ return 0;
+
+ BOOL bReadNextCharSave = bReadNextChar;
+ if( bReadNextChar )
+ {
+ DBG_ASSERT( !bEndTokenFound,
+ "</SCRIPT> gelesen und trotzdem noch ein Zeichen lesen?" );
+ nNextCh = GetNextChar();
+ if( !IsParserWorking() ) // wenn schon Fehler, dann nicht weiter!
+ return 0;
+ bReadNextChar = FALSE;
+ }
+
+ if( bReadScript || bReadStyle || aEndToken.Len() )
+ {
+ nRet = _GetNextRawToken();
+ if( nRet || !IsParserWorking() )
+ return nRet;
+ }
+
+ do {
+ int bNextCh = TRUE;
+ switch( nNextCh )
+ {
+ case '<':
+ {
+ ULONG nStreamPos = rInput.Tell();
+ ULONG nLineNr = GetLineNr();
+ ULONG nLinePos = GetLinePos();
+
+ int bOffState = FALSE;
+ if( '/' == (nNextCh = GetNextChar()) )
+ {
+ bOffState = TRUE;
+ nNextCh = GetNextChar();
+ }
+ if( HTML_ISALPHA( nNextCh ) || '!'==nNextCh ) // fix #26984#
+ {
+ ::rtl::OUStringBuffer sTmpBuffer;
+ do {
+ sTmpBuffer.append( nNextCh );
+ if( MAX_LEN == sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ nNextCh = GetNextChar();
+ } while( '>' != nNextCh && !HTML_ISSPACE( nNextCh ) &&
+ IsParserWorking() && !rInput.IsEof() );
+
+ if( sTmpBuffer.getLength() )
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ // Blanks ueberlesen
+ while( HTML_ISSPACE( nNextCh ) && IsParserWorking() )
+ nNextCh = GetNextChar();
+
+ if( !IsParserWorking() )
+ {
+ if( SVPAR_PENDING == eState )
+ bReadNextChar = bReadNextCharSave;
+ break;
+ }
+
+ // suche das Token in der Tabelle:
+ sSaveToken = aToken;
+ aToken.ToUpperAscii();
+ if( 0 == (nRet = GetHTMLToken( aToken )) )
+ // Unknown Control
+ nRet = HTML_UNKNOWNCONTROL_ON;
+
+ // Wenn es ein Token zum ausschalten ist ...
+ if( bOffState )
+ {
+ if( HTML_TOKEN_ONOFF & nRet )
+ {
+ // und es ein Off-Token gibt, das daraus machen
+ ++nRet;
+ }
+ else if( HTML_LINEBREAK!=nRet )
+ {
+ // und es kein Off-Token gibt, ein unbekanntes
+ // Token daraus machen (ausser </BR>, das wird
+ // wie <BR> behandelt
+ nRet = HTML_UNKNOWNCONTROL_OFF;
+ }
+ }
+
+ if( nRet == HTML_COMMENT )
+ {
+ // fix: sSaveToken wegen Gross-/Kleinschreibung
+ // als Anfang des Kommentars benutzen und ein
+ // Space anhaengen.
+ aToken = sSaveToken;
+ if( '>'!=nNextCh )
+ aToken += (sal_Unicode)' ';
+ ULONG nCStreamPos = 0;
+ ULONG nCLineNr = 0;
+ ULONG nCLinePos = 0;
+ xub_StrLen nCStrLen = 0;
+
+ BOOL bDone = FALSE;
+ // bis zum schliessenden --> lesen. wenn keins gefunden
+ // wurde beim der ersten > wieder aufsetzen
+ while( !bDone && !rInput.IsEof() && IsParserWorking() )
+ {
+ if( '>'==nNextCh )
+ {
+ if( !nCStreamPos )
+ {
+ nCStreamPos = rInput.Tell();
+ nCStrLen = aToken.Len();
+ nCLineNr = GetLineNr();
+ nCLinePos = GetLinePos();
+ }
+ bDone = aToken.Len() >= 2 &&
+ aToken.Copy(aToken.Len()-2,2).
+ EqualsAscii( "--" );
+ if( !bDone )
+ aToken += nNextCh;
+ }
+ else
+ aToken += nNextCh;
+ if( !bDone )
+ nNextCh = GetNextChar();
+ }
+ if( !bDone && IsParserWorking() && nCStreamPos )
+ {
+ rInput.Seek( nCStreamPos );
+ SetLineNr( nCLineNr );
+ SetLinePos( nCLinePos );
+ ClearTxtConvContext();
+ aToken.Erase( nCStrLen );
+ nNextCh = '>';
+ }
+ }
+ else
+ {
+ // den TokenString koennen wir jetzt verwerfen
+ aToken.Erase();
+ }
+
+ // dann lesen wir mal alles bis zur schliessenden '>'
+ if( '>' != nNextCh && IsParserWorking() )
+ {
+ ScanText( '>' );
+ if( sal_Unicode(EOF) == nNextCh && rInput.IsEof() )
+ {
+ // zurueck hinter die < gehen und dort neu
+ // aufsetzen, das < als Text zurueckgeben
+ rInput.Seek( nStreamPos );
+ SetLineNr( nLineNr );
+ SetLinePos( nLinePos );
+ ClearTxtConvContext();
+
+ aToken = '<';
+ nRet = HTML_TEXTTOKEN;
+ nNextCh = GetNextChar();
+ bNextCh = FALSE;
+ break;
+ }
+ }
+ if( SVPAR_PENDING == eState )
+ bReadNextChar = bReadNextCharSave;
+ }
+ else
+ {
+ if( bOffState )
+ {
+ // einfach alles wegschmeissen
+ ScanText( '>' );
+ if( sal_Unicode(EOF) == nNextCh && rInput.IsEof() )
+ {
+ // zurueck hinter die < gehen und dort neu
+ // aufsetzen, das < als Text zurueckgeben
+ rInput.Seek( nStreamPos );
+ SetLineNr( nLineNr );
+ SetLinePos( nLinePos );
+ ClearTxtConvContext();
+
+ aToken = '<';
+ nRet = HTML_TEXTTOKEN;
+ nNextCh = GetNextChar();
+ bNextCh = FALSE;
+ break;
+ }
+ if( SVPAR_PENDING == eState )
+ bReadNextChar = bReadNextCharSave;
+ aToken.Erase();
+ }
+ else if( '%' == nNextCh )
+ {
+ nRet = HTML_UNKNOWNCONTROL_ON;
+
+ ULONG nCStreamPos = rInput.Tell();
+ ULONG nCLineNr = GetLineNr(), nCLinePos = GetLinePos();
+
+ BOOL bDone = FALSE;
+ // bis zum schliessenden %> lesen. wenn keins gefunden
+ // wurde beim der ersten > wieder aufsetzen
+ while( !bDone && !rInput.IsEof() && IsParserWorking() )
+ {
+ bDone = '>'==nNextCh && aToken.Len() >= 1 &&
+ '%' == aToken.GetChar( aToken.Len()-1 );
+ if( !bDone )
+ {
+ aToken += nNextCh;
+ nNextCh = GetNextChar();
+ }
+ }
+ if( !bDone && IsParserWorking() )
+ {
+ rInput.Seek( nCStreamPos );
+ SetLineNr( nCLineNr );
+ SetLinePos( nCLinePos );
+ ClearTxtConvContext();
+ aToken.AssignAscii( "<%", 2 );
+ nRet = HTML_TEXTTOKEN;
+ break;
+ }
+ if( IsParserWorking() )
+ {
+ sSaveToken = aToken;
+ aToken.Erase();
+ }
+ }
+ else
+ {
+ aToken = '<';
+ nRet = HTML_TEXTTOKEN;
+ bNextCh = FALSE;
+ break;
+ }
+ }
+
+ if( IsParserWorking() )
+ {
+ bNextCh = '>' == nNextCh;
+ switch( nRet )
+ {
+ case HTML_TEXTAREA_ON:
+ bReadTextArea = TRUE;
+ break;
+ case HTML_TEXTAREA_OFF:
+ bReadTextArea = FALSE;
+ break;
+ case HTML_SCRIPT_ON:
+ if( !bReadTextArea )
+ bReadScript = TRUE;
+ break;
+ case HTML_SCRIPT_OFF:
+ if( !bReadTextArea )
+ {
+ bReadScript = FALSE;
+ // JavaScript kann den Stream veraendern
+ // also muss das letzte Zeichen nochmals
+ // gelesen werden
+ bReadNextChar = TRUE;
+ bNextCh = FALSE;
+ }
+ break;
+
+ case HTML_STYLE_ON:
+ bReadStyle = TRUE;
+ break;
+ case HTML_STYLE_OFF:
+ bReadStyle = FALSE;
+ break;
+ }
+
+ }
+ }
+ break;
+
+ case sal_Unicode(EOF):
+ if( rInput.IsEof() )
+ {
+ eState = SVPAR_ACCEPTED;
+ nRet = nNextCh;
+ }
+ else
+ {
+ // normalen Text lesen
+ goto scan_text;
+ }
+ break;
+
+ case '\f':
+ // Form-Feeds werden jetzt extra nach oben gereicht
+ nRet = HTML_LINEFEEDCHAR; // !!! eigentlich FORMFEEDCHAR
+ break;
+
+ case '\n':
+ case '\r':
+ if( bReadListing || bReadXMP || bReadPRE || bReadTextArea )
+ {
+ sal_Unicode c = GetNextChar();
+ if( ( '\n' != nNextCh || '\r' != c ) &&
+ ( '\r' != nNextCh || '\n' != c ) )
+ {
+ bNextCh = FALSE;
+ nNextCh = c;
+ }
+ nRet = HTML_NEWPARA;
+ break;
+ }
+ // kein break !
+ case '\t':
+ if( bReadPRE )
+ {
+ nRet = HTML_TABCHAR;
+ break;
+ }
+ // kein break !
+ case ' ':
+ // kein break !
+ default:
+
+scan_text:
+ // es folgt "normaler" Text
+ nRet = ScanText();
+ bNextCh = 0 == aToken.Len();
+
+ // der Text sollte noch verarbeitet werden
+ if( !bNextCh && eState == SVPAR_PENDING )
+ {
+ eState = SVPAR_WORKING;
+ bReadNextChar = TRUE;
+ }
+
+ break;
+ }
+
+ if( bNextCh && SVPAR_WORKING == eState )
+ {
+ nNextCh = GetNextChar();
+ if( SVPAR_PENDING == eState && nRet && HTML_TEXTTOKEN != nRet )
+ {
+ bReadNextChar = TRUE;
+ eState = SVPAR_WORKING;
+ }
+ }
+
+ } while( !nRet && SVPAR_WORKING == eState );
+
+ if( SVPAR_PENDING == eState )
+ nRet = -1; // irgendwas ungueltiges
+
+ return nRet;
+}
+
+void HTMLParser::UnescapeToken()
+{
+ xub_StrLen nPos=0;
+
+ BOOL bEscape = FALSE;
+ while( nPos < aToken.Len() )
+ {
+ BOOL bOldEscape = bEscape;
+ bEscape = FALSE;
+ if( '\\'==aToken.GetChar(nPos) && !bOldEscape )
+ {
+ aToken.Erase( nPos, 1 );
+ bEscape = TRUE;
+ }
+ else
+ {
+ nPos++;
+ }
+ }
+}
+
+// hole die Optionen
+const HTMLOptions *HTMLParser::GetOptions( USHORT *pNoConvertToken ) const
+{
+ // wenn die Option fuer das aktuelle Token schon einmal
+ // geholt wurden, geben wir sie noch einmal zurueck
+ if( pOptions->Count() )
+ return pOptions;
+
+ xub_StrLen nPos = 0;
+ while( nPos < aToken.Len() )
+ {
+ // ein Zeichen ? Dann faengt hier eine Option an
+ if( HTML_ISALPHA( aToken.GetChar(nPos) ) )
+ {
+ int nToken;
+ String aValue;
+ xub_StrLen nStt = nPos;
+ sal_Unicode cChar = 0;
+
+ // Eigentlich sind hier nur ganz bestimmte Zeichen erlaubt.
+ // Netscape achtet aber nur auf "=" und Leerzeichen (siehe
+ // Mozilla: PA_FetchRequestedNameValues in
+ // lipparse/pa_mdl.c
+// while( nPos < aToken.Len() &&
+// ( '-'==(c=aToken[nPos]) || isalnum(c) || '.'==c || '_'==c) )
+ while( nPos < aToken.Len() && '=' != (cChar=aToken.GetChar(nPos)) &&
+ HTML_ISPRINTABLE(cChar) && !HTML_ISSPACE(cChar) )
+ nPos++;
+
+ String sName( aToken.Copy( nStt, nPos-nStt ) );
+
+//JP 23.03.97: die PlugIns wollen die TokenName im "Original" haben
+// also nur fuers Suchen in UpperCase wandeln
+ String sNameUpperCase( sName );
+ sNameUpperCase.ToUpperAscii();
+
+ nToken = GetHTMLOption( sNameUpperCase ); // der Name ist fertig
+ DBG_ASSERTWARNING( nToken!=HTML_O_UNKNOWN,
+ "GetOption: unbekannte HTML-Option" );
+ BOOL bStripCRLF = (nToken < HTML_OPTION_SCRIPT_START ||
+ nToken >= HTML_OPTION_SCRIPT_END) &&
+ (!pNoConvertToken || nToken != *pNoConvertToken);
+
+ while( nPos < aToken.Len() &&
+ ( !HTML_ISPRINTABLE( (cChar=aToken.GetChar(nPos)) ) ||
+ HTML_ISSPACE(cChar) ) )
+ nPos++;
+
+ // hat die Option auch einen Wert?
+ if( nPos!=aToken.Len() && '='==cChar )
+ {
+ nPos++;
+
+ while( nPos < aToken.Len() &&
+ ( !HTML_ISPRINTABLE( (cChar=aToken.GetChar(nPos)) ) ||
+ ' '==cChar || '\t'==cChar || '\r'==cChar || '\n'==cChar ) )
+ nPos++;
+
+ if( nPos != aToken.Len() )
+ {
+ xub_StrLen nLen = 0;
+ nStt = nPos;
+ if( ('"'==cChar) || ('\'')==cChar )
+ {
+ sal_Unicode cEnd = cChar;
+ nPos++; nStt++;
+ BOOL bDone = FALSE;
+ BOOL bEscape = FALSE;
+ while( nPos < aToken.Len() && !bDone )
+ {
+ BOOL bOldEscape = bEscape;
+ bEscape = FALSE;
+ cChar = aToken.GetChar(nPos);
+ switch( cChar )
+ {
+ case '\r':
+ case '\n':
+ if( bStripCRLF )
+ ((String &)aToken).Erase( nPos, 1 );
+ else
+ nPos++, nLen++;
+ break;
+ case '\\':
+ if( bOldEscape )
+ {
+ nPos++, nLen++;
+ }
+ else
+ {
+ ((String &)aToken).Erase( nPos, 1 );
+ bEscape = TRUE;
+ }
+ break;
+ case '"':
+ case '\'':
+ bDone = !bOldEscape && cChar==cEnd;
+ if( !bDone )
+ nPos++, nLen++;
+ break;
+ default:
+ nPos++, nLen++;
+ break;
+ }
+ }
+ if( nPos!=aToken.Len() )
+ nPos++;
+ }
+ else
+ {
+ // hier sind wir etwas laxer als der
+ // Standard und erlauben alles druckbare
+ BOOL bEscape = FALSE;
+ BOOL bDone = FALSE;
+ while( nPos < aToken.Len() && !bDone )
+ {
+ BOOL bOldEscape = bEscape;
+ bEscape = FALSE;
+ sal_Unicode c = aToken.GetChar(nPos);
+ switch( c )
+ {
+ case ' ':
+ bDone = !bOldEscape;
+ if( !bDone )
+ nPos++, nLen++;
+ break;
+
+ case '\t':
+ case '\r':
+ case '\n':
+ bDone = TRUE;
+ break;
+
+ case '\\':
+ if( bOldEscape )
+ {
+ nPos++, nLen++;
+ }
+ else
+ {
+ ((String &)aToken).Erase( nPos, 1 );
+ bEscape = TRUE;
+ }
+ break;
+
+ default:
+ if( HTML_ISPRINTABLE( c ) )
+ nPos++, nLen++;
+ else
+ bDone = TRUE;
+ break;
+ }
+ }
+ }
+
+ if( nLen )
+ aValue = aToken.Copy( nStt, nLen );
+ }
+ }
+
+ // Wir kennen das Token und koennen es Speichern
+ HTMLOption *pOption =
+ new HTMLOption(
+ sal::static_int_cast< sal_uInt16 >(nToken), sName, aValue );
+
+ pOptions->Insert( pOption, pOptions->Count() );
+
+ }
+ else
+ // white space un unerwartete Zeichen ignorieren wie
+ nPos++;
+ }
+
+ return pOptions;
+}
+
+int HTMLParser::FilterPRE( int nToken )
+{
+ switch( nToken )
+ {
+#ifdef HTML_BEHAVIOUR
+ // diese werden laut Definition zu LFs
+ case HTML_PARABREAK_ON:
+ case HTML_LINEBREAK:
+ nToken = HTML_NEWPARA;
+#else
+ // in Netscape zeigen sie aber nur in nicht-leeren Absaetzen Wirkung
+ case HTML_PARABREAK_ON:
+ nToken = HTML_LINEBREAK;
+ case HTML_LINEBREAK:
+#endif
+ case HTML_NEWPARA:
+ nPre_LinePos = 0;
+ if( bPre_IgnoreNewPara )
+ nToken = 0;
+ break;
+
+ case HTML_TABCHAR:
+ {
+ xub_StrLen nSpaces = sal::static_int_cast< xub_StrLen >(
+ 8 - (nPre_LinePos % 8));
+ DBG_ASSERT( !aToken.Len(), "Wieso ist das Token nicht leer?" );
+ aToken.Expand( nSpaces, ' ' );
+ nPre_LinePos += nSpaces;
+ nToken = HTML_TEXTTOKEN;
+ }
+ break;
+ // diese bleiben erhalten
+ case HTML_TEXTTOKEN:
+ nPre_LinePos += aToken.Len();
+ break;
+
+ case HTML_SELECT_ON:
+ case HTML_SELECT_OFF:
+ case HTML_BODY_ON:
+ case HTML_FORM_ON:
+ case HTML_FORM_OFF:
+ case HTML_INPUT:
+ case HTML_OPTION:
+ case HTML_TEXTAREA_ON:
+ case HTML_TEXTAREA_OFF:
+
+ case HTML_IMAGE:
+ case HTML_APPLET_ON:
+ case HTML_APPLET_OFF:
+ case HTML_PARAM:
+ case HTML_EMBED:
+
+ case HTML_HEAD1_ON:
+ case HTML_HEAD1_OFF:
+ case HTML_HEAD2_ON:
+ case HTML_HEAD2_OFF:
+ case HTML_HEAD3_ON:
+ case HTML_HEAD3_OFF:
+ case HTML_HEAD4_ON:
+ case HTML_HEAD4_OFF:
+ case HTML_HEAD5_ON:
+ case HTML_HEAD5_OFF:
+ case HTML_HEAD6_ON:
+ case HTML_HEAD6_OFF:
+ case HTML_BLOCKQUOTE_ON:
+ case HTML_BLOCKQUOTE_OFF:
+ case HTML_ADDRESS_ON:
+ case HTML_ADDRESS_OFF:
+ case HTML_HORZRULE:
+
+ case HTML_CENTER_ON:
+ case HTML_CENTER_OFF:
+ case HTML_DIVISION_ON:
+ case HTML_DIVISION_OFF:
+
+ case HTML_SCRIPT_ON:
+ case HTML_SCRIPT_OFF:
+ case HTML_RAWDATA:
+
+ case HTML_TABLE_ON:
+ case HTML_TABLE_OFF:
+ case HTML_CAPTION_ON:
+ case HTML_CAPTION_OFF:
+ case HTML_COLGROUP_ON:
+ case HTML_COLGROUP_OFF:
+ case HTML_COL_ON:
+ case HTML_COL_OFF:
+ case HTML_THEAD_ON:
+ case HTML_THEAD_OFF:
+ case HTML_TFOOT_ON:
+ case HTML_TFOOT_OFF:
+ case HTML_TBODY_ON:
+ case HTML_TBODY_OFF:
+ case HTML_TABLEROW_ON:
+ case HTML_TABLEROW_OFF:
+ case HTML_TABLEDATA_ON:
+ case HTML_TABLEDATA_OFF:
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEHEADER_OFF:
+
+ case HTML_ANCHOR_ON:
+ case HTML_ANCHOR_OFF:
+ case HTML_BOLD_ON:
+ case HTML_BOLD_OFF:
+ case HTML_ITALIC_ON:
+ case HTML_ITALIC_OFF:
+ case HTML_STRIKE_ON:
+ case HTML_STRIKE_OFF:
+ case HTML_STRIKETHROUGH_ON:
+ case HTML_STRIKETHROUGH_OFF:
+ case HTML_UNDERLINE_ON:
+ case HTML_UNDERLINE_OFF:
+ case HTML_BASEFONT_ON:
+ case HTML_BASEFONT_OFF:
+ case HTML_FONT_ON:
+ case HTML_FONT_OFF:
+ case HTML_BLINK_ON:
+ case HTML_BLINK_OFF:
+ case HTML_SPAN_ON:
+ case HTML_SPAN_OFF:
+ case HTML_SUBSCRIPT_ON:
+ case HTML_SUBSCRIPT_OFF:
+ case HTML_SUPERSCRIPT_ON:
+ case HTML_SUPERSCRIPT_OFF:
+ case HTML_BIGPRINT_ON:
+ case HTML_BIGPRINT_OFF:
+ case HTML_SMALLPRINT_OFF:
+ case HTML_SMALLPRINT_ON:
+
+ case HTML_EMPHASIS_ON:
+ case HTML_EMPHASIS_OFF:
+ case HTML_CITIATION_ON:
+ case HTML_CITIATION_OFF:
+ case HTML_STRONG_ON:
+ case HTML_STRONG_OFF:
+ case HTML_CODE_ON:
+ case HTML_CODE_OFF:
+ case HTML_SAMPLE_ON:
+ case HTML_SAMPLE_OFF:
+ case HTML_KEYBOARD_ON:
+ case HTML_KEYBOARD_OFF:
+ case HTML_VARIABLE_ON:
+ case HTML_VARIABLE_OFF:
+ case HTML_DEFINSTANCE_ON:
+ case HTML_DEFINSTANCE_OFF:
+ case HTML_SHORTQUOTE_ON:
+ case HTML_SHORTQUOTE_OFF:
+ case HTML_LANGUAGE_ON:
+ case HTML_LANGUAGE_OFF:
+ case HTML_AUTHOR_ON:
+ case HTML_AUTHOR_OFF:
+ case HTML_PERSON_ON:
+ case HTML_PERSON_OFF:
+ case HTML_ACRONYM_ON:
+ case HTML_ACRONYM_OFF:
+ case HTML_ABBREVIATION_ON:
+ case HTML_ABBREVIATION_OFF:
+ case HTML_INSERTEDTEXT_ON:
+ case HTML_INSERTEDTEXT_OFF:
+ case HTML_DELETEDTEXT_ON:
+ case HTML_DELETEDTEXT_OFF:
+ case HTML_TELETYPE_ON:
+ case HTML_TELETYPE_OFF:
+
+ break;
+
+ // der Rest wird als unbekanntes Token behandelt
+ default:
+ if( nToken )
+ {
+ nToken =
+ ( ((HTML_TOKEN_ONOFF & nToken) && (1 & nToken))
+ ? HTML_UNKNOWNCONTROL_OFF
+ : HTML_UNKNOWNCONTROL_ON );
+ }
+ break;
+ }
+
+ bPre_IgnoreNewPara = FALSE;
+
+ return nToken;
+}
+
+int HTMLParser::FilterXMP( int nToken )
+{
+ switch( nToken )
+ {
+ case HTML_NEWPARA:
+ if( bPre_IgnoreNewPara )
+ nToken = 0;
+ case HTML_TEXTTOKEN:
+ case HTML_NONBREAKSPACE:
+ case HTML_SOFTHYPH:
+ break; // bleiben erhalten
+
+ default:
+ if( nToken )
+ {
+ if( (HTML_TOKEN_ONOFF & nToken) && (1 & nToken) )
+ {
+ sSaveToken.Insert( '<', 0 );
+ sSaveToken.Insert( '/', 1 );
+ }
+ else
+ sSaveToken.Insert( '<', 0 );
+ if( aToken.Len() )
+ {
+ UnescapeToken();
+ sSaveToken += (sal_Unicode)' ';
+ aToken.Insert( sSaveToken, 0 );
+ }
+ else
+ aToken = sSaveToken;
+ aToken += (sal_Unicode)'>';
+ nToken = HTML_TEXTTOKEN;
+ }
+ break;
+ }
+
+ bPre_IgnoreNewPara = FALSE;
+
+ return nToken;
+}
+
+int HTMLParser::FilterListing( int nToken )
+{
+ switch( nToken )
+ {
+ case HTML_NEWPARA:
+ if( bPre_IgnoreNewPara )
+ nToken = 0;
+ case HTML_TEXTTOKEN:
+ case HTML_NONBREAKSPACE:
+ case HTML_SOFTHYPH:
+ break; // bleiben erhalten
+
+ default:
+ if( nToken )
+ {
+ nToken =
+ ( ((HTML_TOKEN_ONOFF & nToken) && (1 & nToken))
+ ? HTML_UNKNOWNCONTROL_OFF
+ : HTML_UNKNOWNCONTROL_ON );
+ }
+ break;
+ }
+
+ bPre_IgnoreNewPara = FALSE;
+
+ return nToken;
+}
+
+FASTBOOL HTMLParser::IsHTMLFormat( const sal_Char* pHeader,
+ BOOL bSwitchToUCS2,
+ rtl_TextEncoding eEnc )
+{
+ // Einer der folgenden regulaeren Ausdrucke muss sich auf den String
+ // anwenden lassen, damit das Dok ein HTML-Dokument ist.
+ //
+ // ^[^<]*<[^ \t]*[> \t]
+ // -------
+ // ^<!
+ //
+ // wobei der unterstrichene Teilausdruck einem HTML-Token
+ // ensprechen muss
+
+ ByteString sCmp;
+ BOOL bUCS2B = FALSE;
+ if( bSwitchToUCS2 )
+ {
+ if( 0xfeU == (sal_uChar)pHeader[0] &&
+ 0xffU == (sal_uChar)pHeader[1] )
+ {
+ eEnc = RTL_TEXTENCODING_UCS2;
+ bUCS2B = TRUE;
+ }
+ else if( 0xffU == (sal_uChar)pHeader[0] &&
+ 0xfeU == (sal_uChar)pHeader[1] )
+ {
+ eEnc = RTL_TEXTENCODING_UCS2;
+ }
+ }
+ if
+ (
+ RTL_TEXTENCODING_UCS2 == eEnc &&
+ (
+ (0xfe == (sal_uChar)pHeader[0] && 0xff == (sal_uChar)pHeader[1]) ||
+ (0xff == (sal_uChar)pHeader[0] && 0xfe == (sal_uChar)pHeader[1])
+ )
+ )
+ {
+ if( 0xfe == (sal_uChar)pHeader[0] )
+ bUCS2B = TRUE;
+
+ xub_StrLen nLen;
+ for( nLen = 2;
+ pHeader[nLen] != 0 || pHeader[nLen+1] != 0;
+ nLen+=2 )
+ ;
+
+ ::rtl::OStringBuffer sTmp( (nLen - 2)/2 );
+ for( xub_StrLen nPos = 2; nPos < nLen; nPos += 2 )
+ {
+ sal_Unicode cUC;
+ if( bUCS2B )
+ cUC = (sal_Unicode(pHeader[nPos]) << 8) | pHeader[nPos+1];
+ else
+ cUC = (sal_Unicode(pHeader[nPos+1]) << 8) | pHeader[nPos];
+ if( 0U == cUC )
+ break;
+
+ sTmp.append( cUC < 256U ? (sal_Char)cUC : '.' );
+ }
+ sCmp = ByteString( sTmp.makeStringAndClear() );
+ }
+ else
+ {
+ sCmp = (sal_Char *)pHeader;
+ }
+
+ sCmp.ToUpperAscii();
+
+ // Ein HTML-Dokument muss in der ersten Zeile ein '<' besitzen
+ xub_StrLen nStart = sCmp.Search( '<' );
+ if( STRING_NOTFOUND == nStart )
+ return FALSE;
+ nStart++;
+
+ // danach duerfen beliebige andere Zeichen bis zu einem blank oder
+ // '>' kommen
+ sal_Char c;
+ xub_StrLen nPos;
+ for( nPos = nStart; nPos<sCmp.Len(); nPos++ )
+ {
+ if( '>'==(c=sCmp.GetChar(nPos)) || HTML_ISSPACE(c) )
+ break;
+ }
+
+ // wenn das Dokeument hinter dem < aufhoert ist es wohl kein HTML
+ if( nPos==nStart )
+ return FALSE;
+
+ // die Zeichenkette nach dem '<' muss ausserdem ein bekanntes
+ // HTML Token sein. Damit die Ausgabe eines DOS-dir-Befehls nicht
+ // als HTML interpretiert wird, wird ein <DIR> jedoch nicht als HTML
+ // interpretiert.
+ String sTest( sCmp.Copy( nStart, nPos-nStart ), RTL_TEXTENCODING_ASCII_US );
+ int nTok = GetHTMLToken( sTest );
+ if( 0 != nTok && HTML_DIRLIST_ON != nTok )
+ return TRUE;
+
+ // oder es handelt sich um ein "<!" ganz am Anfang der Datei (fix #27092#)
+ if( nStart == 1 && '!' == sCmp.GetChar( 1 ) )
+ return TRUE;
+
+ // oder wir finden irgendwo ein <HTML> in den ersten 80 Zeichen
+ nStart = sCmp.Search( OOO_STRING_SVTOOLS_HTML_html );
+ if( nStart!=STRING_NOTFOUND &&
+ nStart>0 && '<'==sCmp.GetChar(nStart-1) &&
+ nStart+4 < sCmp.Len() && '>'==sCmp.GetChar(nStart+4) )
+ return TRUE;
+
+ // sonst ist es wohl doch eher kein HTML-Dokument
+ return FALSE;
+}
+
+BOOL HTMLParser::InternalImgToPrivateURL( String& rURL )
+{
+ if( rURL.Len() < 19 || 'i' != rURL.GetChar(0) ||
+ rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_internal_gopher, 9 ) != COMPARE_EQUAL )
+ return FALSE;
+
+ BOOL bFound = FALSE;
+
+ if( rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_internal_gopher,16) == COMPARE_EQUAL )
+ {
+ String aName( rURL.Copy(16) );
+ switch( aName.GetChar(0) )
+ {
+ case 'b':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_binary );
+ break;
+ case 'i':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_image ) ||
+ aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_index );
+ break;
+ case 'm':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_menu ) ||
+ aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_movie );
+ break;
+ case 's':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_sound );
+ break;
+ case 't':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_telnet ) ||
+ aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_text );
+ break;
+ case 'u':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_unknown );
+ break;
+ }
+ }
+ else if( rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_internal_icon,14) == COMPARE_EQUAL )
+ {
+ String aName( rURL.Copy(14) );
+ switch( aName.GetChar(0) )
+ {
+ case 'b':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_baddata );
+ break;
+ case 'd':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_delayed );
+ break;
+ case 'e':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_embed );
+ break;
+ case 'i':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_insecure );
+ break;
+ case 'n':
+ bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_notfound );
+ break;
+ }
+ }
+ if( bFound )
+ {
+ String sTmp ( rURL );
+ rURL.AssignAscii( OOO_STRING_SVTOOLS_HTML_private_image );
+ rURL.Append( sTmp );
+ }
+
+ return bFound;
+}
+
+#ifdef USED
+void HTMLParser::SaveState( int nToken )
+{
+ SvParser::SaveState( nToken );
+}
+
+void HTMLParser::RestoreState()
+{
+ SvParser::RestoreState();
+}
+#endif
+
+
+enum eHtmlMetas {
+ HTML_META_NONE = 0,
+ HTML_META_AUTHOR,
+ HTML_META_DESCRIPTION,
+ HTML_META_KEYWORDS,
+ HTML_META_REFRESH,
+ HTML_META_CLASSIFICATION,
+ HTML_META_CREATED,
+ HTML_META_CHANGEDBY,
+ HTML_META_CHANGED,
+ HTML_META_GENERATOR,
+ HTML_META_SDFOOTNOTE,
+ HTML_META_SDENDNOTE,
+ HTML_META_CONTENT_TYPE
+};
+
+// <META NAME=xxx>
+static HTMLOptionEnum __READONLY_DATA aHTMLMetaNameTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_META_author, HTML_META_AUTHOR },
+ { OOO_STRING_SVTOOLS_HTML_META_changed, HTML_META_CHANGED },
+ { OOO_STRING_SVTOOLS_HTML_META_changedby, HTML_META_CHANGEDBY },
+ { OOO_STRING_SVTOOLS_HTML_META_classification,HTML_META_CLASSIFICATION},
+ { OOO_STRING_SVTOOLS_HTML_META_content_type, HTML_META_CONTENT_TYPE },
+ { OOO_STRING_SVTOOLS_HTML_META_created, HTML_META_CREATED },
+ { OOO_STRING_SVTOOLS_HTML_META_description, HTML_META_DESCRIPTION },
+ { OOO_STRING_SVTOOLS_HTML_META_keywords, HTML_META_KEYWORDS },
+ { OOO_STRING_SVTOOLS_HTML_META_generator, HTML_META_GENERATOR },
+ { OOO_STRING_SVTOOLS_HTML_META_refresh, HTML_META_REFRESH },
+ { OOO_STRING_SVTOOLS_HTML_META_sdendnote, HTML_META_SDENDNOTE },
+ { OOO_STRING_SVTOOLS_HTML_META_sdfootnote, HTML_META_SDFOOTNOTE },
+ { 0, 0 }
+};
+
+
+void HTMLParser::AddMetaUserDefined( ::rtl::OUString const & )
+{
+}
+
+bool HTMLParser::ParseMetaOptionsImpl(
+ const uno::Reference<document::XDocumentProperties> & i_xDocProps,
+ SvKeyValueIterator *i_pHTTPHeader,
+ const HTMLOptions *i_pOptions,
+ rtl_TextEncoding& o_rEnc )
+{
+ String aName, aContent;
+ USHORT nAction = HTML_META_NONE;
+ bool bHTTPEquiv = false, bChanged = false;
+
+ for ( USHORT i = i_pOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*i_pOptions)[ --i ];
+ switch ( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ if ( HTML_META_NONE==nAction )
+ {
+ pOption->GetEnum( nAction, aHTMLMetaNameTable );
+ }
+ break;
+ case HTML_O_HTTPEQUIV:
+ aName = pOption->GetString();
+ pOption->GetEnum( nAction, aHTMLMetaNameTable );
+ bHTTPEquiv = true;
+ break;
+ case HTML_O_CONTENT:
+ aContent = pOption->GetString();
+ break;
+ }
+ }
+
+ if ( bHTTPEquiv || HTML_META_DESCRIPTION != nAction )
+ {
+ // if it is not a Description, remove CRs and LFs from CONTENT
+ aContent.EraseAllChars( _CR );
+ aContent.EraseAllChars( _LF );
+ }
+ else
+ {
+ // convert line endings for Description
+ aContent.ConvertLineEnd();
+ }
+
+
+ if ( bHTTPEquiv && i_pHTTPHeader )
+ {
+ // #57232#: Netscape seems to just ignore a closing ", so we do too
+ if ( aContent.Len() && '"' == aContent.GetChar( aContent.Len()-1 ) )
+ {
+ aContent.Erase( aContent.Len() - 1 );
+ }
+ SvKeyValue aKeyValue( aName, aContent );
+ i_pHTTPHeader->Append( aKeyValue );
+ }
+
+ switch ( nAction )
+ {
+ case HTML_META_AUTHOR:
+ if (i_xDocProps.is()) {
+ i_xDocProps->setAuthor( aContent );
+ bChanged = true;
+ }
+ break;
+ case HTML_META_DESCRIPTION:
+ if (i_xDocProps.is()) {
+ i_xDocProps->setDescription( aContent );
+ bChanged = true;
+ }
+ break;
+ case HTML_META_KEYWORDS:
+ if (i_xDocProps.is()) {
+ i_xDocProps->setKeywords(
+ ::comphelper::string::convertCommaSeparated(aContent));
+ bChanged = true;
+ }
+ break;
+ case HTML_META_CLASSIFICATION:
+ if (i_xDocProps.is()) {
+ i_xDocProps->setSubject( aContent );
+ bChanged = true;
+ }
+ break;
+
+ case HTML_META_CHANGEDBY:
+ if (i_xDocProps.is()) {
+ i_xDocProps->setModifiedBy( aContent );
+ }
+ break;
+
+ case HTML_META_CREATED:
+ case HTML_META_CHANGED:
+ if ( i_xDocProps.is() && aContent.Len() &&
+ aContent.GetTokenCount() == 2 )
+ {
+ Date aDate( (ULONG)aContent.GetToken(0).ToInt32() );
+ Time aTime( (ULONG)aContent.GetToken(1).ToInt32() );
+ DateTime aDateTime( aDate, aTime );
+ ::util::DateTime uDT(aDateTime.Get100Sec(),
+ aDateTime.GetSec(), aDateTime.GetMin(),
+ aDateTime.GetHour(), aDateTime.GetDay(),
+ aDateTime.GetMonth(), aDateTime.GetYear());
+ if ( HTML_META_CREATED==nAction )
+ i_xDocProps->setCreationDate( uDT );
+ else
+ i_xDocProps->setModificationDate( uDT );
+ bChanged = true;
+ }
+ break;
+
+ case HTML_META_REFRESH:
+ DBG_ASSERT( !bHTTPEquiv || i_pHTTPHeader,
+ "Reload-URL aufgrund unterlassener MUSS-Aenderung verlorengegangen" );
+ break;
+
+ case HTML_META_CONTENT_TYPE:
+ if ( aContent.Len() )
+ {
+ o_rEnc = GetEncodingByMIME( aContent );
+ }
+ break;
+
+ case HTML_META_NONE:
+ if ( !bHTTPEquiv )
+ {
+ if (i_xDocProps.is())
+ {
+ uno::Reference<beans::XPropertyContainer> xUDProps
+ = i_xDocProps->getUserDefinedProperties();
+ try {
+ xUDProps->addProperty(aName,
+ beans::PropertyAttribute::REMOVEABLE,
+ uno::makeAny(::rtl::OUString(aContent)));
+ AddMetaUserDefined(aName);
+ bChanged = true;
+ } catch (uno::Exception &) {
+ // ignore
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return bChanged;
+}
+
+bool HTMLParser::ParseMetaOptions(
+ const uno::Reference<document::XDocumentProperties> & i_xDocProps,
+ SvKeyValueIterator *i_pHeader )
+{
+ USHORT nContentOption = HTML_O_CONTENT;
+ rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
+
+ bool bRet = ParseMetaOptionsImpl( i_xDocProps, i_pHeader,
+ GetOptions(&nContentOption),
+ eEnc );
+
+ // If the encoding is set by a META tag, it may only overwrite the
+ // current encoding if both, the current and the new encoding, are 1-BYTE
+ // encodings. Everything else cannot lead to reasonable results.
+ if (RTL_TEXTENCODING_DONTKNOW != eEnc &&
+ rtl_isOctetTextEncoding( eEnc ) &&
+ rtl_isOctetTextEncoding( GetSrcEncoding() ) )
+ {
+ eEnc = GetExtendedCompatibilityTextEncoding( eEnc ); // #89973#
+ SetSrcEncoding( eEnc );
+ }
+
+ return bRet;
+}
+
+rtl_TextEncoding HTMLParser::GetEncodingByMIME( const String& rMime )
+{
+ ByteString sType;
+ ByteString sSubType;
+ INetContentTypeParameterList aParameters;
+ ByteString sMime( rMime, RTL_TEXTENCODING_ASCII_US );
+ if (INetContentTypes::parse(sMime, sType, sSubType, &aParameters))
+ {
+ const INetContentTypeParameter * pCharset
+ = aParameters.find("charset");
+ if (pCharset != 0)
+ {
+ ByteString sValue( pCharset->m_sValue, RTL_TEXTENCODING_ASCII_US );
+ return GetExtendedCompatibilityTextEncoding(
+ rtl_getTextEncodingFromMimeCharset( sValue.GetBuffer() ) );
+ }
+ }
+ return RTL_TEXTENCODING_DONTKNOW;
+}
+
+rtl_TextEncoding HTMLParser::GetEncodingByHttpHeader( SvKeyValueIterator *pHTTPHeader )
+{
+ rtl_TextEncoding eRet = RTL_TEXTENCODING_DONTKNOW;
+ if( pHTTPHeader )
+ {
+ SvKeyValue aKV;
+ for( BOOL bCont = pHTTPHeader->GetFirst( aKV ); bCont;
+ bCont = pHTTPHeader->GetNext( aKV ) )
+ {
+ if( aKV.GetKey().EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ) )
+ {
+ if( aKV.GetValue().Len() )
+ {
+ eRet = HTMLParser::GetEncodingByMIME( aKV.GetValue() );
+ }
+ }
+ }
+ }
+ return eRet;
+}
+
+BOOL HTMLParser::SetEncodingByHTTPHeader(
+ SvKeyValueIterator *pHTTPHeader )
+{
+ BOOL bRet = FALSE;
+ rtl_TextEncoding eEnc = HTMLParser::GetEncodingByHttpHeader( pHTTPHeader );
+ if(RTL_TEXTENCODING_DONTKNOW != eEnc)
+ {
+ SetSrcEncoding( eEnc );
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+
diff --git a/svtools/source/svrtf/makefile.mk b/svtools/source/svrtf/makefile.mk
new file mode 100644
index 000000000000..5ebb0e28c69e
--- /dev/null
+++ b/svtools/source/svrtf/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=svrtf
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/svparser.obj \
+ $(SLO)$/parrtf.obj \
+ $(SLO)$/rtfout.obj \
+ $(SLO)$/rtfkeywd.obj
+
+# ==========================================================================
+
+.INCLUDE : target.mk
+
diff --git a/svtools/source/svrtf/parrtf.cxx b/svtools/source/svrtf/parrtf.cxx
new file mode 100644
index 000000000000..1c578d160307
--- /dev/null
+++ b/svtools/source/svrtf/parrtf.cxx
@@ -0,0 +1,710 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include <stdio.h> // for EOF
+#include <rtl/tencinfo.h>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include "rtftoken.h"
+#include "rtfkeywd.hxx"
+#include <svtools/parrtf.hxx>
+
+const int MAX_STRING_LEN = 1024;
+const int MAX_TOKEN_LEN = 128;
+
+#define RTF_ISDIGIT( c ) (c >= '0' && c <= '9')
+#define RTF_ISALPHA( c ) ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') )
+
+SV_IMPL_VARARR( RtfParserStates_Impl, RtfParserState_Impl )
+
+SvRTFParser::SvRTFParser( SvStream& rIn, BYTE nStackSize )
+ : SvParser( rIn, nStackSize ),
+ eUNICodeSet( RTL_TEXTENCODING_MS_1252 ), // default ist ANSI-CodeSet
+ nUCharOverread( 1 )
+{
+ // default ist ANSI-CodeSet
+ SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
+ bRTF_InTextRead = false;
+}
+
+SvRTFParser::~SvRTFParser()
+{
+}
+
+
+
+
+int SvRTFParser::_GetNextToken()
+{
+ int nRet = 0;
+ do {
+ int bNextCh = true;
+ switch( nNextCh )
+ {
+ case '\\':
+ {
+ // Steuerzeichen
+ switch( nNextCh = GetNextChar() )
+ {
+ case '{':
+ case '}':
+ case '\\':
+ case '+': // habe ich in einem RTF-File gefunden
+ case '~': // nonbreaking space
+ case '-': // optional hyphen
+ case '_': // nonbreaking hyphen
+ case '\'': // HexValue
+ nNextCh = '\\';
+ rInput.SeekRel( -1 );
+ ScanText();
+ nRet = RTF_TEXTTOKEN;
+ bNextCh = 0 == nNextCh;
+ break;
+
+ case '*': // ignoreflag
+ nRet = RTF_IGNOREFLAG;
+ break;
+ case ':': // subentry in an index entry
+ nRet = RTF_SUBENTRYINDEX;
+ break;
+ case '|': // formula-charakter
+ nRet = RTF_FORMULA;
+ break;
+
+ case 0x0a:
+ case 0x0d:
+ nRet = RTF_PAR;
+ break;
+
+ default:
+ if( RTF_ISALPHA( nNextCh ) )
+ {
+ aToken = '\\';
+ {
+ String aStrBuffer;
+ sal_Unicode* pStr = aStrBuffer.AllocBuffer(
+ MAX_TOKEN_LEN );
+ xub_StrLen nStrLen = 0;
+ do {
+ *(pStr + nStrLen++) = nNextCh;
+ if( MAX_TOKEN_LEN == nStrLen )
+ {
+ aToken += aStrBuffer;
+ aToken.GetBufferAccess(); // make unique string!
+ nStrLen = 0;
+ }
+ nNextCh = GetNextChar();
+ } while( RTF_ISALPHA( nNextCh ) );
+ if( nStrLen )
+ {
+ aStrBuffer.ReleaseBufferAccess( nStrLen );
+ aToken += aStrBuffer;
+ }
+ }
+
+ // Minus fuer numerischen Parameter
+ int bNegValue = false;
+ if( '-' == nNextCh )
+ {
+ bNegValue = true;
+ nNextCh = GetNextChar();
+ }
+
+ // evt. Numerischer Parameter
+ if( RTF_ISDIGIT( nNextCh ) )
+ {
+ nTokenValue = 0;
+ do {
+ nTokenValue *= 10;
+ nTokenValue += nNextCh - '0';
+ nNextCh = GetNextChar();
+ } while( RTF_ISDIGIT( nNextCh ) );
+ if( bNegValue )
+ nTokenValue = -nTokenValue;
+ bTokenHasValue=true;
+ }
+ else if( bNegValue ) // das Minus wieder zurueck
+ {
+ nNextCh = '-';
+ rInput.SeekRel( -1 );
+ }
+ if( ' ' == nNextCh ) // Blank gehoert zum Token!
+ nNextCh = GetNextChar();
+
+ // suche das Token in der Tabelle:
+ if( 0 == (nRet = GetRTFToken( aToken )) )
+ // Unknown Control
+ nRet = RTF_UNKNOWNCONTROL;
+
+ // bug 76812 - unicode token handled as normal text
+ bNextCh = false;
+ switch( nRet )
+ {
+ case RTF_UC:
+ if( 0 <= nTokenValue )
+ {
+ nUCharOverread = (BYTE)nTokenValue;
+#if 1
+ //cmc: other ifdef breaks #i3584
+ aParserStates[ aParserStates.Count()-1].
+ nUCharOverread = nUCharOverread;
+#else
+ if( !nUCharOverread )
+ nUCharOverread = aParserStates[
+ aParserStates.Count()-1].nUCharOverread;
+ else
+ aParserStates[ aParserStates.Count()-1].
+ nUCharOverread = nUCharOverread;
+#endif
+ }
+ aToken.Erase(); // #i47831# erase token to prevent the token from beeing treated as text
+ // read next token
+ nRet = 0;
+ break;
+
+ case RTF_UPR:
+ if (!_inSkipGroup) {
+ // UPR - overread the group with the ansi
+ // informations
+ while( '{' != _GetNextToken() )
+ ;
+ SkipGroup();
+ _GetNextToken(); // overread the last bracket
+ nRet = 0;
+ }
+ break;
+
+ case RTF_U:
+ if( !bRTF_InTextRead )
+ {
+ nRet = RTF_TEXTTOKEN;
+ aToken = (sal_Unicode)nTokenValue;
+
+ // overread the next n "RTF" characters. This
+ // can be also \{, \}, \'88
+ for( BYTE m = 0; m < nUCharOverread; ++m )
+ {
+ sal_Unicode cAnsi = nNextCh;
+ while( 0xD == cAnsi )
+ cAnsi = GetNextChar();
+ while( 0xA == cAnsi )
+ cAnsi = GetNextChar();
+
+ if( '\\' == cAnsi &&
+ '\'' == ( cAnsi = GetNextChar() ))
+ // HexValue ueberlesen
+ cAnsi = GetHexValue();
+ nNextCh = GetNextChar();
+ }
+ ScanText();
+ bNextCh = 0 == nNextCh;
+ }
+ break;
+ }
+ }
+ else if( SVPAR_PENDING != eState )
+ {
+ // Bug 34631 - "\ " ueberlesen - Blank als Zeichen
+ // eState = SVPAR_ERROR;
+ bNextCh = false;
+ }
+ break;
+ }
+ }
+ break;
+
+ case sal_Unicode(EOF):
+ eState = SVPAR_ACCEPTED;
+ nRet = nNextCh;
+ break;
+
+ case '{':
+ {
+ if( 0 <= nOpenBrakets )
+ {
+ RtfParserState_Impl aState( nUCharOverread, GetSrcEncoding() );
+ aParserStates.Insert(
+ aState, sal::static_int_cast< USHORT >(nOpenBrakets) );
+ }
+ ++nOpenBrakets;
+ DBG_ASSERT( nOpenBrakets == aParserStates.Count(),
+ "ParserStateStack unequal to bracket count" );
+ nRet = nNextCh;
+ }
+ break;
+
+ case '}':
+ --nOpenBrakets;
+ if( 0 <= nOpenBrakets )
+ {
+ aParserStates.Remove(
+ sal::static_int_cast< USHORT >(nOpenBrakets) );
+ if( aParserStates.Count() )
+ {
+ const RtfParserState_Impl& rRPS =
+ aParserStates[ aParserStates.Count() - 1 ];
+ nUCharOverread = rRPS.nUCharOverread;
+ SetSrcEncoding( rRPS.eCodeSet );
+ }
+ else
+ {
+ nUCharOverread = 1;
+ SetSrcEncoding( GetCodeSet() );
+ }
+ }
+ DBG_ASSERT( nOpenBrakets == aParserStates.Count(),
+ "ParserStateStack unequal to bracket count" );
+ nRet = nNextCh;
+ break;
+
+ case 0x0d:
+ case 0x0a:
+ break;
+
+ default:
+ // es folgt normaler Text
+ ScanText();
+ nRet = RTF_TEXTTOKEN;
+ bNextCh = 0 == nNextCh;
+ break;
+ }
+
+ if( bNextCh )
+ nNextCh = GetNextChar();
+
+ } while( !nRet && SVPAR_WORKING == eState );
+ return nRet;
+}
+
+
+sal_Unicode SvRTFParser::GetHexValue()
+{
+ // Hex-Wert sammeln
+ register int n;
+ register sal_Unicode nHexVal = 0;
+
+ for( n = 0; n < 2; ++n )
+ {
+ nHexVal *= 16;
+ nNextCh = GetNextChar();
+ if( nNextCh >= '0' && nNextCh <= '9' )
+ nHexVal += (nNextCh - 48);
+ else if( nNextCh >= 'a' && nNextCh <= 'f' )
+ nHexVal += (nNextCh - 87);
+ else if( nNextCh >= 'A' && nNextCh <= 'F' )
+ nHexVal += (nNextCh - 55);
+ }
+ return nHexVal;
+}
+
+void SvRTFParser::ScanText( const sal_Unicode cBreak )
+{
+ String aStrBuffer;
+ int bWeiter = true;
+ while( bWeiter && IsParserWorking() && aStrBuffer.Len() < MAX_STRING_LEN)
+ {
+ int bNextCh = true;
+ switch( nNextCh )
+ {
+ case '\\':
+ {
+ switch (nNextCh = GetNextChar())
+ {
+ case '\'':
+ {
+
+#if 0
+ // #i35653 patch from cmc
+ ByteString aByteString(static_cast<char>(GetHexValue()));
+ if (aByteString.Len())
+ aStrBuffer.Append(String(aByteString, GetSrcEncoding()));
+#else
+ ByteString aByteString;
+ while (1)
+ {
+ aByteString.Append((char)GetHexValue());
+
+ bool bBreak = false;
+ sal_Char nSlash = '\\';
+ while (!bBreak)
+ {
+ wchar_t __next=GetNextChar();
+ if (__next>0xFF) // fix for #i43933# and #i35653#
+ {
+ if (aByteString.Len())
+ aStrBuffer.Append(String(aByteString, GetSrcEncoding()));
+ aStrBuffer.Append((sal_Unicode)__next);
+
+ aByteString.Erase();
+ continue;
+ }
+ nSlash = (sal_Char)__next;
+ while (nSlash == 0xD || nSlash == 0xA)
+ nSlash = (sal_Char)GetNextChar();
+
+ switch (nSlash)
+ {
+ case '{':
+ case '}':
+ case '\\':
+ bBreak = true;
+ break;
+ default:
+ aByteString.Append(nSlash);
+ break;
+ }
+ }
+
+ nNextCh = GetNextChar();
+
+ if (nSlash != '\\' || nNextCh != '\'')
+ {
+ rInput.SeekRel(-1);
+ nNextCh = nSlash;
+ break;
+ }
+ }
+
+ bNextCh = false;
+
+ if (aByteString.Len())
+ aStrBuffer.Append(String(aByteString, GetSrcEncoding()));
+#endif
+ }
+ break;
+ case '\\':
+ case '}':
+ case '{':
+ case '+': // habe ich in einem RTF-File gefunden
+ aStrBuffer.Append(nNextCh);
+ break;
+ case '~': // nonbreaking space
+ aStrBuffer.Append(static_cast< sal_Unicode >(0xA0));
+ break;
+ case '-': // optional hyphen
+ aStrBuffer.Append(static_cast< sal_Unicode >(0xAD));
+ break;
+ case '_': // nonbreaking hyphen
+ aStrBuffer.Append(static_cast< sal_Unicode >(0x2011));
+ break;
+
+ case 'u':
+ // UNI-Code Zeichen lesen
+ {
+ nNextCh = GetNextChar();
+ rInput.SeekRel( -2 );
+
+ if( '-' == nNextCh || RTF_ISDIGIT( nNextCh ) )
+ {
+ bRTF_InTextRead = true;
+
+ String sSave( aToken );
+ nNextCh = '\\';
+ #ifdef DBG_UTIL
+ int nToken =
+ #endif
+ _GetNextToken();
+ DBG_ASSERT( RTF_U == nToken, "doch kein UNI-Code Zeichen" );
+ // dont convert symbol chars
+ aStrBuffer.Append(
+ static_cast< sal_Unicode >(nTokenValue));
+
+ // overread the next n "RTF" characters. This
+ // can be also \{, \}, \'88
+ for( BYTE m = 0; m < nUCharOverread; ++m )
+ {
+ sal_Unicode cAnsi = nNextCh;
+ while( 0xD == cAnsi )
+ cAnsi = GetNextChar();
+ while( 0xA == cAnsi )
+ cAnsi = GetNextChar();
+
+ if( '\\' == cAnsi &&
+ '\'' == ( cAnsi = GetNextChar() ))
+ // HexValue ueberlesen
+ cAnsi = GetHexValue();
+ nNextCh = GetNextChar();
+ }
+ bNextCh = false;
+ aToken = sSave;
+ bRTF_InTextRead = false;
+ }
+ else
+ {
+ nNextCh = '\\';
+ bWeiter = false; // Abbrechen, String zusammen
+ }
+ }
+ break;
+
+ default:
+ rInput.SeekRel( -1 );
+ nNextCh = '\\';
+ bWeiter = false; // Abbrechen, String zusammen
+ break;
+ }
+ }
+ break;
+
+ case sal_Unicode(EOF):
+ eState = SVPAR_ERROR;
+ // weiter
+ case '{':
+ case '}':
+ bWeiter = false;
+ break;
+
+ case 0x0a:
+ case 0x0d:
+ break;
+
+ default:
+ if( nNextCh == cBreak || aStrBuffer.Len() >= MAX_STRING_LEN)
+ bWeiter = false;
+ else
+ {
+ do {
+ // alle anderen Zeichen kommen in den Text
+ aStrBuffer.Append(nNextCh);
+
+ if (sal_Unicode(EOF) == (nNextCh = GetNextChar()))
+ {
+ if (aStrBuffer.Len())
+ aToken += aStrBuffer;
+ return;
+ }
+ } while
+ (
+ (RTF_ISALPHA(nNextCh) || RTF_ISDIGIT(nNextCh)) &&
+ (aStrBuffer.Len() < MAX_STRING_LEN)
+ );
+ bNextCh = false;
+ }
+ }
+
+ if( bWeiter && bNextCh )
+ nNextCh = GetNextChar();
+ }
+
+ if (aStrBuffer.Len())
+ aToken += aStrBuffer;
+}
+
+
+short SvRTFParser::_inSkipGroup=0;
+
+void SvRTFParser::SkipGroup()
+{
+short nBrackets=1;
+if (_inSkipGroup>0)
+ return;
+_inSkipGroup++;
+#if 1 //#i16185# fecking \bin keyword
+ do
+ {
+ switch (nNextCh)
+ {
+ case '{':
+ ++nBrackets;
+ break;
+ case '}':
+ if (!--nBrackets) {
+ _inSkipGroup--;
+ return;
+ }
+ break;
+ }
+ int nToken = _GetNextToken();
+ if (nToken == RTF_BIN)
+ {
+ rInput.SeekRel(-1);
+ rInput.SeekRel(nTokenValue);
+ nNextCh = GetNextChar();
+ }
+ while (nNextCh==0xa || nNextCh==0xd)
+ {
+ nNextCh = GetNextChar();
+ }
+ } while (sal_Unicode(EOF) != nNextCh && IsParserWorking());
+#else
+ sal_Unicode cPrev = 0;
+ do {
+ switch( nNextCh )
+ {
+ case '{':
+ if( '\\' != cPrev )
+ ++nBrackets;
+ break;
+
+ case '}':
+ if( '\\' != cPrev && !--nBrackets )
+ return;
+ break;
+
+ case '\\':
+ if( '\\' == cPrev )
+ nNextCh = 0;
+ break;
+ }
+ cPrev = nNextCh;
+ nNextCh = GetNextChar();
+ } while( sal_Unicode(EOF) != nNextCh && IsParserWorking() );
+#endif
+
+ if( SVPAR_PENDING != eState && '}' != nNextCh )
+ eState = SVPAR_ERROR;
+ _inSkipGroup--;
+}
+
+void SvRTFParser::ReadUnknownData() { SkipGroup(); }
+void SvRTFParser::ReadBitmapData() { SkipGroup(); }
+void SvRTFParser::ReadOLEData() { SkipGroup(); }
+
+
+SvParserState SvRTFParser::CallParser()
+{
+ sal_Char cFirstCh;
+ nNextChPos = rInput.Tell();
+ rInput >> cFirstCh; nNextCh = cFirstCh;
+ eState = SVPAR_WORKING;
+ nOpenBrakets = 0;
+ SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_MS_1252 );
+ eUNICodeSet = RTL_TEXTENCODING_MS_1252; // default ist ANSI-CodeSet
+
+ // die 1. beiden Token muessen '{' und \\rtf sein !!
+ if( '{' == GetNextToken() && RTF_RTF == GetNextToken() )
+ {
+ AddRef();
+ Continue( 0 );
+ if( SVPAR_PENDING != eState )
+ ReleaseRef(); // dann brauchen wir den Parser nicht mehr!
+ }
+ else
+ eState = SVPAR_ERROR;
+
+ return eState;
+}
+
+void SvRTFParser::Continue( int nToken )
+{
+// DBG_ASSERT( SVPAR_CS_DONTKNOW == GetCharSet(),
+// "Zeichensatz wurde geaendert." );
+
+ if( !nToken )
+ nToken = GetNextToken();
+
+ while( IsParserWorking() )
+ {
+ SaveState( nToken );
+ switch( nToken )
+ {
+ case '}':
+ if( nOpenBrakets )
+ goto NEXTTOKEN;
+ eState = SVPAR_ACCEPTED;
+ break;
+
+ case '{':
+ // eine unbekannte Gruppe ?
+ {
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nToken = SkipToken( -1 );
+ else if( RTF_UNKNOWNCONTROL != GetNextToken() )
+ nToken = SkipToken( -2 );
+ else
+ {
+ // gleich herausfiltern
+ ReadUnknownData();
+ nToken = GetNextToken();
+ if( '}' != nToken )
+ eState = SVPAR_ERROR;
+ break; // auf zum naechsten Token!!
+ }
+ }
+ goto NEXTTOKEN;
+
+ case RTF_UNKNOWNCONTROL:
+ break; // unbekannte Token ueberspringen
+ case RTF_NEXTTYPE:
+ case RTF_ANSITYPE:
+ SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_MS_1252 );
+ break;
+ case RTF_MACTYPE:
+ SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_APPLE_ROMAN );
+ break;
+ case RTF_PCTYPE:
+ SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_IBM_437 );
+ break;
+ case RTF_PCATYPE:
+ SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_IBM_850 );
+ break;
+ case RTF_ANSICPG:
+ eCodeSet = rtl_getTextEncodingFromWindowsCodePage(nTokenValue);
+ SetSrcEncoding(eCodeSet);
+ break;
+ default:
+NEXTTOKEN:
+ NextToken( nToken );
+ break;
+ }
+ if( IsParserWorking() )
+ SaveState( 0 ); // bis hierhin abgearbeitet,
+ // weiter mit neuem Token!
+ nToken = GetNextToken();
+ }
+ if( SVPAR_ACCEPTED == eState && 0 < nOpenBrakets )
+ eState = SVPAR_ERROR;
+}
+
+void SvRTFParser::SetEncoding( rtl_TextEncoding eEnc )
+{
+ if (eEnc == RTL_TEXTENCODING_DONTKNOW)
+ eEnc = GetCodeSet();
+
+ if (aParserStates.Count())
+ aParserStates[aParserStates.Count() - 1].eCodeSet = eEnc;
+ SetSrcEncoding(eEnc);
+}
+
+#ifdef USED
+void SvRTFParser::SaveState( int nToken )
+{
+ SvParser::SaveState( nToken );
+}
+
+void SvRTFParser::RestoreState()
+{
+ SvParser::RestoreState();
+}
+#endif
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/svtools/source/svrtf/rtfkey2.cxx b/svtools/source/svrtf/rtfkey2.cxx
new file mode 100644
index 000000000000..03a7667f48e2
--- /dev/null
+++ b/svtools/source/svrtf/rtfkey2.cxx
@@ -0,0 +1,1159 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include "rtfkeywd.hxx"
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEXCHAR, "\\'" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_IGNORE, "\\*" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OPTHYPH, "\\-" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBENTRY, "\\:" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSH, "\\absh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSW, "\\absw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ALT, "\\alt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANNOTATION, "\\annotation" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANSI, "\\ansi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNID, "\\atnid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AUTHOR, "\\author" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_B, "\\b" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGBDIAG, "\\bgbdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGCROSS, "\\bgcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDCROSS, "\\bgdcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKBDIAG, "\\bgdkbdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKCROSS, "\\bgdkcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKDCROSS, "\\bgdkdcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKFDIAG, "\\bgdkfdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKHORIZ, "\\bgdkhoriz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKVERT, "\\bgdkvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGFDIAG, "\\bgfdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGHORIZ, "\\bghoriz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGVERT, "\\bgvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BIN, "\\bin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BINFSXN, "\\binfsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BINSXN, "\\binsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKCOLF, "\\bkmkcolf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKCOLL, "\\bkmkcoll" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKEND, "\\bkmkend" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKSTART, "\\bkmkstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLUE, "\\blue" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BOX, "\\box" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRB, "\\brdrb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRBAR, "\\brdrbar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRBTW, "\\brdrbtw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRCF, "\\brdrcf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDB, "\\brdrdb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDOT, "\\brdrdot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRHAIR, "\\brdrhair" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRL, "\\brdrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRR, "\\brdrr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRS, "\\brdrs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRSH, "\\brdrsh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRT, "\\brdrt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTH, "\\brdrth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRW, "\\brdrw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRSP, "\\brsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BULLET, "\\bullet" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BUPTIM, "\\buptim" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BXE, "\\bxe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CAPS, "\\caps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CB, "\\cb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CBPAT, "\\cbpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CELL, "\\cell" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CELLX, "\\cellx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CF, "\\cf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CFPAT, "\\cfpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHATN, "\\chatn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHDATE, "\\chdate" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHDPA, "\\chdpa" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHDPL, "\\chdpl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHFTN, "\\chftn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHFTNSEP, "\\chftnsep" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHFTNSEPC, "\\chftnsepc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHPGN, "\\chpgn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHTIME, "\\chtime" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGBDIAG, "\\clbgbdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGCROSS, "\\clbgcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDCROSS, "\\clbgdcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKBDIAG, "\\clbgdkbdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKCROSS, "\\clbgdkcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKDCROSS, "\\clbgdkdcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKFDIAG, "\\clbgdkfdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKHOR, "\\clbgdkhor" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKVERT, "\\clbgdkvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGFDIAG, "\\clbgfdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGHORIZ, "\\clbghoriz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGVERT, "\\clbgvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRB, "\\clbrdrb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRL, "\\clbrdrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRR, "\\clbrdrr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRT, "\\clbrdrt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLCBPAT, "\\clcbpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLCFPAT, "\\clcfpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLMGF, "\\clmgf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLMRG, "\\clmrg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLSHDNG, "\\clshdng" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLNO, "\\colno" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLORTBL, "\\colortbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLS, "\\cols" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLSR, "\\colsr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLSX, "\\colsx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLUMN, "\\column" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLW, "\\colw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COMMENT, "\\comment" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CREATIM, "\\creatim" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CTRL, "\\ctrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFF, "\\deff" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFFORMAT, "\\defformat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFLANG, "\\deflang" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFTAB, "\\deftab" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DELETED, "\\deleted" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTX, "\\dfrmtxtx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTY, "\\dfrmtxty" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DIBITMAP, "\\dibitmap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DN, "\\dn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCCOMM, "\\doccomm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCTEMP, "\\doctemp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DROPCAPLI, "\\dropcapli" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DROPCAPT, "\\dropcapt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSNOOVRLP, "\\absnoovrlp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DXFRTEXT, "\\dxfrtext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DY, "\\dy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EDMINS, "\\edmins" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMDASH, "\\emdash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDASH, "\\endash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDDOC, "\\enddoc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDNHERE, "\\endnhere" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDNOTES, "\\endnotes" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EXPND, "\\expnd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EXPNDTW, "\\expndtw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_F, "\\f" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FACINGP, "\\facingp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FACPGSXN, "\\facpgsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FALT, "\\falt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FCHARSET, "\\fcharset" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FDECOR, "\\fdecor" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FI, "\\fi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FIELD, "\\field" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDDIRTY, "\\flddirty" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDEDIT, "\\fldedit" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDINST, "\\fldinst" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDLOCK, "\\fldlock" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDPRIV, "\\fldpriv" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDRSLT, "\\fldrslt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FMODERN, "\\fmodern" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FN, "\\fn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FNIL, "\\fnil" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FONTTBL, "\\fonttbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTER, "\\footer" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERF, "\\footerf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERL, "\\footerl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERR, "\\footerr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERY, "\\footery" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTNOTE, "\\footnote" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FPRQ, "\\fprq" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRACWIDTH, "\\fracwidth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FROMAN, "\\froman" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FS, "\\fs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FSCRIPT, "\\fscript" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FSWISS, "\\fswiss" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTECH, "\\ftech" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNBJ, "\\ftnbj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNCN, "\\ftncn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNRESTART, "\\ftnrestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNSEP, "\\ftnsep" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNSEPC, "\\ftnsepc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNSTART, "\\ftnstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNTJ, "\\ftntj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GREEN, "\\green" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GUTTER, "\\gutter" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GUTTERSXN, "\\guttersxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADER, "\\header" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERF, "\\headerf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERL, "\\headerl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERR, "\\headerr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERY, "\\headery" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HR, "\\hr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHHOTZ, "\\hyphhotz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_I, "\\i" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ID, "\\id" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_INFO, "\\info" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_INTBL, "\\intbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_IXE, "\\ixe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEEP, "\\keep" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEEPN, "\\keepn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KERNING, "\\kerning" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEYCODE, "\\keycode" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEYWORDS, "\\keywords" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LANDSCAPE, "\\landscape" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LANG, "\\lang" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LDBLQUOTE, "\\ldblquote" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVEL, "\\level" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LI, "\\li" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LIN, "\\lin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINE, "\\line" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEBETCOL, "\\linebetcol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINECONT, "\\linecont" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEMOD, "\\linemod" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEPPAGE, "\\lineppage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINERESTART, "\\linerestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINESTART, "\\linestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINESTARTS, "\\linestarts" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEX, "\\linex" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LNDSCPSXN, "\\lndscpsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LQUOTE, "\\lquote" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MAC, "\\mac" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MACPICT, "\\macpict" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MAKEBACKUP, "\\makebackup" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGB, "\\margb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGBSXN, "\\margbsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGL, "\\margl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGLSXN, "\\marglsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGMIRROR, "\\margmirror" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGR, "\\margr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGRSXN, "\\margrsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGT, "\\margt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGTSXN, "\\margtsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MIN, "\\min" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MO, "\\mo" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NEXTCSET, "\\nextcset" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NEXTFILE, "\\nextfile" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFCHARS, "\\nofchars" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFPAGES, "\\nofpages" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFWORDS, "\\nofwords" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOLINE, "\\noline" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSUPERSUB, "\\nosupersub" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOWRAP, "\\nowrap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OPERATOR, "\\operator" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OUTL, "\\outl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAGE, "\\page" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAGEBB, "\\pagebb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAPERH, "\\paperh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAPERW, "\\paperw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAR, "\\par" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PARD, "\\pard" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PC, "\\pc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PCA, "\\pca" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGHSXN, "\\pghsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNCONT, "\\pgncont" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNDEC, "\\pgndec" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNLCLTR, "\\pgnlcltr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNLCRM, "\\pgnlcrm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNRESTART, "\\pgnrestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNSTART, "\\pgnstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNSTARTS, "\\pgnstarts" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNUCLTR, "\\pgnucltr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNUCRM, "\\pgnucrm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNX, "\\pgnx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNY, "\\pgny" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGWSXN, "\\pgwsxn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PHCOL, "\\phcol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PHMRG, "\\phmrg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PHPG, "\\phpg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPB, "\\piccropb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPL, "\\piccropl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPR, "\\piccropr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPT, "\\piccropt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICH, "\\pich" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICHGOAL, "\\pichgoal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICSCALED, "\\picscaled" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICSCALEX, "\\picscalex" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICSCALEY, "\\picscaley" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICT, "\\pict" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICW, "\\picw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICWGOAL, "\\picwgoal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PLAIN, "\\plain" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PMMETAFILE, "\\pmmetafile" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSNEGX, "\\posnegx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSNEGY, "\\posnegy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSX, "\\posx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXC, "\\posxc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXI, "\\posxi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXL, "\\posxl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXO, "\\posxo" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXR, "\\posxr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSY, "\\posy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYB, "\\posyb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYC, "\\posyc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYIL, "\\posyil" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYT, "\\posyt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRINTIM, "\\printim" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PSOVER, "\\psover" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PVMRG, "\\pvmrg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PVPARA, "\\pvpara" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PVPG, "\\pvpg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QC, "\\qc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QJ, "\\qj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QL, "\\ql" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QR, "\\qr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RDBLQUOTE, "\\rdblquote" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RED, "\\red" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVBAR, "\\revbar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVISED, "\\revised" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVISIONS, "\\revisions" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVPROP, "\\revprop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVTIM, "\\revtim" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RI, "\\ri" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RIN, "\\rin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ROW, "\\row" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RQUOTE, "\\rquote" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTF, "\\rtf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RXE, "\\rxe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_S, "\\s" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SA, "\\sa" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SB, "\\sb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBASEDON, "\\sbasedon" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKCOL, "\\sbkcol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKEVEN, "\\sbkeven" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKNONE, "\\sbknone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKODD, "\\sbkodd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKPAGE, "\\sbkpage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBYS, "\\sbys" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SCAPS, "\\scaps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECT, "\\sect" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTD, "\\sectd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHAD, "\\shad" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHADING, "\\shading" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHIFT, "\\shift" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SL, "\\sl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SNEXT, "\\snext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STRIKE, "\\strike" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STYLESHEET, "\\stylesheet" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUB, "\\sub" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBJECT, "\\subject" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUPER, "\\super" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TAB, "\\tab" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TB, "\\tb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TC, "\\tc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCF, "\\tcf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCL, "\\tcl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TEMPLATE, "\\template" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TITLE, "\\title" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TITLEPG, "\\titlepg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLDOT, "\\tldot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLEQ, "\\tleq" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLHYPH, "\\tlhyph" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLTH, "\\tlth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLUL, "\\tlul" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQC, "\\tqc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQDEC, "\\tqdec" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQR, "\\tqr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQL, "\\tql" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRGAPH, "\\trgaph" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRLEFT, "\\trleft" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TROWD, "\\trowd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRQC, "\\trqc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRQL, "\\trql" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRQR, "\\trqr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRRH, "\\trrh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TX, "\\tx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TXE, "\\txe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UL, "\\ul" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULD, "\\uld" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDB, "\\uldb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULNONE, "\\ulnone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULW, "\\ulw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UP, "\\up" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_V, "\\v" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERN, "\\vern" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERSION, "\\version" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALB, "\\vertalb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALC, "\\vertalc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALJ, "\\vertalj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALT, "\\vertalt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBITMAP, "\\wbitmap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBMBITSPIXEL, "\\wbmbitspixel" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBMPLANES, "\\wbmplanes" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBMWIDTHBYTES, "\\wbmwidthbytes" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WIDOWCTRL, "\\widowctrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WMETAFILE, "\\wmetafile" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_XE, "\\xe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_YR, "\\yr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOBRKHYPH, "\\_" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMULA, "\\|" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOBREAK, "\\~" );
+
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AB, "\\ab" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACAPS, "\\acaps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACF, "\\acf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADDITIVE, "\\additive" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADN, "\\adn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AENDDOC, "\\aenddoc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AENDNOTES, "\\aendnotes" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AEXPND, "\\aexpnd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AF, "\\af" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFS, "\\afs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNBJ, "\\aftnbj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNCN, "\\aftncn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNALC, "\\aftnnalc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNAR, "\\aftnnar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNAUC, "\\aftnnauc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNCHI, "\\aftnnchi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNRLC, "\\aftnnrlc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNRUC, "\\aftnnruc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNRESTART, "\\aftnrestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNRSTCONT, "\\aftnrstcont" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNSEP, "\\aftnsep" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNSEPC, "\\aftnsepc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNSTART, "\\aftnstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNTJ, "\\aftntj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AI, "\\ai" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ALANG, "\\alang" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ALLPROT, "\\allprot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANNOTPROT, "\\annotprot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AOUTL, "\\aoutl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASCAPS, "\\ascaps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASHAD, "\\ashad" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASTRIKE, "\\astrike" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNAUTHOR, "\\atnauthor" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNICN, "\\atnicn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNREF, "\\atnref" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNTIME, "\\atntime" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATRFEND, "\\atrfend" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATRFSTART, "\\atrfstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AUL, "\\aul" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULD, "\\auld" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULDB, "\\auldb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULNONE, "\\aulnone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULW, "\\aulw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AUP, "\\aup" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKPUB, "\\bkmkpub" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASH, "\\brdrdash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRKFRM, "\\brkfrm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CCHS, "\\cchs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CPG, "\\cpg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CS, "\\cs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CVMME, "\\cvmme" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DATAFIELD, "\\datafield" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DO, "\\do" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBXCOLUMN, "\\dobxcolumn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBXMARGIN, "\\dobxmargin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBXPAGE, "\\dobxpage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBYMARGIN, "\\dobymargin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBYPAGE, "\\dobypage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBYPARA, "\\dobypara" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DODHGT, "\\dodhgt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOLOCK, "\\dolock" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDHOL, "\\dpaendhol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDL, "\\dpaendl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDSOL, "\\dpaendsol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDW, "\\dpaendw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPARC, "\\dparc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPARCFLIPX, "\\dparcflipx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPARCFLIPY, "\\dparcflipy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTHOL, "\\dpastarthol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTL, "\\dpastartl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTSOL, "\\dpastartsol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTW, "\\dpastartw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCALLOUT, "\\dpcallout" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOA, "\\dpcoa" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOACCENT, "\\dpcoaccent" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOBESTFIT, "\\dpcobestfit" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOBORDER, "\\dpcoborder" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODABS, "\\dpcodabs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODBOTTOM, "\\dpcodbottom" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODCENTER, "\\dpcodcenter" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODTOP, "\\dpcodtop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOLENGTH, "\\dpcolength" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOMINUSX, "\\dpcominusx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOMINUSY, "\\dpcominusy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOOFFSET, "\\dpcooffset" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOSMARTA, "\\dpcosmarta" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTDOUBLE, "\\dpcotdouble" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTRIGHT, "\\dpcotright" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTSINGLE, "\\dpcotsingle" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTTRIPLE, "\\dpcottriple" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOUNT, "\\dpcount" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPELLIPSE, "\\dpellipse" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPENDGROUP, "\\dpendgroup" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGCB, "\\dpfillbgcb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGCG, "\\dpfillbgcg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGCR, "\\dpfillbgcr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGGRAY, "\\dpfillbggray" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGPAL, "\\dpfillbgpal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGCB, "\\dpfillfgcb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGCG, "\\dpfillfgcg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGCR, "\\dpfillfgcr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGGRAY, "\\dpfillfggray" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGPAL, "\\dpfillfgpal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLPAT, "\\dpfillpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPGROUP, "\\dpgroup" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINE, "\\dpline" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINECOB, "\\dplinecob" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINECOG, "\\dplinecog" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINECOR, "\\dplinecor" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDADO, "\\dplinedado" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDADODO, "\\dplinedadodo" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDASH, "\\dplinedash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDOT, "\\dplinedot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEGRAY, "\\dplinegray" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEHOLLOW, "\\dplinehollow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEPAL, "\\dplinepal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINESOLID, "\\dplinesolid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEW, "\\dplinew" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPOLYCOUNT, "\\dppolycount" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPOLYGON, "\\dppolygon" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPOLYLINE, "\\dppolyline" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPTX, "\\dpptx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPTY, "\\dppty" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPRECT, "\\dprect" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPROUNDR, "\\dproundr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPSHADOW, "\\dpshadow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPSHADX, "\\dpshadx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPSHADY, "\\dpshady" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPTXBX, "\\dptxbx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPTXBXMAR, "\\dptxbxmar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPTXBXTEXT, "\\dptxbxtext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPX, "\\dpx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPXSIZE, "\\dpxsize" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPY, "\\dpy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPYSIZE, "\\dpysize" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DS, "\\ds" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMSPACE, "\\emspace" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENSPACE, "\\enspace" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FBIDI, "\\fbidi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FET, "\\fet" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FID, "\\fid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FILE, "\\file" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FILETBL, "\\filetbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDALT, "\\fldalt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FNETWORK, "\\fnetwork" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FONTEMB, "\\fontemb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FONTFILE, "\\fontfile" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMDISP, "\\formdisp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMPROT, "\\formprot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMSHADE, "\\formshade" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOSNUM, "\\fosnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRELATIVE, "\\frelative" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNALT, "\\ftnalt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNIL, "\\ftnil" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNALC, "\\ftnnalc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNAR, "\\ftnnar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNAUC, "\\ftnnauc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNCHI, "\\ftnnchi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNRLC, "\\ftnnrlc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNRUC, "\\ftnnruc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNRSTCONT, "\\ftnrstcont" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNRSTPG, "\\ftnrstpg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTTRUETYPE, "\\fttruetype" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDDOS, "\\fvaliddos" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDHPFS, "\\fvalidhpfs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDMAC, "\\fvalidmac" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDNTFS, "\\fvalidntfs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHAUTO, "\\hyphauto" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHCAPS, "\\hyphcaps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHCONSEC, "\\hyphconsec" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHPAR, "\\hyphpar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINKSELF, "\\linkself" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINKSTYLES, "\\linkstyles" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRCH, "\\ltrch" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRDOC, "\\ltrdoc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRMARK, "\\ltrmark" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRPAR, "\\ltrpar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRROW, "\\ltrrow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRSECT, "\\ltrsect" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOCOLBAL, "\\nocolbal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOEXTRASPRL, "\\noextrasprl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOTABIND, "\\notabind" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOWIDCTLPAR, "\\nowidctlpar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJALIAS, "\\objalias" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJALIGN, "\\objalign" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJAUTLINK, "\\objautlink" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCLASS, "\\objclass" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPB, "\\objcropb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPL, "\\objcropl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPR, "\\objcropr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPT, "\\objcropt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJDATA, "\\objdata" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJECT, "\\object" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJEMB, "\\objemb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJH, "\\objh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJICEMB, "\\objicemb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJLINK, "\\objlink" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJLOCK, "\\objlock" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJNAME, "\\objname" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJPUB, "\\objpub" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSCALEX, "\\objscalex" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSCALEY, "\\objscaley" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSECT, "\\objsect" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSETSIZE, "\\objsetsize" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSUB, "\\objsub" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJTIME, "\\objtime" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJTRANSY, "\\objtransy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJUPDATE, "\\objupdate" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJW, "\\objw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OTBLRUL, "\\otblrul" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHN, "\\pgnhn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSC, "\\pgnhnsc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSH, "\\pgnhnsh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSM, "\\pgnhnsm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSN, "\\pgnhnsn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSP, "\\pgnhnsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICBMP, "\\picbmp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICBPP, "\\picbpp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PN, "\\pn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNACROSS, "\\pnacross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNB, "\\pnb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCAPS, "\\pncaps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCARD, "\\pncard" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCF, "\\pncf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDEC, "\\pndec" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNF, "\\pnf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNFS, "\\pnfs" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNHANG, "\\pnhang" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNI, "\\pni" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNINDENT, "\\pnindent" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLCLTR, "\\pnlcltr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLCRM, "\\pnlcrm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVL, "\\pnlvl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVLBLT, "\\pnlvlblt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVLBODY, "\\pnlvlbody" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVLCONT, "\\pnlvlcont" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNNUMONCE, "\\pnnumonce" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNORD, "\\pnord" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNORDT, "\\pnordt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNPREV, "\\pnprev" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNQC, "\\pnqc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNQL, "\\pnql" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNQR, "\\pnqr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRESTART, "\\pnrestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSCAPS, "\\pnscaps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSECLVL, "\\pnseclvl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSP, "\\pnsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSTART, "\\pnstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSTRIKE, "\\pnstrike" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNTEXT, "\\pntext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNTXTA, "\\pntxta" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNTXTB, "\\pntxtb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNUCLTR, "\\pnucltr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNUCRM, "\\pnucrm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNUL, "\\pnul" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULD, "\\pnuld" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULDB, "\\pnuldb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULNONE, "\\pnulnone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULW, "\\pnulw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRCOLBL, "\\prcolbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRINTDATA, "\\printdata" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PSZ, "\\psz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PUBAUTO, "\\pubauto" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RESULT, "\\result" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVAUTH, "\\revauth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVDTTM, "\\revdttm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVPROT, "\\revprot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVTBL, "\\revtbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTBMP, "\\rsltbmp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTMERGE, "\\rsltmerge" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTPICT, "\\rsltpict" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTRTF, "\\rsltrtf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTTXT, "\\rslttxt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLCH, "\\rtlch" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLDOC, "\\rtldoc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLMARK, "\\rtlmark" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLPAR, "\\rtlpar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLROW, "\\rtlrow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLSECT, "\\rtlsect" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SEC, "\\sec" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTNUM, "\\sectnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTUNLOCKED, "\\sectunlocked" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SLMULT, "\\slmult" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTCOL, "\\softcol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTLHEIGHT, "\\softlheight" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTLINE, "\\softline" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTPAGE, "\\softpage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSSPBF, "\\sprsspbf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSTSP, "\\sprstsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBDOCUMENT, "\\subdocument" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SWPBDR, "\\swpbdr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCN, "\\tcn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRANSMF, "\\transmf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRB, "\\trbrdrb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRH, "\\trbrdrh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRL, "\\trbrdrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRR, "\\trbrdrr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRT, "\\trbrdrt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRV, "\\trbrdrv" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRHDR, "\\trhdr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRKEEP, "\\trkeep" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDB, "\\trpaddb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDL, "\\trpaddl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDR, "\\trpaddr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDT, "\\trpaddt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFB, "\\trpaddfb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFL, "\\trpaddfl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFR, "\\trpaddfr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFT, "\\trpaddft" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WRAPTRSP, "\\wraptrsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_XEF, "\\xef" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ZWJ, "\\zwj" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ZWNJ, "\\zwnj" );
+
+// neue Tokens zur 1.5
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSLOCK, "\\abslock" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADJUSTRIGHT, "\\adjustright" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNCHOSUNG, "\\aftnnchosung" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNCNUM, "\\aftnncnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBAR, "\\aftnndbar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUM, "\\aftnndbnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUMD, "\\aftnndbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUMK, "\\aftnndbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUMT, "\\aftnndbnumt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGANADA, "\\aftnnganada" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUM, "\\aftnngbnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUMD, "\\aftnngbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUMK, "\\aftnngbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUML, "\\aftnngbnuml" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNZODIAC, "\\aftnnzodiac" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNZODIACD, "\\aftnnzodiacd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNZODIACL, "\\aftnnzodiacl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANIMTEXT, "\\animtext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANSICPG, "\\ansicpg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BACKGROUND, "\\background" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BDBFHDR, "\\bdbfhdr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLIPTAG, "\\bliptag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLIPUID, "\\blipuid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLIPUPI, "\\blipupi" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRART, "\\brdrart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHD, "\\brdrdashd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHDD, "\\brdrdashdd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHDOTSTR, "\\brdrdashdotstr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHSM, "\\brdrdashsm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDREMBOSS, "\\brdremboss" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRENGRAVE, "\\brdrengrave" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRFRAME, "\\brdrframe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTHTNLG, "\\brdrthtnlg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTHTNMG, "\\brdrthtnmg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTHTNSG, "\\brdrthtnsg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHLG, "\\brdrtnthlg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHMG, "\\brdrtnthmg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHSG, "\\brdrtnthsg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHTNLG, "\\brdrtnthtnlg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHTNMG, "\\brdrtnthtnmg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHTNSG, "\\brdrtnthtnsg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTRIPLE, "\\brdrtriple" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRWAVY, "\\brdrwavy" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRWAVYDB, "\\brdrwavydb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CATEGORY, "\\category" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CGRID, "\\cgrid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHARSCALEX, "\\charscalex" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGBDIAG, "\\chbgbdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGCROSS, "\\chbgcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDCROSS, "\\chbgdcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKBDIAG, "\\chbgdkbdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKCROSS, "\\chbgdkcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKDCROSS, "\\chbgdkdcross" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKFDIAG, "\\chbgdkfdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKHORIZ, "\\chbgdkhoriz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKVERT, "\\chbgdkvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGFDIAG, "\\chbgfdiag" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGHORIZ, "\\chbghoriz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGVERT, "\\chbgvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBRDR, "\\chbrdr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHCBPAT, "\\chcbpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHCFPAT, "\\chcfpat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHSHDNG, "\\chshdng" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADL, "\\clpadl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADT, "\\clpadt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADB, "\\clpadb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADR, "\\clpadr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFL, "\\clpadfl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFT, "\\clpadft" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFB, "\\clpadfb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFR, "\\clpadfr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXLRTB, "\\cltxlrtb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXTBRL, "\\cltxtbrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVERTALB, "\\clvertalb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVERTALC, "\\clvertalc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVERTALT, "\\clvertalt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVMGF, "\\clvmgf" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVMRG, "\\clvmrg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXTBRLV, "\\cltxtbrlv" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXBTLR, "\\cltxbtlr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXLRTBV, "\\cltxlrtbv" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COMPANY, "\\company" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CRAUTH, "\\crauth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CRDATE, "\\crdate" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DATE, "\\date" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFLANGFE, "\\deflangfe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRAUTH, "\\dfrauth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRDATE, "\\dfrdate" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRSTART, "\\dfrstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRSTOP, "\\dfrstop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRXST, "\\dfrxst" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DGMARGIN, "\\dgmargin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DNTBLNSBDB, "\\dntblnsbdb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCTYPE, "\\doctype" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCVAR, "\\docvar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODESCENT, "\\dpcodescent" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMBO, "\\embo" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMFBLIP, "\\emfblip" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EXPSHRTN, "\\expshrtn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAAUTO, "\\faauto" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FBIAS, "\\fbias" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFDEFRES, "\\ffdefres" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFDEFTEXT, "\\ffdeftext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFENTRYMCR, "\\ffentrymcr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFEXITMCR, "\\ffexitmcr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFFORMAT, "\\ffformat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFHASLISTBOX, "\\ffhaslistbox" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFHELPTEXT, "\\ffhelptext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFHPS, "\\ffhps" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFL, "\\ffl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFMAXLEN, "\\ffmaxlen" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFNAME, "\\ffname" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFOWNHELP, "\\ffownhelp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFOWNSTAT, "\\ffownstat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFPROT, "\\ffprot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFRECALC, "\\ffrecalc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFRES, "\\ffres" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFSIZE, "\\ffsize" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFSTATTEXT, "\\ffstattext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFTYPE, "\\fftype" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFTYPETXT, "\\fftypetxt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDTYPE, "\\fldtype" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FNAME, "\\fname" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMFIELD, "\\formfield" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FROMTEXT, "\\fromtext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNCHOSUNG, "\\ftnnchosung" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNCNUM, "\\ftnncnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBAR, "\\ftnndbar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUM, "\\ftnndbnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUMD, "\\ftnndbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUMK, "\\ftnndbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUMT, "\\ftnndbnumt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGANADA, "\\ftnnganada" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUM, "\\ftnngbnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUMD, "\\ftnngbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUMK, "\\ftnngbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUML, "\\ftnngbnuml" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNZODIAC, "\\ftnnzodiac" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNZODIACD, "\\ftnnzodiacd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNZODIACL, "\\ftnnzodiacl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_G, "\\g" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GCW, "\\gcw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRIDTBL, "\\gridtbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HIGHLIGHT, "\\highlight" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLFR, "\\hlfr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLINKBASE, "\\hlinkbase" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLLOC, "\\hlloc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLSRC, "\\hlsrc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ILVL, "\\ilvl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_IMPR, "\\impr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_JPEGBLIP, "\\jpegblip" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELFOLLOW, "\\levelfollow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELINDENT, "\\levelindent" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELJC, "\\leveljc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELLEGAL, "\\levellegal" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELNFC, "\\levelnfc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELNORESTART, "\\levelnorestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELNUMBERS, "\\levelnumbers" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELOLD, "\\levelold" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELPREV, "\\levelprev" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELPREVSPACE, "\\levelprevspace" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELSPACE, "\\levelspace" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELSTARTAT, "\\levelstartat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELTEXT, "\\leveltext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINKVAL, "\\linkval" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LIST, "\\list" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTID, "\\listid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTLEVEL, "\\listlevel" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTNAME, "\\listname" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDE, "\\listoverride" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDECOUNT, "\\listoverridecount" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDEFORMAT, "\\listoverrideformat" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDESTART, "\\listoverridestart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDETABLE, "\\listoverridetable" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTRESTARTHDN, "\\listrestarthdn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTSIMPLE, "\\listsimple" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTTABLE, "\\listtable" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTTEMPLATEID, "\\listtemplateid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTTEXT, "\\listtext" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LS, "\\ls" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LYTEXCTTP, "\\lytexcttp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LYTPRTMET, "\\lytprtmet" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MANAGER, "\\manager" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MSMCAP, "\\msmcap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFCHARSWS, "\\nofcharsws" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOLEAD, "\\nolead" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NONSHPPICT, "\\nonshppict" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSECTEXPAND, "\\nosectexpand" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSNAPLINEGRID, "\\nosnaplinegrid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSPACEFORUL, "\\nospaceforul" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOULTRLSPC, "\\noultrlspc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOXLATTOYEN, "\\noxlattoyen" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJATTPH, "\\objattph" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJHTML, "\\objhtml" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJOCX, "\\objocx" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDLINEWRAP, "\\oldlinewrap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OUTLINELEVEL, "\\outlinelevel" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OVERLAY, "\\overlay" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PANOSE, "\\panose" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRB, "\\pgbrdrb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRFOOT, "\\pgbrdrfoot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRHEAD, "\\pgbrdrhead" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRL, "\\pgbrdrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDROPT, "\\pgbrdropt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRR, "\\pgbrdrr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRSNAP, "\\pgbrdrsnap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRT, "\\pgbrdrt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNCHOSUNG, "\\pgnchosung" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNCNUM, "\\pgncnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNDBNUMK, "\\pgndbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNDBNUMT, "\\pgndbnumt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGANADA, "\\pgnganada" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUM, "\\pgngbnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUMD, "\\pgngbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUMK, "\\pgngbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUML, "\\pgngbnuml" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNZODIAC, "\\pgnzodiac" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNZODIACD, "\\pgnzodiacd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNZODIACL, "\\pgnzodiacl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICPROP, "\\picprop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNAIUEO, "\\pnaiueo" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNAIUEOD, "\\pnaiueod" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCHOSUNG, "\\pnchosung" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUMD, "\\pndbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUMK, "\\pndbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUML, "\\pndbnuml" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUMT, "\\pndbnumt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGANADA, "\\pnganada" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBLIP, "\\pngblip" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUM, "\\pngbnum" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUMD, "\\pngbnumd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUMK, "\\pngbnumk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUML, "\\pngbnuml" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRAUTH, "\\pnrauth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRDATE, "\\pnrdate" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRNFC, "\\pnrnfc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRNOT, "\\pnrnot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRPNBR, "\\pnrpnbr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRRGB, "\\pnrrgb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRSTART, "\\pnrstart" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRSTOP, "\\pnrstop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRXST, "\\pnrxst" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNZODIAC, "\\pnzodiac" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNZODIACD, "\\pnzodiacd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNZODIACL, "\\pnzodiacl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LFOLEVEL, "\\lfolevel" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYIN, "\\posyin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYOUT, "\\posyout" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRIVATE, "\\private" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PROPNAME, "\\propname" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PROPTYPE, "\\proptype" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVAUTHDEL, "\\revauthdel" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVDTTMDEL, "\\revdttmdel" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SAUTOUPD, "\\sautoupd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTDEFAULTCL, "\\sectdefaultcl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTEXPAND, "\\sectexpand" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTLINEGRID, "\\sectlinegrid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTSPECIFYCL, "\\sectspecifycl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTSPECIFYL, "\\sectspecifyl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHIDDEN, "\\shidden" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBOTTOM, "\\shpbottom" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBXCOLUMN, "\\shpbxcolumn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBXMARGIN, "\\shpbxmargin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBXPAGE, "\\shpbxpage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBYMARGIN, "\\shpbymargin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBYPAGE, "\\shpbypage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBYPARA, "\\shpbypara" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPFBLWTXT, "\\shpfblwtxt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPFHDR, "\\shpfhdr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPGRP, "\\shpgrp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLEFT, "\\shpleft" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLID, "\\shplid" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLOCKANCHOR, "\\shplockanchor" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPPICT, "\\shppict" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPRIGHT, "\\shpright" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPRSLT, "\\shprslt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPTOP, "\\shptop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPTXT, "\\shptxt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPWRK, "\\shpwrk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPWR, "\\shpwr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPZ, "\\shpz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSBSP, "\\sprsbsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSLNSP, "\\sprslnsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSTSM, "\\sprstsm" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STATICVAL, "\\staticval" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STEXTFLOW, "\\stextflow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STRIKED, "\\striked" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBFONTBYSIZE, "\\subfontbysize" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCELLD, "\\tcelld" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TIME, "\\time" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRUNCATEFONTHEIGHT, "\\truncatefontheight" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UC, "\\uc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UD, "\\ud" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDASH, "\\uldash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDASHD, "\\uldashd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDASHDD, "\\uldashdd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTH, "\\ulth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULWAVE, "\\ulwave" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULC, "\\ulc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_U, "\\u" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UPR, "\\upr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_USERPROPS, "\\userprops" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VIEWKIND, "\\viewkind" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VIEWSCALE, "\\viewscale" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VIEWZK, "\\viewzk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WIDCTLPAR, "\\widctlpar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WINDOWCAPTION, "\\windowcaption" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WPEQN, "\\wpeqn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WPJST, "\\wpjst" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WPSP, "\\wpsp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_YXE, "\\yxe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXLRTB, "\\frmtxlrtb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXTBRL, "\\frmtxtbrl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXBTLR, "\\frmtxbtlr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXLRTBV, "\\frmtxlrtbv" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXTBRLV, "\\frmtxtbrlv" );
+
+// MS-2000 Tokens
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHD, "\\ulthd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHDASH, "\\ulthdash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULLDASH, "\\ulldash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHLDASH, "\\ulthldash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHDASHD, "\\ulthdashd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHDASHDD, "\\ulthdashdd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULHWAVE, "\\ulhwave" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULULDBWAVE, "\\ululdbwave" );
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LOCH, "\\loch" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HICH, "\\hich" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DBCH, "\\dbch" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LANGFE, "\\langfe" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADEFLANG, "\\adeflang" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADEFF, "\\adeff" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACCNONE, "\\accnone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACCDOT, "\\accdot" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACCCOMMA, "\\acccomma" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TWOINONE, "\\twoinone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HORZVERT, "\\horzvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAHANG, "\\fahang" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAVAR, "\\favar" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FACENTER, "\\facenter" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAROMAN, "\\faroman" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAFIXED, "\\fafixed" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOCWRAP, "\\nocwrap" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOOVERFLOW,"\\nooverflow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASPALPHA, "\\aspalpha" );
+
+// SWG spezifische Attribute
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRFALIGNV, "\\grfalignv" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRFALIGNH, "\\grfalignh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRFMIRROR, "\\grfmirror" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERYB, "\\headeryb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERXL, "\\headerxl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERXR, "\\headerxr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERYT, "\\footeryt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERXL, "\\footerxl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERXR, "\\footerxr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERYH, "\\headeryh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERYH, "\\footeryh" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BALANCEDCOLUMN, "\\swcolmnblnc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UPDNPROP, "\\updnprop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRTDATA, "\\prtdata" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKKEY, "\\bkmkkey" );
+
+// Attribute fuer die freifliegenden Rahmen
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYPRINT, "\\flyprint" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYOPAQUE, "\\flyopaque" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYPRTCTD, "\\flyprtctd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYMAINCNT, "\\flymaincnt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYVERT, "\\flyvert" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYHORZ, "\\flyhorz" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTL, "\\dfrmtxtl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTR, "\\dfrmtxtr" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTU, "\\dfrmtxtu" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTW, "\\dfrmtxtw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYANCHOR, "\\flyanchor" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYCNTNT, "\\flycntnt" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYCOLUMN, "\\flycolumn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYPAGE, "\\flypage" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYINPARA, "\\flyinpara" );
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDBOX, "\\brdbox" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNCOL, "\\brdlncol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNIN, "\\brdlnin" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNOUT, "\\brdlnout" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNDIST, "\\brdlndist" );
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHADOW, "\\shadow" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWDIST, "\\shdwdist" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWSTYLE, "\\shdwstyle" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWCOL, "\\shdwcol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWFCOL, "\\shdwfcol" );
+
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCTBL, "\\pgdsctbl" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSC, "\\pgdsc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCUSE, "\\pgdscuse" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCNXT, "\\pgdscnxt" );
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHEN, "\\hyphen" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHLEAD, "\\hyphlead" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHTRAIL, "\\hyphtrail" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHMAX, "\\hyphmax" );
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLSWG, "\\tlswg" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRK, "\\pgbrk" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCNO, "\\pgdscno" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOUTLVL, "\\soutlvl" );
+
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHP, "\\shp" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SN, "\\sn" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SV, "\\sv" );
+/*
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLEFT, "\\shpleft" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPTOP, "\\shptop" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBOTTOM, "\\shpbottom" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPRIGHT, "\\shpright" );
+*/
+
+// Support for overline attributes
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OL, "\\ol" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLD, "\\old" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDB, "\\oldb" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLNONE, "\\olnone" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLW, "\\olw" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDASH, "\\oldash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDASHD, "\\oldashd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDASHDD, "\\oldashdd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTH, "\\olth" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLWAVE, "\\olwave" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLC, "\\olc" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHD, "\\olthd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHDASH, "\\olthdash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLLDASH, "\\olldash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHLDASH, "\\olthldash" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHDASHD, "\\olthdashd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHDASHDD, "\\olthdashdd" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLHWAVE, "\\olhwave" );
+sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLOLDBWAVE, "\\ololdbwave" );
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/svtools/source/svrtf/rtfkeywd.cxx b/svtools/source/svrtf/rtfkeywd.cxx
new file mode 100644
index 000000000000..27ce3643f8cf
--- /dev/null
+++ b/svtools/source/svrtf/rtfkeywd.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_svtools.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include "rtfkeywd.hxx"
+#include "rtftoken.h"
+#include "tools/string.hxx"
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+// die Tabelle muss noch sortiert werden
+struct RTF_TokenEntry
+{
+ union{
+ const sal_Char* sToken;
+ const String* pUToken;
+ };
+ int nToken;
+};
+
+// Flag: RTF-Token Tabelle wurde schon sortiert
+static int __FAR_DATA bSortKeyWords = FALSE;
+
+static RTF_TokenEntry __FAR_DATA aRTFTokenTab[] = {
+{{OOO_STRING_SVTOOLS_RTF_IGNORE}, RTF_IGNOREFLAG},
+{{OOO_STRING_SVTOOLS_RTF_RTF}, RTF_RTF},
+{{OOO_STRING_SVTOOLS_RTF_ANSI}, RTF_ANSITYPE},
+{{OOO_STRING_SVTOOLS_RTF_MAC}, RTF_MACTYPE},
+{{OOO_STRING_SVTOOLS_RTF_PC}, RTF_PCTYPE},
+{{OOO_STRING_SVTOOLS_RTF_PCA}, RTF_PCATYPE},
+{{OOO_STRING_SVTOOLS_RTF_NEXTCSET}, RTF_NEXTTYPE},
+{{OOO_STRING_SVTOOLS_RTF_STYLESHEET}, RTF_STYLESHEET},
+{{OOO_STRING_SVTOOLS_RTF_SBASEDON}, RTF_SBASEDON},
+{{OOO_STRING_SVTOOLS_RTF_SNEXT}, RTF_SNEXT},
+{{OOO_STRING_SVTOOLS_RTF_FONTTBL}, RTF_FONTTBL},
+{{OOO_STRING_SVTOOLS_RTF_DEFF}, RTF_DEFF},
+{{OOO_STRING_SVTOOLS_RTF_FNIL}, RTF_FNIL},
+{{OOO_STRING_SVTOOLS_RTF_FROMAN}, RTF_FROMAN},
+{{OOO_STRING_SVTOOLS_RTF_FSWISS}, RTF_FSWISS},
+{{OOO_STRING_SVTOOLS_RTF_FMODERN}, RTF_FMODERN},
+{{OOO_STRING_SVTOOLS_RTF_FSCRIPT}, RTF_FSCRIPT},
+{{OOO_STRING_SVTOOLS_RTF_FDECOR}, RTF_FDECOR},
+{{OOO_STRING_SVTOOLS_RTF_FTECH}, RTF_FTECH},
+{{OOO_STRING_SVTOOLS_RTF_FCHARSET}, RTF_FCHARSET},
+{{OOO_STRING_SVTOOLS_RTF_FALT}, RTF_FALT},
+{{OOO_STRING_SVTOOLS_RTF_FPRQ}, RTF_FPRQ},
+{{OOO_STRING_SVTOOLS_RTF_COLORTBL}, RTF_COLORTBL},
+{{OOO_STRING_SVTOOLS_RTF_RED}, RTF_RED},
+{{OOO_STRING_SVTOOLS_RTF_GREEN}, RTF_GREEN},
+{{OOO_STRING_SVTOOLS_RTF_BLUE}, RTF_BLUE},
+{{OOO_STRING_SVTOOLS_RTF_CF}, RTF_CF},
+{{OOO_STRING_SVTOOLS_RTF_CB}, RTF_CB},
+{{OOO_STRING_SVTOOLS_RTF_INFO}, RTF_INFO},
+{{OOO_STRING_SVTOOLS_RTF_TITLE}, RTF_TITLE},
+{{OOO_STRING_SVTOOLS_RTF_SUBJECT}, RTF_SUBJECT},
+{{OOO_STRING_SVTOOLS_RTF_AUTHOR}, RTF_AUTHOR},
+{{OOO_STRING_SVTOOLS_RTF_OPERATOR}, RTF_OPERATOR},
+{{OOO_STRING_SVTOOLS_RTF_KEYWORDS}, RTF_KEYWORDS},
+{{OOO_STRING_SVTOOLS_RTF_COMMENT}, RTF_COMMENT},
+{{OOO_STRING_SVTOOLS_RTF_VERSION}, RTF_VERSION},
+{{OOO_STRING_SVTOOLS_RTF_DOCCOMM}, RTF_DOCCOMM},
+{{OOO_STRING_SVTOOLS_RTF_VERN}, RTF_VERN},
+{{OOO_STRING_SVTOOLS_RTF_CREATIM}, RTF_CREATIM},
+{{OOO_STRING_SVTOOLS_RTF_REVTIM}, RTF_REVTIM},
+{{OOO_STRING_SVTOOLS_RTF_PRINTIM}, RTF_PRINTIM},
+{{OOO_STRING_SVTOOLS_RTF_BUPTIM}, RTF_BUPTIM},
+{{OOO_STRING_SVTOOLS_RTF_EDMINS}, RTF_EDMINS},
+{{OOO_STRING_SVTOOLS_RTF_NOFPAGES}, RTF_NOFPAGES},
+{{OOO_STRING_SVTOOLS_RTF_NOFWORDS}, RTF_NOFWORDS},
+{{OOO_STRING_SVTOOLS_RTF_NOFCHARS}, RTF_NOFCHARS},
+{{OOO_STRING_SVTOOLS_RTF_ID}, RTF_ID},
+{{OOO_STRING_SVTOOLS_RTF_YR}, RTF_YR},
+{{OOO_STRING_SVTOOLS_RTF_MO}, RTF_MO},
+{{OOO_STRING_SVTOOLS_RTF_DY}, RTF_DY},
+{{OOO_STRING_SVTOOLS_RTF_HR}, RTF_HR},
+{{OOO_STRING_SVTOOLS_RTF_MIN}, RTF_MIN},
+{{OOO_STRING_SVTOOLS_RTF_ANNOTATION}, RTF_ANNOTATION},
+{{OOO_STRING_SVTOOLS_RTF_ATNID}, RTF_ATNID},
+{{OOO_STRING_SVTOOLS_RTF_FOOTNOTE}, RTF_FOOTNOTE},
+{{OOO_STRING_SVTOOLS_RTF_FOOTER}, RTF_FOOTER},
+{{OOO_STRING_SVTOOLS_RTF_FOOTERL}, RTF_FOOTERL},
+{{OOO_STRING_SVTOOLS_RTF_FOOTERR}, RTF_FOOTERR},
+{{OOO_STRING_SVTOOLS_RTF_FOOTERF}, RTF_FOOTERF},
+{{OOO_STRING_SVTOOLS_RTF_HEADER}, RTF_HEADER},
+{{OOO_STRING_SVTOOLS_RTF_HEADERL}, RTF_HEADERL},
+{{OOO_STRING_SVTOOLS_RTF_HEADERR}, RTF_HEADERR},
+{{OOO_STRING_SVTOOLS_RTF_HEADERF}, RTF_HEADERF},
+{{OOO_STRING_SVTOOLS_RTF_XE}, RTF_XE},
+{{OOO_STRING_SVTOOLS_RTF_BXE}, RTF_BXE},
+{{OOO_STRING_SVTOOLS_RTF_IXE}, RTF_IXE},
+{{OOO_STRING_SVTOOLS_RTF_RXE}, RTF_RXE},
+{{OOO_STRING_SVTOOLS_RTF_TXE}, RTF_TXE},
+{{OOO_STRING_SVTOOLS_RTF_TC}, RTF_TC},
+{{OOO_STRING_SVTOOLS_RTF_TCF}, RTF_TCF},
+{{OOO_STRING_SVTOOLS_RTF_TCL}, RTF_TCL},
+{{OOO_STRING_SVTOOLS_RTF_BKMKSTART}, RTF_BKMKSTART},
+{{OOO_STRING_SVTOOLS_RTF_BKMKEND}, RTF_BKMKEND},
+{{OOO_STRING_SVTOOLS_RTF_PICT}, RTF_PICT},
+{{OOO_STRING_SVTOOLS_RTF_PICW}, RTF_PICW},
+{{OOO_STRING_SVTOOLS_RTF_PICH}, RTF_PICH},
+{{OOO_STRING_SVTOOLS_RTF_WBMBITSPIXEL}, RTF_WBMBITSPIXEL},
+{{OOO_STRING_SVTOOLS_RTF_WBMPLANES}, RTF_WBMPLANES},
+{{OOO_STRING_SVTOOLS_RTF_WBMWIDTHBYTES}, RTF_WBMWIDTHBYTES},
+{{OOO_STRING_SVTOOLS_RTF_PICWGOAL}, RTF_PICWGOAL},
+{{OOO_STRING_SVTOOLS_RTF_PICHGOAL}, RTF_PICHGOAL},
+{{OOO_STRING_SVTOOLS_RTF_BIN}, RTF_BIN},
+{{OOO_STRING_SVTOOLS_RTF_PICSCALEX}, RTF_PICSCALEX},
+{{OOO_STRING_SVTOOLS_RTF_PICSCALEY}, RTF_PICSCALEY},
+{{OOO_STRING_SVTOOLS_RTF_PICSCALED}, RTF_PICSCALED},
+{{OOO_STRING_SVTOOLS_RTF_WBITMAP}, RTF_WBITMAP},
+{{OOO_STRING_SVTOOLS_RTF_WMETAFILE}, RTF_WMETAFILE},
+{{OOO_STRING_SVTOOLS_RTF_MACPICT}, RTF_MACPICT},
+{{OOO_STRING_SVTOOLS_RTF_PICCROPT}, RTF_PICCROPT},
+{{OOO_STRING_SVTOOLS_RTF_PICCROPB}, RTF_PICCROPB},
+{{OOO_STRING_SVTOOLS_RTF_PICCROPL}, RTF_PICCROPL},
+{{OOO_STRING_SVTOOLS_RTF_PICCROPR}, RTF_PICCROPR},
+{{OOO_STRING_SVTOOLS_RTF_FIELD}, RTF_FIELD},
+{{OOO_STRING_SVTOOLS_RTF_FLDDIRTY}, RTF_FLDDIRTY},
+{{OOO_STRING_SVTOOLS_RTF_FLDEDIT}, RTF_FLDEDIT},
+{{OOO_STRING_SVTOOLS_RTF_FLDLOCK}, RTF_FLDLOCK},
+{{OOO_STRING_SVTOOLS_RTF_FLDPRIV}, RTF_FLDPRIV},
+{{OOO_STRING_SVTOOLS_RTF_FLDINST}, RTF_FLDINST},
+{{OOO_STRING_SVTOOLS_RTF_FLDRSLT}, RTF_FLDRSLT},
+{{OOO_STRING_SVTOOLS_RTF_PAPERW}, RTF_PAPERW},
+{{OOO_STRING_SVTOOLS_RTF_PAPERH}, RTF_PAPERH},
+{{OOO_STRING_SVTOOLS_RTF_MARGL}, RTF_MARGL},
+{{OOO_STRING_SVTOOLS_RTF_MARGR}, RTF_MARGR},
+{{OOO_STRING_SVTOOLS_RTF_MARGT}, RTF_MARGT},
+{{OOO_STRING_SVTOOLS_RTF_MARGB}, RTF_MARGB},
+{{OOO_STRING_SVTOOLS_RTF_FACINGP}, RTF_FACINGP},
+{{OOO_STRING_SVTOOLS_RTF_GUTTER}, RTF_GUTTER},
+{{OOO_STRING_SVTOOLS_RTF_DEFTAB}, RTF_DEFTAB},
+{{OOO_STRING_SVTOOLS_RTF_WIDOWCTRL}, RTF_WIDOWCTRL},
+{{OOO_STRING_SVTOOLS_RTF_HYPHHOTZ}, RTF_HYPHHOTZ},
+{{OOO_STRING_SVTOOLS_RTF_FTNSEP}, RTF_FTNSEP},
+{{OOO_STRING_SVTOOLS_RTF_FTNSEPC}, RTF_FTNSEPC},
+{{OOO_STRING_SVTOOLS_RTF_FTNCN}, RTF_FTNCN},
+{{OOO_STRING_SVTOOLS_RTF_ENDNOTES}, RTF_ENDNOTES},
+{{OOO_STRING_SVTOOLS_RTF_ENDDOC}, RTF_ENDDOC},
+{{OOO_STRING_SVTOOLS_RTF_FTNTJ}, RTF_FTNTJ},
+{{OOO_STRING_SVTOOLS_RTF_FTNBJ}, RTF_FTNBJ},
+{{OOO_STRING_SVTOOLS_RTF_FTNSTART}, RTF_FTNSTART},
+{{OOO_STRING_SVTOOLS_RTF_FTNRESTART}, RTF_FTNRESTART},
+{{OOO_STRING_SVTOOLS_RTF_PGNSTART}, RTF_PGNSTART},
+{{OOO_STRING_SVTOOLS_RTF_LINESTART}, RTF_LINESTART},
+{{OOO_STRING_SVTOOLS_RTF_LANDSCAPE}, RTF_LANDSCAPE},
+{{OOO_STRING_SVTOOLS_RTF_FRACWIDTH}, RTF_FRACWIDTH},
+{{OOO_STRING_SVTOOLS_RTF_NEXTFILE}, RTF_NEXTFILE},
+{{OOO_STRING_SVTOOLS_RTF_TEMPLATE}, RTF_TEMPLATE},
+{{OOO_STRING_SVTOOLS_RTF_MAKEBACKUP}, RTF_MAKEBACKUP},
+{{OOO_STRING_SVTOOLS_RTF_DEFFORMAT}, RTF_DEFFORMAT},
+{{OOO_STRING_SVTOOLS_RTF_REVISIONS}, RTF_REVISIONS},
+{{OOO_STRING_SVTOOLS_RTF_MARGMIRROR}, RTF_MARGMIRROR},
+{{OOO_STRING_SVTOOLS_RTF_REVPROP}, RTF_REVPROP},
+{{OOO_STRING_SVTOOLS_RTF_REVBAR}, RTF_REVBAR},
+{{OOO_STRING_SVTOOLS_RTF_SECTD}, RTF_SECTD},
+{{OOO_STRING_SVTOOLS_RTF_SBKNONE}, RTF_SBKNONE},
+{{OOO_STRING_SVTOOLS_RTF_SBKCOL}, RTF_SBKCOL},
+{{OOO_STRING_SVTOOLS_RTF_SBKPAGE}, RTF_SBKPAGE},
+{{OOO_STRING_SVTOOLS_RTF_SBKEVEN}, RTF_SBKEVEN},
+{{OOO_STRING_SVTOOLS_RTF_SBKODD}, RTF_SBKODD},
+{{OOO_STRING_SVTOOLS_RTF_PGNSTARTS}, RTF_PGNSTARTS},
+{{OOO_STRING_SVTOOLS_RTF_PGNCONT}, RTF_PGNCONT},
+{{OOO_STRING_SVTOOLS_RTF_PGNRESTART}, RTF_PGNRESTART},
+{{OOO_STRING_SVTOOLS_RTF_PGNDEC}, RTF_PGNDEC},
+{{OOO_STRING_SVTOOLS_RTF_PGNUCRM}, RTF_PGNUCRM},
+{{OOO_STRING_SVTOOLS_RTF_PGNLCRM}, RTF_PGNLCRM},
+{{OOO_STRING_SVTOOLS_RTF_PGNUCLTR}, RTF_PGNUCLTR},
+{{OOO_STRING_SVTOOLS_RTF_PGNLCLTR}, RTF_PGNLCLTR},
+{{OOO_STRING_SVTOOLS_RTF_PGNX}, RTF_PGNX},
+{{OOO_STRING_SVTOOLS_RTF_PGNY}, RTF_PGNY},
+{{OOO_STRING_SVTOOLS_RTF_HEADERY}, RTF_HEADERY},
+{{OOO_STRING_SVTOOLS_RTF_FOOTERY}, RTF_FOOTERY},
+{{OOO_STRING_SVTOOLS_RTF_LINEMOD}, RTF_LINEMOD},
+{{OOO_STRING_SVTOOLS_RTF_LINEX}, RTF_LINEX},
+{{OOO_STRING_SVTOOLS_RTF_LINESTARTS}, RTF_LINESTARTS},
+{{OOO_STRING_SVTOOLS_RTF_LINERESTART}, RTF_LINERESTART},
+{{OOO_STRING_SVTOOLS_RTF_LINEPPAGE}, RTF_LINEPAGE},
+{{OOO_STRING_SVTOOLS_RTF_LINECONT}, RTF_LINECONT},
+{{OOO_STRING_SVTOOLS_RTF_VERTALT}, RTF_VERTALT},
+{{OOO_STRING_SVTOOLS_RTF_VERTALB}, RTF_VERTALB},
+{{OOO_STRING_SVTOOLS_RTF_VERTALC}, RTF_VERTALC},
+{{OOO_STRING_SVTOOLS_RTF_VERTALJ}, RTF_VERTALJ},
+{{OOO_STRING_SVTOOLS_RTF_COLS}, RTF_COLS},
+{{OOO_STRING_SVTOOLS_RTF_COLSX}, RTF_COLSX},
+{{OOO_STRING_SVTOOLS_RTF_COLNO}, RTF_COLNO},
+{{OOO_STRING_SVTOOLS_RTF_COLSR}, RTF_COLSR},
+{{OOO_STRING_SVTOOLS_RTF_COLW}, RTF_COLW},
+{{OOO_STRING_SVTOOLS_RTF_LINEBETCOL}, RTF_LINEBETCOL},
+{{OOO_STRING_SVTOOLS_RTF_ENDNHERE}, RTF_ENDNHERE},
+{{OOO_STRING_SVTOOLS_RTF_TITLEPG}, RTF_TITLEPG},
+{{OOO_STRING_SVTOOLS_RTF_PARD}, RTF_PARD},
+{{OOO_STRING_SVTOOLS_RTF_S}, RTF_S},
+{{OOO_STRING_SVTOOLS_RTF_QL}, RTF_QL},
+{{OOO_STRING_SVTOOLS_RTF_QR}, RTF_QR},
+{{OOO_STRING_SVTOOLS_RTF_QJ}, RTF_QJ},
+{{OOO_STRING_SVTOOLS_RTF_QC}, RTF_QC},
+{{OOO_STRING_SVTOOLS_RTF_FI}, RTF_FI},
+{{OOO_STRING_SVTOOLS_RTF_LI}, RTF_LI},
+{{OOO_STRING_SVTOOLS_RTF_LIN}, RTF_LIN},
+{{OOO_STRING_SVTOOLS_RTF_RI}, RTF_RI},
+{{OOO_STRING_SVTOOLS_RTF_RIN}, RTF_RIN},
+{{OOO_STRING_SVTOOLS_RTF_SB}, RTF_SB},
+{{OOO_STRING_SVTOOLS_RTF_SA}, RTF_SA},
+{{OOO_STRING_SVTOOLS_RTF_SL}, RTF_SL},
+{{OOO_STRING_SVTOOLS_RTF_INTBL}, RTF_INTBL},
+{{OOO_STRING_SVTOOLS_RTF_KEEP}, RTF_KEEP},
+{{OOO_STRING_SVTOOLS_RTF_KEEPN}, RTF_KEEPN},
+{{OOO_STRING_SVTOOLS_RTF_LEVEL}, RTF_LEVEL},
+{{OOO_STRING_SVTOOLS_RTF_SBYS}, RTF_SBYS},
+{{OOO_STRING_SVTOOLS_RTF_PAGEBB}, RTF_PAGEBB},
+{{OOO_STRING_SVTOOLS_RTF_NOLINE}, RTF_NOLINE},
+{{OOO_STRING_SVTOOLS_RTF_TX}, RTF_TX},
+{{OOO_STRING_SVTOOLS_RTF_TQL}, RTF_TQL},
+{{OOO_STRING_SVTOOLS_RTF_TQR}, RTF_TQR},
+{{OOO_STRING_SVTOOLS_RTF_TQC}, RTF_TQC},
+{{OOO_STRING_SVTOOLS_RTF_TQDEC}, RTF_TQDEC},
+{{OOO_STRING_SVTOOLS_RTF_TB}, RTF_TB},
+{{OOO_STRING_SVTOOLS_RTF_BRDRT}, RTF_BRDRT},
+{{OOO_STRING_SVTOOLS_RTF_BRDRB}, RTF_BRDRB},
+{{OOO_STRING_SVTOOLS_RTF_BRDRL}, RTF_BRDRL},
+{{OOO_STRING_SVTOOLS_RTF_BRDRR}, RTF_BRDRR},
+{{OOO_STRING_SVTOOLS_RTF_BOX}, RTF_BOX},
+{{OOO_STRING_SVTOOLS_RTF_BRDRS}, RTF_BRDRS},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTH}, RTF_BRDRTH},
+{{OOO_STRING_SVTOOLS_RTF_BRDRSH}, RTF_BRDRSH},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDB}, RTF_BRDRDB},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDOT}, RTF_BRDRDOT},
+{{OOO_STRING_SVTOOLS_RTF_BRDRHAIR}, RTF_BRDRHAIR},
+{{OOO_STRING_SVTOOLS_RTF_BRSP}, RTF_BRSP},
+{{OOO_STRING_SVTOOLS_RTF_TLDOT}, RTF_TLDOT},
+{{OOO_STRING_SVTOOLS_RTF_TLHYPH}, RTF_TLHYPH},
+{{OOO_STRING_SVTOOLS_RTF_TLUL}, RTF_TLUL},
+{{OOO_STRING_SVTOOLS_RTF_TLTH}, RTF_TLTH},
+{{OOO_STRING_SVTOOLS_RTF_POSX}, RTF_POSX},
+{{OOO_STRING_SVTOOLS_RTF_POSXC}, RTF_POSXC},
+{{OOO_STRING_SVTOOLS_RTF_POSXI}, RTF_POSXI},
+{{OOO_STRING_SVTOOLS_RTF_POSXL}, RTF_POSXL},
+{{OOO_STRING_SVTOOLS_RTF_POSXO}, RTF_POSXO},
+{{OOO_STRING_SVTOOLS_RTF_POSXR}, RTF_POSXR},
+{{OOO_STRING_SVTOOLS_RTF_POSY}, RTF_POSY},
+{{OOO_STRING_SVTOOLS_RTF_POSYIL}, RTF_POSYIL},
+{{OOO_STRING_SVTOOLS_RTF_POSYT}, RTF_POSYT},
+{{OOO_STRING_SVTOOLS_RTF_POSYC}, RTF_POSYC},
+{{OOO_STRING_SVTOOLS_RTF_POSYB}, RTF_POSYB},
+{{OOO_STRING_SVTOOLS_RTF_ABSW}, RTF_ABSW},
+{{OOO_STRING_SVTOOLS_RTF_DXFRTEXT}, RTF_DXFRTEXT},
+{{OOO_STRING_SVTOOLS_RTF_PVMRG}, RTF_PVMRG},
+{{OOO_STRING_SVTOOLS_RTF_PVPG}, RTF_PVPG},
+{{OOO_STRING_SVTOOLS_RTF_PHMRG}, RTF_PHMRG},
+{{OOO_STRING_SVTOOLS_RTF_PHPG}, RTF_PHPG},
+{{OOO_STRING_SVTOOLS_RTF_PHCOL}, RTF_PHCOL},
+{{OOO_STRING_SVTOOLS_RTF_CLBRDRB}, RTF_CLBRDRB},
+{{OOO_STRING_SVTOOLS_RTF_CLBRDRT}, RTF_CLBRDRT},
+{{OOO_STRING_SVTOOLS_RTF_CLBRDRL}, RTF_CLBRDRL},
+{{OOO_STRING_SVTOOLS_RTF_CLBRDRR}, RTF_CLBRDRR},
+{{OOO_STRING_SVTOOLS_RTF_CLPADL}, RTF_CLPADL},
+{{OOO_STRING_SVTOOLS_RTF_CLPADT}, RTF_CLPADT},
+{{OOO_STRING_SVTOOLS_RTF_CLPADB}, RTF_CLPADB},
+{{OOO_STRING_SVTOOLS_RTF_CLPADR}, RTF_CLPADR},
+{{OOO_STRING_SVTOOLS_RTF_CLPADFL}, RTF_CLPADFL},
+{{OOO_STRING_SVTOOLS_RTF_CLPADFT}, RTF_CLPADFT},
+{{OOO_STRING_SVTOOLS_RTF_CLPADFB}, RTF_CLPADFB},
+{{OOO_STRING_SVTOOLS_RTF_CLPADFR}, RTF_CLPADFR},
+{{OOO_STRING_SVTOOLS_RTF_TROWD}, RTF_TROWD},
+{{OOO_STRING_SVTOOLS_RTF_TRQL}, RTF_TRQL},
+{{OOO_STRING_SVTOOLS_RTF_TRQR}, RTF_TRQR},
+{{OOO_STRING_SVTOOLS_RTF_TRQC}, RTF_TRQC},
+{{OOO_STRING_SVTOOLS_RTF_TRGAPH}, RTF_TRGAPH},
+{{OOO_STRING_SVTOOLS_RTF_TRRH}, RTF_TRRH},
+{{OOO_STRING_SVTOOLS_RTF_TRLEFT}, RTF_TRLEFT},
+{{OOO_STRING_SVTOOLS_RTF_CELLX}, RTF_CELLX},
+{{OOO_STRING_SVTOOLS_RTF_CLMGF}, RTF_CLMGF},
+{{OOO_STRING_SVTOOLS_RTF_CLMRG}, RTF_CLMRG},
+{{OOO_STRING_SVTOOLS_RTF_PLAIN}, RTF_PLAIN},
+{{OOO_STRING_SVTOOLS_RTF_B}, RTF_B},
+{{OOO_STRING_SVTOOLS_RTF_I}, RTF_I},
+{{OOO_STRING_SVTOOLS_RTF_STRIKE}, RTF_STRIKE},
+{{OOO_STRING_SVTOOLS_RTF_OUTL}, RTF_OUTL},
+{{OOO_STRING_SVTOOLS_RTF_SHAD}, RTF_SHAD},
+{{OOO_STRING_SVTOOLS_RTF_SCAPS}, RTF_SCAPS},
+{{OOO_STRING_SVTOOLS_RTF_CAPS}, RTF_CAPS},
+{{OOO_STRING_SVTOOLS_RTF_V}, RTF_V},
+{{OOO_STRING_SVTOOLS_RTF_F}, RTF_F},
+{{OOO_STRING_SVTOOLS_RTF_FS}, RTF_FS},
+{{OOO_STRING_SVTOOLS_RTF_EXPND}, RTF_EXPND},
+{{OOO_STRING_SVTOOLS_RTF_EXPNDTW}, RTF_EXPNDTW},
+{{OOO_STRING_SVTOOLS_RTF_KERNING}, RTF_KERNING},
+{{OOO_STRING_SVTOOLS_RTF_UL}, RTF_UL},
+{{OOO_STRING_SVTOOLS_RTF_ULW}, RTF_ULW},
+{{OOO_STRING_SVTOOLS_RTF_ULD}, RTF_ULD},
+{{OOO_STRING_SVTOOLS_RTF_ULDB}, RTF_ULDB},
+{{OOO_STRING_SVTOOLS_RTF_ULNONE}, RTF_ULNONE},
+{{OOO_STRING_SVTOOLS_RTF_UP}, RTF_UP},
+{{OOO_STRING_SVTOOLS_RTF_DN}, RTF_DN},
+{{OOO_STRING_SVTOOLS_RTF_REVISED}, RTF_REVISED},
+{{OOO_STRING_SVTOOLS_RTF_SUB}, RTF_SUB},
+{{OOO_STRING_SVTOOLS_RTF_NOSUPERSUB}, RTF_NOSUPERSUB},
+{{OOO_STRING_SVTOOLS_RTF_SUPER}, RTF_SUPER},
+{{OOO_STRING_SVTOOLS_RTF_CHDATE}, RTF_CHDATE},
+{{OOO_STRING_SVTOOLS_RTF_CHTIME}, RTF_CHTIME},
+{{OOO_STRING_SVTOOLS_RTF_CHPGN}, RTF_CHPGN},
+{{OOO_STRING_SVTOOLS_RTF_CHFTN}, RTF_CHFTN},
+{{OOO_STRING_SVTOOLS_RTF_CHATN}, RTF_CHATN},
+{{OOO_STRING_SVTOOLS_RTF_CHFTNSEP}, RTF_CHFTNSEP},
+{{OOO_STRING_SVTOOLS_RTF_CHFTNSEPC}, RTF_CHFTNSEPC},
+{{OOO_STRING_SVTOOLS_RTF_FORMULA}, RTF_FORMULA},
+{{OOO_STRING_SVTOOLS_RTF_NOBREAK}, RTF_NONBREAKINGSPACE},
+{{OOO_STRING_SVTOOLS_RTF_OPTHYPH}, RTF_OPTIONALHYPHEN},
+{{OOO_STRING_SVTOOLS_RTF_NOBRKHYPH}, RTF_NONBREAKINGHYPHEN},
+{{OOO_STRING_SVTOOLS_RTF_HEXCHAR}, RTF_HEX},
+{{OOO_STRING_SVTOOLS_RTF_CELL}, RTF_CELL},
+{{OOO_STRING_SVTOOLS_RTF_ROW}, RTF_ROW},
+{{OOO_STRING_SVTOOLS_RTF_PAR}, RTF_PAR},
+{{OOO_STRING_SVTOOLS_RTF_SECT}, RTF_SECT},
+{{OOO_STRING_SVTOOLS_RTF_PAGE}, RTF_PAGE},
+{{OOO_STRING_SVTOOLS_RTF_COLUMN}, RTF_COLUM},
+{{OOO_STRING_SVTOOLS_RTF_LINE}, RTF_LINE},
+{{OOO_STRING_SVTOOLS_RTF_TAB}, RTF_TAB},
+{{OOO_STRING_SVTOOLS_RTF_SUBENTRY}, RTF_SUBENTRYINDEX},
+
+{{OOO_STRING_SVTOOLS_RTF_DEFLANG}, RTF_DEFLANG},
+{{OOO_STRING_SVTOOLS_RTF_LANG}, RTF_LANG},
+{{OOO_STRING_SVTOOLS_RTF_PMMETAFILE}, RTF_OSMETAFILE},
+{{OOO_STRING_SVTOOLS_RTF_DIBITMAP}, RTF_DIBITMAP},
+{{OOO_STRING_SVTOOLS_RTF_KEYCODE}, RTF_KEYCODE},
+{{OOO_STRING_SVTOOLS_RTF_FN}, RTF_FNKEY},
+{{OOO_STRING_SVTOOLS_RTF_ALT}, RTF_ALTKEY},
+{{OOO_STRING_SVTOOLS_RTF_SHIFT}, RTF_SHIFTKEY},
+{{OOO_STRING_SVTOOLS_RTF_CTRL}, RTF_CTRLKEY},
+{{OOO_STRING_SVTOOLS_RTF_CHDPL}, RTF_CHDATEL},
+{{OOO_STRING_SVTOOLS_RTF_CHDPA}, RTF_CHDATEA},
+{{OOO_STRING_SVTOOLS_RTF_EMDASH}, RTF_EMDASH},
+{{OOO_STRING_SVTOOLS_RTF_ENDASH}, RTF_ENDASH},
+{{OOO_STRING_SVTOOLS_RTF_BULLET}, RTF_BULLET},
+{{OOO_STRING_SVTOOLS_RTF_LQUOTE}, RTF_LQUOTE},
+{{OOO_STRING_SVTOOLS_RTF_RQUOTE}, RTF_RQUOTE},
+{{OOO_STRING_SVTOOLS_RTF_LDBLQUOTE}, RTF_LDBLQUOTE},
+{{OOO_STRING_SVTOOLS_RTF_RDBLQUOTE}, RTF_RDBLQUOTE},
+
+{{OOO_STRING_SVTOOLS_RTF_BKMKCOLF}, RTF_BKMKCOLF},
+{{OOO_STRING_SVTOOLS_RTF_BKMKCOLL}, RTF_BKMKCOLL},
+{{OOO_STRING_SVTOOLS_RTF_PSOVER}, RTF_PSOVER},
+{{OOO_STRING_SVTOOLS_RTF_DOCTEMP}, RTF_DOCTEMP},
+{{OOO_STRING_SVTOOLS_RTF_BINFSXN}, RTF_BINFSXN},
+{{OOO_STRING_SVTOOLS_RTF_BINSXN}, RTF_BINSXN},
+{{OOO_STRING_SVTOOLS_RTF_PGWSXN}, RTF_PGWSXN},
+{{OOO_STRING_SVTOOLS_RTF_PGHSXN}, RTF_PGHSXN},
+{{OOO_STRING_SVTOOLS_RTF_MARGLSXN}, RTF_MARGLSXN},
+{{OOO_STRING_SVTOOLS_RTF_MARGRSXN}, RTF_MARGRSXN},
+{{OOO_STRING_SVTOOLS_RTF_MARGTSXN}, RTF_MARGTSXN},
+{{OOO_STRING_SVTOOLS_RTF_MARGBSXN}, RTF_MARGBSXN},
+{{OOO_STRING_SVTOOLS_RTF_GUTTERSXN}, RTF_GUTTERSXN},
+{{OOO_STRING_SVTOOLS_RTF_LNDSCPSXN}, RTF_LNDSCPSXN},
+{{OOO_STRING_SVTOOLS_RTF_FACPGSXN}, RTF_FACPGSXN},
+{{OOO_STRING_SVTOOLS_RTF_TLEQ}, RTF_TLEQ},
+{{OOO_STRING_SVTOOLS_RTF_BRDRBTW}, RTF_BRDRBTW},
+{{OOO_STRING_SVTOOLS_RTF_BRDRBAR}, RTF_BRDRBAR},
+{{OOO_STRING_SVTOOLS_RTF_BRDRW}, RTF_BRDRW},
+{{OOO_STRING_SVTOOLS_RTF_BRDRCF}, RTF_BRDRCF},
+{{OOO_STRING_SVTOOLS_RTF_ABSH}, RTF_ABSH},
+{{OOO_STRING_SVTOOLS_RTF_PVPARA}, RTF_PVPARA},
+{{OOO_STRING_SVTOOLS_RTF_NOWRAP}, RTF_NOWRAP},
+{{OOO_STRING_SVTOOLS_RTF_DFRMTXTX}, RTF_DFRMTXTX},
+{{OOO_STRING_SVTOOLS_RTF_DFRMTXTY}, RTF_DFRMTXTY},
+{{OOO_STRING_SVTOOLS_RTF_DROPCAPLI}, RTF_DROPCAPLI},
+{{OOO_STRING_SVTOOLS_RTF_DROPCAPT}, RTF_DROPCAPT},
+{{OOO_STRING_SVTOOLS_RTF_ABSNOOVRLP}, RTF_ABSNOOVRLP},
+{{OOO_STRING_SVTOOLS_RTF_POSNEGX}, RTF_POSNEGX},
+{{OOO_STRING_SVTOOLS_RTF_POSNEGY}, RTF_POSNEGY},
+{{OOO_STRING_SVTOOLS_RTF_DELETED}, RTF_DELETED},
+
+{{OOO_STRING_SVTOOLS_RTF_SHADING}, RTF_SHADING},
+{{OOO_STRING_SVTOOLS_RTF_BGHORIZ}, RTF_BGHORIZ},
+{{OOO_STRING_SVTOOLS_RTF_BGVERT}, RTF_BGVERT},
+{{OOO_STRING_SVTOOLS_RTF_BGFDIAG}, RTF_BGFDIAG},
+{{OOO_STRING_SVTOOLS_RTF_BGBDIAG}, RTF_BGBDIAG},
+{{OOO_STRING_SVTOOLS_RTF_BGCROSS}, RTF_BGCROSS},
+{{OOO_STRING_SVTOOLS_RTF_BGDCROSS}, RTF_BGDCROSS},
+{{OOO_STRING_SVTOOLS_RTF_BGDKHORIZ}, RTF_BGDKHORIZ},
+{{OOO_STRING_SVTOOLS_RTF_BGDKVERT}, RTF_BGDKVERT},
+{{OOO_STRING_SVTOOLS_RTF_BGDKFDIAG}, RTF_BGDKFDIAG},
+{{OOO_STRING_SVTOOLS_RTF_BGDKBDIAG}, RTF_BGDKBDIAG},
+{{OOO_STRING_SVTOOLS_RTF_BGDKCROSS}, RTF_BGDKCROSS},
+{{OOO_STRING_SVTOOLS_RTF_BGDKDCROSS}, RTF_BGDKDCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CFPAT}, RTF_CFPAT},
+{{OOO_STRING_SVTOOLS_RTF_CBPAT}, RTF_CBPAT},
+
+{{OOO_STRING_SVTOOLS_RTF_CLSHDNG}, RTF_CLSHDNG},
+{{OOO_STRING_SVTOOLS_RTF_CLBGHORIZ}, RTF_CLBGHORIZ},
+{{OOO_STRING_SVTOOLS_RTF_CLBGVERT}, RTF_CLBGVERT},
+{{OOO_STRING_SVTOOLS_RTF_CLBGFDIAG}, RTF_CLBGFDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CLBGBDIAG}, RTF_CLBGBDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CLBGCROSS}, RTF_CLBGCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDCROSS}, RTF_CLBGDCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDKHOR}, RTF_CLBGDKHOR},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDKVERT}, RTF_CLBGDKVERT},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDKFDIAG}, RTF_CLBGDKFDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDKBDIAG}, RTF_CLBGDKBDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDKCROSS}, RTF_CLBGDKCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CLBGDKDCROSS}, RTF_CLBGDKDCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CLCFPAT}, RTF_CLCFPAT},
+{{OOO_STRING_SVTOOLS_RTF_CLCBPAT}, RTF_CLCBPAT},
+
+{{OOO_STRING_SVTOOLS_RTF_AB}, RTF_AB},
+{{OOO_STRING_SVTOOLS_RTF_ACAPS}, RTF_ACAPS},
+{{OOO_STRING_SVTOOLS_RTF_ACF}, RTF_ACF},
+{{OOO_STRING_SVTOOLS_RTF_ADDITIVE}, RTF_ADDITIVE},
+{{OOO_STRING_SVTOOLS_RTF_ADN}, RTF_ADN},
+{{OOO_STRING_SVTOOLS_RTF_AENDDOC}, RTF_AENDDOC},
+{{OOO_STRING_SVTOOLS_RTF_AENDNOTES}, RTF_AENDNOTES},
+{{OOO_STRING_SVTOOLS_RTF_AEXPND}, RTF_AEXPND},
+{{OOO_STRING_SVTOOLS_RTF_AF}, RTF_AF},
+{{OOO_STRING_SVTOOLS_RTF_AFS}, RTF_AFS},
+{{OOO_STRING_SVTOOLS_RTF_AFTNBJ}, RTF_AFTNBJ},
+{{OOO_STRING_SVTOOLS_RTF_AFTNCN}, RTF_AFTNCN},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNALC}, RTF_AFTNNALC},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNAR}, RTF_AFTNNAR},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNAUC}, RTF_AFTNNAUC},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNCHI}, RTF_AFTNNCHI},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNRLC}, RTF_AFTNNRLC},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNRUC}, RTF_AFTNNRUC},
+{{OOO_STRING_SVTOOLS_RTF_AFTNRESTART}, RTF_AFTNRESTART},
+{{OOO_STRING_SVTOOLS_RTF_AFTNRSTCONT}, RTF_AFTNRSTCONT},
+{{OOO_STRING_SVTOOLS_RTF_AFTNSEP}, RTF_AFTNSEP},
+{{OOO_STRING_SVTOOLS_RTF_AFTNSEPC}, RTF_AFTNSEPC},
+{{OOO_STRING_SVTOOLS_RTF_AFTNSTART}, RTF_AFTNSTART},
+{{OOO_STRING_SVTOOLS_RTF_AFTNTJ}, RTF_AFTNTJ},
+{{OOO_STRING_SVTOOLS_RTF_AI}, RTF_AI},
+{{OOO_STRING_SVTOOLS_RTF_ALANG}, RTF_ALANG},
+{{OOO_STRING_SVTOOLS_RTF_ALLPROT}, RTF_ALLPROT},
+{{OOO_STRING_SVTOOLS_RTF_ANNOTPROT}, RTF_ANNOTPROT},
+{{OOO_STRING_SVTOOLS_RTF_AOUTL}, RTF_AOUTL},
+{{OOO_STRING_SVTOOLS_RTF_ASCAPS}, RTF_ASCAPS},
+{{OOO_STRING_SVTOOLS_RTF_ASHAD}, RTF_ASHAD},
+{{OOO_STRING_SVTOOLS_RTF_ASTRIKE}, RTF_ASTRIKE},
+{{OOO_STRING_SVTOOLS_RTF_ATNAUTHOR}, RTF_ATNAUTHOR},
+{{OOO_STRING_SVTOOLS_RTF_ATNICN}, RTF_ATNICN},
+{{OOO_STRING_SVTOOLS_RTF_ATNREF}, RTF_ATNREF},
+{{OOO_STRING_SVTOOLS_RTF_ATNTIME}, RTF_ATNTIME},
+{{OOO_STRING_SVTOOLS_RTF_ATRFEND}, RTF_ATRFEND},
+{{OOO_STRING_SVTOOLS_RTF_ATRFSTART}, RTF_ATRFSTART},
+{{OOO_STRING_SVTOOLS_RTF_AUL}, RTF_AUL},
+{{OOO_STRING_SVTOOLS_RTF_AULD}, RTF_AULD},
+{{OOO_STRING_SVTOOLS_RTF_AULDB}, RTF_AULDB},
+{{OOO_STRING_SVTOOLS_RTF_AULNONE}, RTF_AULNONE},
+{{OOO_STRING_SVTOOLS_RTF_AULW}, RTF_AULW},
+{{OOO_STRING_SVTOOLS_RTF_AUP}, RTF_AUP},
+{{OOO_STRING_SVTOOLS_RTF_BKMKPUB}, RTF_BKMKPUB},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDASH}, RTF_BRDRDASH},
+{{OOO_STRING_SVTOOLS_RTF_BRKFRM}, RTF_BRKFRM},
+{{OOO_STRING_SVTOOLS_RTF_CCHS}, RTF_CCHS},
+{{OOO_STRING_SVTOOLS_RTF_CPG}, RTF_CPG},
+{{OOO_STRING_SVTOOLS_RTF_CS}, RTF_CS},
+{{OOO_STRING_SVTOOLS_RTF_CVMME}, RTF_CVMME},
+{{OOO_STRING_SVTOOLS_RTF_DATAFIELD}, RTF_DATAFIELD},
+{{OOO_STRING_SVTOOLS_RTF_DO}, RTF_DO},
+{{OOO_STRING_SVTOOLS_RTF_DOBXCOLUMN}, RTF_DOBXCOLUMN},
+{{OOO_STRING_SVTOOLS_RTF_DOBXMARGIN}, RTF_DOBXMARGIN},
+{{OOO_STRING_SVTOOLS_RTF_DOBXPAGE}, RTF_DOBXPAGE},
+{{OOO_STRING_SVTOOLS_RTF_DOBYMARGIN}, RTF_DOBYMARGIN},
+{{OOO_STRING_SVTOOLS_RTF_DOBYPAGE}, RTF_DOBYPAGE},
+{{OOO_STRING_SVTOOLS_RTF_DOBYPARA}, RTF_DOBYPARA},
+{{OOO_STRING_SVTOOLS_RTF_DODHGT}, RTF_DODHGT},
+{{OOO_STRING_SVTOOLS_RTF_DOLOCK}, RTF_DOLOCK},
+{{OOO_STRING_SVTOOLS_RTF_DPAENDHOL}, RTF_DPAENDHOL},
+{{OOO_STRING_SVTOOLS_RTF_DPAENDL}, RTF_DPAENDL},
+{{OOO_STRING_SVTOOLS_RTF_DPAENDSOL}, RTF_DPAENDSOL},
+{{OOO_STRING_SVTOOLS_RTF_DPAENDW}, RTF_DPAENDW},
+{{OOO_STRING_SVTOOLS_RTF_DPARC}, RTF_DPARC},
+{{OOO_STRING_SVTOOLS_RTF_DPARCFLIPX}, RTF_DPARCFLIPX},
+{{OOO_STRING_SVTOOLS_RTF_DPARCFLIPY}, RTF_DPARCFLIPY},
+{{OOO_STRING_SVTOOLS_RTF_DPASTARTHOL}, RTF_DPASTARTHOL},
+{{OOO_STRING_SVTOOLS_RTF_DPASTARTL}, RTF_DPASTARTL},
+{{OOO_STRING_SVTOOLS_RTF_DPASTARTSOL}, RTF_DPASTARTSOL},
+{{OOO_STRING_SVTOOLS_RTF_DPASTARTW}, RTF_DPASTARTW},
+{{OOO_STRING_SVTOOLS_RTF_DPCALLOUT}, RTF_DPCALLOUT},
+{{OOO_STRING_SVTOOLS_RTF_DPCOA}, RTF_DPCOA},
+{{OOO_STRING_SVTOOLS_RTF_DPCOACCENT}, RTF_DPCOACCENT},
+{{OOO_STRING_SVTOOLS_RTF_DPCOBESTFIT}, RTF_DPCOBESTFIT},
+{{OOO_STRING_SVTOOLS_RTF_DPCOBORDER}, RTF_DPCOBORDER},
+{{OOO_STRING_SVTOOLS_RTF_DPCODABS}, RTF_DPCODABS},
+{{OOO_STRING_SVTOOLS_RTF_DPCODBOTTOM}, RTF_DPCODBOTTOM},
+{{OOO_STRING_SVTOOLS_RTF_DPCODCENTER}, RTF_DPCODCENTER},
+{{OOO_STRING_SVTOOLS_RTF_DPCODTOP}, RTF_DPCODTOP},
+{{OOO_STRING_SVTOOLS_RTF_DPCOLENGTH}, RTF_DPCOLENGTH},
+{{OOO_STRING_SVTOOLS_RTF_DPCOMINUSX}, RTF_DPCOMINUSX},
+{{OOO_STRING_SVTOOLS_RTF_DPCOMINUSY}, RTF_DPCOMINUSY},
+{{OOO_STRING_SVTOOLS_RTF_DPCOOFFSET}, RTF_DPCOOFFSET},
+{{OOO_STRING_SVTOOLS_RTF_DPCOSMARTA}, RTF_DPCOSMARTA},
+{{OOO_STRING_SVTOOLS_RTF_DPCOTDOUBLE}, RTF_DPCOTDOUBLE},
+{{OOO_STRING_SVTOOLS_RTF_DPCOTRIGHT}, RTF_DPCOTRIGHT},
+{{OOO_STRING_SVTOOLS_RTF_DPCOTSINGLE}, RTF_DPCOTSINGLE},
+{{OOO_STRING_SVTOOLS_RTF_DPCOTTRIPLE}, RTF_DPCOTTRIPLE},
+{{OOO_STRING_SVTOOLS_RTF_DPCOUNT}, RTF_DPCOUNT},
+{{OOO_STRING_SVTOOLS_RTF_DPELLIPSE}, RTF_DPELLIPSE},
+{{OOO_STRING_SVTOOLS_RTF_DPENDGROUP}, RTF_DPENDGROUP},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLBGCB}, RTF_DPFILLBGCB},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLBGCG}, RTF_DPFILLBGCG},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLBGCR}, RTF_DPFILLBGCR},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLBGGRAY}, RTF_DPFILLBGGRAY},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLBGPAL}, RTF_DPFILLBGPAL},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLFGCB}, RTF_DPFILLFGCB},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLFGCG}, RTF_DPFILLFGCG},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLFGCR}, RTF_DPFILLFGCR},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLFGGRAY}, RTF_DPFILLFGGRAY},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLFGPAL}, RTF_DPFILLFGPAL},
+{{OOO_STRING_SVTOOLS_RTF_DPFILLPAT}, RTF_DPFILLPAT},
+{{OOO_STRING_SVTOOLS_RTF_DPGROUP}, RTF_DPGROUP},
+{{OOO_STRING_SVTOOLS_RTF_DPLINE}, RTF_DPLINE},
+{{OOO_STRING_SVTOOLS_RTF_DPLINECOB}, RTF_DPLINECOB},
+{{OOO_STRING_SVTOOLS_RTF_DPLINECOG}, RTF_DPLINECOG},
+{{OOO_STRING_SVTOOLS_RTF_DPLINECOR}, RTF_DPLINECOR},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEDADO}, RTF_DPLINEDADO},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEDADODO}, RTF_DPLINEDADODO},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEDASH}, RTF_DPLINEDASH},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEDOT}, RTF_DPLINEDOT},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEGRAY}, RTF_DPLINEGRAY},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEHOLLOW}, RTF_DPLINEHOLLOW},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEPAL}, RTF_DPLINEPAL},
+{{OOO_STRING_SVTOOLS_RTF_DPLINESOLID}, RTF_DPLINESOLID},
+{{OOO_STRING_SVTOOLS_RTF_DPLINEW}, RTF_DPLINEW},
+{{OOO_STRING_SVTOOLS_RTF_DPPOLYCOUNT}, RTF_DPPOLYCOUNT},
+{{OOO_STRING_SVTOOLS_RTF_DPPOLYGON}, RTF_DPPOLYGON},
+{{OOO_STRING_SVTOOLS_RTF_DPPOLYLINE}, RTF_DPPOLYLINE},
+{{OOO_STRING_SVTOOLS_RTF_DPPTX}, RTF_DPPTX},
+{{OOO_STRING_SVTOOLS_RTF_DPPTY}, RTF_DPPTY},
+{{OOO_STRING_SVTOOLS_RTF_DPRECT}, RTF_DPRECT},
+{{OOO_STRING_SVTOOLS_RTF_DPROUNDR}, RTF_DPROUNDR},
+{{OOO_STRING_SVTOOLS_RTF_DPSHADOW}, RTF_DPSHADOW},
+{{OOO_STRING_SVTOOLS_RTF_DPSHADX}, RTF_DPSHADX},
+{{OOO_STRING_SVTOOLS_RTF_DPSHADY}, RTF_DPSHADY},
+{{OOO_STRING_SVTOOLS_RTF_DPTXBX}, RTF_DPTXBX},
+{{OOO_STRING_SVTOOLS_RTF_DPTXBXMAR}, RTF_DPTXBXMAR},
+{{OOO_STRING_SVTOOLS_RTF_DPTXBXTEXT}, RTF_DPTXBXTEXT},
+{{OOO_STRING_SVTOOLS_RTF_DPX}, RTF_DPX},
+{{OOO_STRING_SVTOOLS_RTF_DPXSIZE}, RTF_DPXSIZE},
+{{OOO_STRING_SVTOOLS_RTF_DPY}, RTF_DPY},
+{{OOO_STRING_SVTOOLS_RTF_DPYSIZE}, RTF_DPYSIZE},
+{{OOO_STRING_SVTOOLS_RTF_DS}, RTF_DS},
+{{OOO_STRING_SVTOOLS_RTF_EMSPACE}, RTF_EMSPACE},
+{{OOO_STRING_SVTOOLS_RTF_ENSPACE}, RTF_ENSPACE},
+{{OOO_STRING_SVTOOLS_RTF_FBIDI}, RTF_FBIDI},
+{{OOO_STRING_SVTOOLS_RTF_FET}, RTF_FET},
+{{OOO_STRING_SVTOOLS_RTF_FID}, RTF_FID},
+{{OOO_STRING_SVTOOLS_RTF_FILE}, RTF_FILE},
+{{OOO_STRING_SVTOOLS_RTF_FILETBL}, RTF_FILETBL},
+{{OOO_STRING_SVTOOLS_RTF_FLDALT}, RTF_FLDALT},
+{{OOO_STRING_SVTOOLS_RTF_FNETWORK}, RTF_FNETWORK},
+{{OOO_STRING_SVTOOLS_RTF_FONTEMB}, RTF_FONTEMB},
+{{OOO_STRING_SVTOOLS_RTF_FONTFILE}, RTF_FONTFILE},
+{{OOO_STRING_SVTOOLS_RTF_FORMDISP}, RTF_FORMDISP},
+{{OOO_STRING_SVTOOLS_RTF_FORMPROT}, RTF_FORMPROT},
+{{OOO_STRING_SVTOOLS_RTF_FORMSHADE}, RTF_FORMSHADE},
+{{OOO_STRING_SVTOOLS_RTF_FOSNUM}, RTF_FOSNUM},
+{{OOO_STRING_SVTOOLS_RTF_FRELATIVE}, RTF_FRELATIVE},
+{{OOO_STRING_SVTOOLS_RTF_FTNALT}, RTF_FTNALT},
+{{OOO_STRING_SVTOOLS_RTF_FTNIL}, RTF_FTNIL},
+{{OOO_STRING_SVTOOLS_RTF_FTNNALC}, RTF_FTNNALC},
+{{OOO_STRING_SVTOOLS_RTF_FTNNAR}, RTF_FTNNAR},
+{{OOO_STRING_SVTOOLS_RTF_FTNNAUC}, RTF_FTNNAUC},
+{{OOO_STRING_SVTOOLS_RTF_FTNNCHI}, RTF_FTNNCHI},
+{{OOO_STRING_SVTOOLS_RTF_FTNNRLC}, RTF_FTNNRLC},
+{{OOO_STRING_SVTOOLS_RTF_FTNNRUC}, RTF_FTNNRUC},
+{{OOO_STRING_SVTOOLS_RTF_FTNRSTCONT}, RTF_FTNRSTCONT},
+{{OOO_STRING_SVTOOLS_RTF_FTNRSTPG}, RTF_FTNRSTPG},
+{{OOO_STRING_SVTOOLS_RTF_FTTRUETYPE}, RTF_FTTRUETYPE},
+{{OOO_STRING_SVTOOLS_RTF_FVALIDDOS}, RTF_FVALIDDOS},
+{{OOO_STRING_SVTOOLS_RTF_FVALIDHPFS}, RTF_FVALIDHPFS},
+{{OOO_STRING_SVTOOLS_RTF_FVALIDMAC}, RTF_FVALIDMAC},
+{{OOO_STRING_SVTOOLS_RTF_FVALIDNTFS}, RTF_FVALIDNTFS},
+{{OOO_STRING_SVTOOLS_RTF_HYPHAUTO}, RTF_HYPHAUTO},
+{{OOO_STRING_SVTOOLS_RTF_HYPHCAPS}, RTF_HYPHCAPS},
+{{OOO_STRING_SVTOOLS_RTF_HYPHCONSEC}, RTF_HYPHCONSEC},
+{{OOO_STRING_SVTOOLS_RTF_HYPHPAR}, RTF_HYPHPAR},
+{{OOO_STRING_SVTOOLS_RTF_LINKSELF}, RTF_LINKSELF},
+{{OOO_STRING_SVTOOLS_RTF_LINKSTYLES}, RTF_LINKSTYLES},
+{{OOO_STRING_SVTOOLS_RTF_LTRCH}, RTF_LTRCH},
+{{OOO_STRING_SVTOOLS_RTF_LTRDOC}, RTF_LTRDOC},
+{{OOO_STRING_SVTOOLS_RTF_LTRMARK}, RTF_LTRMARK},
+{{OOO_STRING_SVTOOLS_RTF_LTRPAR}, RTF_LTRPAR},
+{{OOO_STRING_SVTOOLS_RTF_LTRROW}, RTF_LTRROW},
+{{OOO_STRING_SVTOOLS_RTF_LTRSECT}, RTF_LTRSECT},
+{{OOO_STRING_SVTOOLS_RTF_NOCOLBAL}, RTF_NOCOLBAL},
+{{OOO_STRING_SVTOOLS_RTF_NOEXTRASPRL}, RTF_NOEXTRASPRL},
+{{OOO_STRING_SVTOOLS_RTF_NOTABIND}, RTF_NOTABIND},
+{{OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR}, RTF_NOWIDCTLPAR},
+{{OOO_STRING_SVTOOLS_RTF_OBJALIAS}, RTF_OBJALIAS},
+{{OOO_STRING_SVTOOLS_RTF_OBJALIGN}, RTF_OBJALIGN},
+{{OOO_STRING_SVTOOLS_RTF_OBJAUTLINK}, RTF_OBJAUTLINK},
+{{OOO_STRING_SVTOOLS_RTF_OBJCLASS}, RTF_OBJCLASS},
+{{OOO_STRING_SVTOOLS_RTF_OBJCROPB}, RTF_OBJCROPB},
+{{OOO_STRING_SVTOOLS_RTF_OBJCROPL}, RTF_OBJCROPL},
+{{OOO_STRING_SVTOOLS_RTF_OBJCROPR}, RTF_OBJCROPR},
+{{OOO_STRING_SVTOOLS_RTF_OBJCROPT}, RTF_OBJCROPT},
+{{OOO_STRING_SVTOOLS_RTF_OBJDATA}, RTF_OBJDATA},
+{{OOO_STRING_SVTOOLS_RTF_OBJECT}, RTF_OBJECT},
+{{OOO_STRING_SVTOOLS_RTF_OBJEMB}, RTF_OBJEMB},
+{{OOO_STRING_SVTOOLS_RTF_OBJH}, RTF_OBJH},
+{{OOO_STRING_SVTOOLS_RTF_OBJICEMB}, RTF_OBJICEMB},
+{{OOO_STRING_SVTOOLS_RTF_OBJLINK}, RTF_OBJLINK},
+{{OOO_STRING_SVTOOLS_RTF_OBJLOCK}, RTF_OBJLOCK},
+{{OOO_STRING_SVTOOLS_RTF_OBJNAME}, RTF_OBJNAME},
+{{OOO_STRING_SVTOOLS_RTF_OBJPUB}, RTF_OBJPUB},
+{{OOO_STRING_SVTOOLS_RTF_OBJSCALEX}, RTF_OBJSCALEX},
+{{OOO_STRING_SVTOOLS_RTF_OBJSCALEY}, RTF_OBJSCALEY},
+{{OOO_STRING_SVTOOLS_RTF_OBJSECT}, RTF_OBJSECT},
+{{OOO_STRING_SVTOOLS_RTF_OBJSETSIZE}, RTF_OBJSETSIZE},
+{{OOO_STRING_SVTOOLS_RTF_OBJSUB}, RTF_OBJSUB},
+{{OOO_STRING_SVTOOLS_RTF_OBJTIME}, RTF_OBJTIME},
+{{OOO_STRING_SVTOOLS_RTF_OBJTRANSY}, RTF_OBJTRANSY},
+{{OOO_STRING_SVTOOLS_RTF_OBJUPDATE}, RTF_OBJUPDATE},
+{{OOO_STRING_SVTOOLS_RTF_OBJW}, RTF_OBJW},
+{{OOO_STRING_SVTOOLS_RTF_OTBLRUL}, RTF_OTBLRUL},
+{{OOO_STRING_SVTOOLS_RTF_PGNHN}, RTF_PGNHN},
+{{OOO_STRING_SVTOOLS_RTF_PGNHNSC}, RTF_PGNHNSC},
+{{OOO_STRING_SVTOOLS_RTF_PGNHNSH}, RTF_PGNHNSH},
+{{OOO_STRING_SVTOOLS_RTF_PGNHNSM}, RTF_PGNHNSM},
+{{OOO_STRING_SVTOOLS_RTF_PGNHNSN}, RTF_PGNHNSN},
+{{OOO_STRING_SVTOOLS_RTF_PGNHNSP}, RTF_PGNHNSP},
+{{OOO_STRING_SVTOOLS_RTF_PICBMP}, RTF_PICBMP},
+{{OOO_STRING_SVTOOLS_RTF_PICBPP}, RTF_PICBPP},
+{{OOO_STRING_SVTOOLS_RTF_PN}, RTF_PN},
+{{OOO_STRING_SVTOOLS_RTF_PNACROSS}, RTF_PNACROSS},
+{{OOO_STRING_SVTOOLS_RTF_PNB}, RTF_PNB},
+{{OOO_STRING_SVTOOLS_RTF_PNCAPS}, RTF_PNCAPS},
+{{OOO_STRING_SVTOOLS_RTF_PNCARD}, RTF_PNCARD},
+{{OOO_STRING_SVTOOLS_RTF_PNCF}, RTF_PNCF},
+{{OOO_STRING_SVTOOLS_RTF_PNDEC}, RTF_PNDEC},
+{{OOO_STRING_SVTOOLS_RTF_PNF}, RTF_PNF},
+{{OOO_STRING_SVTOOLS_RTF_PNFS}, RTF_PNFS},
+{{OOO_STRING_SVTOOLS_RTF_PNHANG}, RTF_PNHANG},
+{{OOO_STRING_SVTOOLS_RTF_PNI}, RTF_PNI},
+{{OOO_STRING_SVTOOLS_RTF_PNINDENT}, RTF_PNINDENT},
+{{OOO_STRING_SVTOOLS_RTF_PNLCLTR}, RTF_PNLCLTR},
+{{OOO_STRING_SVTOOLS_RTF_PNLCRM}, RTF_PNLCRM},
+{{OOO_STRING_SVTOOLS_RTF_PNLVL}, RTF_PNLVL},
+{{OOO_STRING_SVTOOLS_RTF_PNLVLBLT}, RTF_PNLVLBLT},
+{{OOO_STRING_SVTOOLS_RTF_PNLVLBODY}, RTF_PNLVLBODY},
+{{OOO_STRING_SVTOOLS_RTF_PNLVLCONT}, RTF_PNLVLCONT},
+{{OOO_STRING_SVTOOLS_RTF_PNNUMONCE}, RTF_PNNUMONCE},
+{{OOO_STRING_SVTOOLS_RTF_PNORD}, RTF_PNORD},
+{{OOO_STRING_SVTOOLS_RTF_PNORDT}, RTF_PNORDT},
+{{OOO_STRING_SVTOOLS_RTF_PNPREV}, RTF_PNPREV},
+{{OOO_STRING_SVTOOLS_RTF_PNQC}, RTF_PNQC},
+{{OOO_STRING_SVTOOLS_RTF_PNQL}, RTF_PNQL},
+{{OOO_STRING_SVTOOLS_RTF_PNQR}, RTF_PNQR},
+{{OOO_STRING_SVTOOLS_RTF_PNRESTART}, RTF_PNRESTART},
+{{OOO_STRING_SVTOOLS_RTF_PNSCAPS}, RTF_PNSCAPS},
+{{OOO_STRING_SVTOOLS_RTF_PNSECLVL}, RTF_PNSECLVL},
+{{OOO_STRING_SVTOOLS_RTF_PNSP}, RTF_PNSP},
+{{OOO_STRING_SVTOOLS_RTF_PNSTART}, RTF_PNSTART},
+{{OOO_STRING_SVTOOLS_RTF_PNSTRIKE}, RTF_PNSTRIKE},
+{{OOO_STRING_SVTOOLS_RTF_PNTEXT}, RTF_PNTEXT},
+{{OOO_STRING_SVTOOLS_RTF_PNTXTA}, RTF_PNTXTA},
+{{OOO_STRING_SVTOOLS_RTF_PNTXTB}, RTF_PNTXTB},
+{{OOO_STRING_SVTOOLS_RTF_PNUCLTR}, RTF_PNUCLTR},
+{{OOO_STRING_SVTOOLS_RTF_PNUCRM}, RTF_PNUCRM},
+{{OOO_STRING_SVTOOLS_RTF_PNUL}, RTF_PNUL},
+{{OOO_STRING_SVTOOLS_RTF_PNULD}, RTF_PNULD},
+{{OOO_STRING_SVTOOLS_RTF_PNULDB}, RTF_PNULDB},
+{{OOO_STRING_SVTOOLS_RTF_PNULNONE}, RTF_PNULNONE},
+{{OOO_STRING_SVTOOLS_RTF_PNULW}, RTF_PNULW},
+{{OOO_STRING_SVTOOLS_RTF_PRCOLBL}, RTF_PRCOLBL},
+{{OOO_STRING_SVTOOLS_RTF_PRINTDATA}, RTF_PRINTDATA},
+{{OOO_STRING_SVTOOLS_RTF_PSZ}, RTF_PSZ},
+{{OOO_STRING_SVTOOLS_RTF_PUBAUTO}, RTF_PUBAUTO},
+{{OOO_STRING_SVTOOLS_RTF_RESULT}, RTF_RESULT},
+{{OOO_STRING_SVTOOLS_RTF_REVAUTH}, RTF_REVAUTH},
+{{OOO_STRING_SVTOOLS_RTF_REVDTTM}, RTF_REVDTTM},
+{{OOO_STRING_SVTOOLS_RTF_REVPROT}, RTF_REVPROT},
+{{OOO_STRING_SVTOOLS_RTF_REVTBL}, RTF_REVTBL},
+{{OOO_STRING_SVTOOLS_RTF_RSLTBMP}, RTF_RSLTBMP},
+{{OOO_STRING_SVTOOLS_RTF_RSLTMERGE}, RTF_RSLTMERGE},
+{{OOO_STRING_SVTOOLS_RTF_RSLTPICT}, RTF_RSLTPICT},
+{{OOO_STRING_SVTOOLS_RTF_RSLTRTF}, RTF_RSLTRTF},
+{{OOO_STRING_SVTOOLS_RTF_RSLTTXT}, RTF_RSLTTXT},
+{{OOO_STRING_SVTOOLS_RTF_RTLCH}, RTF_RTLCH},
+{{OOO_STRING_SVTOOLS_RTF_RTLDOC}, RTF_RTLDOC},
+{{OOO_STRING_SVTOOLS_RTF_RTLMARK}, RTF_RTLMARK},
+{{OOO_STRING_SVTOOLS_RTF_RTLPAR}, RTF_RTLPAR},
+{{OOO_STRING_SVTOOLS_RTF_RTLROW}, RTF_RTLROW},
+{{OOO_STRING_SVTOOLS_RTF_RTLSECT}, RTF_RTLSECT},
+{{OOO_STRING_SVTOOLS_RTF_SEC}, RTF_SEC},
+{{OOO_STRING_SVTOOLS_RTF_SECTNUM}, RTF_SECTNUM},
+{{OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED}, RTF_SECTUNLOCKED},
+{{OOO_STRING_SVTOOLS_RTF_SLMULT}, RTF_SLMULT},
+{{OOO_STRING_SVTOOLS_RTF_SOFTCOL}, RTF_SOFTCOL},
+{{OOO_STRING_SVTOOLS_RTF_SOFTLHEIGHT}, RTF_SOFTLHEIGHT},
+{{OOO_STRING_SVTOOLS_RTF_SOFTLINE}, RTF_SOFTLINE},
+{{OOO_STRING_SVTOOLS_RTF_SOFTPAGE}, RTF_SOFTPAGE},
+{{OOO_STRING_SVTOOLS_RTF_SPRSSPBF}, RTF_SPRSSPBF},
+{{OOO_STRING_SVTOOLS_RTF_SPRSTSP}, RTF_SPRSTSP},
+{{OOO_STRING_SVTOOLS_RTF_SUBDOCUMENT}, RTF_SUBDOCUMENT},
+{{OOO_STRING_SVTOOLS_RTF_SWPBDR}, RTF_SWPBDR},
+{{OOO_STRING_SVTOOLS_RTF_TCN}, RTF_TCN},
+{{OOO_STRING_SVTOOLS_RTF_TRANSMF}, RTF_TRANSMF},
+{{OOO_STRING_SVTOOLS_RTF_TRBRDRB}, RTF_TRBRDRB},
+{{OOO_STRING_SVTOOLS_RTF_TRBRDRH}, RTF_TRBRDRH},
+{{OOO_STRING_SVTOOLS_RTF_TRBRDRL}, RTF_TRBRDRL},
+{{OOO_STRING_SVTOOLS_RTF_TRBRDRR}, RTF_TRBRDRR},
+{{OOO_STRING_SVTOOLS_RTF_TRBRDRT}, RTF_TRBRDRT},
+{{OOO_STRING_SVTOOLS_RTF_TRBRDRV}, RTF_TRBRDRV},
+{{OOO_STRING_SVTOOLS_RTF_TRHDR}, RTF_TRHDR},
+{{OOO_STRING_SVTOOLS_RTF_TRKEEP}, RTF_TRKEEP},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDB}, RTF_TRPADDB},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDL}, RTF_TRPADDL},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDR}, RTF_TRPADDR},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDT}, RTF_TRPADDT},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDFB}, RTF_TRPADDFB},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDFL}, RTF_TRPADDFL},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDFR}, RTF_TRPADDFR},
+{{OOO_STRING_SVTOOLS_RTF_TRPADDFT}, RTF_TRPADDFT},
+
+
+{{OOO_STRING_SVTOOLS_RTF_WRAPTRSP}, RTF_WRAPTRSP},
+{{OOO_STRING_SVTOOLS_RTF_XEF}, RTF_XEF},
+{{OOO_STRING_SVTOOLS_RTF_ZWJ}, RTF_ZWJ},
+{{OOO_STRING_SVTOOLS_RTF_ZWNJ}, RTF_ZWNJ},
+
+
+{{OOO_STRING_SVTOOLS_RTF_ABSLOCK}, RTF_ABSLOCK},
+{{OOO_STRING_SVTOOLS_RTF_ADJUSTRIGHT}, RTF_ADJUSTRIGHT},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNCHOSUNG}, RTF_AFTNNCHOSUNG},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNCNUM}, RTF_AFTNNCNUM},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNDBAR}, RTF_AFTNNDBAR},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNDBNUM}, RTF_AFTNNDBNUM},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNDBNUMD}, RTF_AFTNNDBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNDBNUMK}, RTF_AFTNNDBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNDBNUMT}, RTF_AFTNNDBNUMT},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNGANADA}, RTF_AFTNNGANADA},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNGBNUM}, RTF_AFTNNGBNUM},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNGBNUMD}, RTF_AFTNNGBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNGBNUMK}, RTF_AFTNNGBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNGBNUML}, RTF_AFTNNGBNUML},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNZODIAC}, RTF_AFTNNZODIAC},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNZODIACD}, RTF_AFTNNZODIACD},
+{{OOO_STRING_SVTOOLS_RTF_AFTNNZODIACL}, RTF_AFTNNZODIACL},
+{{OOO_STRING_SVTOOLS_RTF_ANIMTEXT}, RTF_ANIMTEXT},
+{{OOO_STRING_SVTOOLS_RTF_ANSICPG}, RTF_ANSICPG},
+{{OOO_STRING_SVTOOLS_RTF_BACKGROUND}, RTF_BACKGROUND},
+{{OOO_STRING_SVTOOLS_RTF_BDBFHDR}, RTF_BDBFHDR},
+{{OOO_STRING_SVTOOLS_RTF_BLIPTAG}, RTF_BLIPTAG},
+{{OOO_STRING_SVTOOLS_RTF_BLIPUID}, RTF_BLIPUID},
+{{OOO_STRING_SVTOOLS_RTF_BLIPUPI}, RTF_BLIPUPI},
+{{OOO_STRING_SVTOOLS_RTF_BRDRART}, RTF_BRDRART},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDASHD}, RTF_BRDRDASHD},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDASHDD}, RTF_BRDRDASHDD},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDASHDOTSTR},RTF_BRDRDASHDOTSTR},
+{{OOO_STRING_SVTOOLS_RTF_BRDRDASHSM}, RTF_BRDRDASHSM},
+{{OOO_STRING_SVTOOLS_RTF_BRDREMBOSS}, RTF_BRDREMBOSS},
+{{OOO_STRING_SVTOOLS_RTF_BRDRENGRAVE}, RTF_BRDRENGRAVE},
+{{OOO_STRING_SVTOOLS_RTF_BRDRFRAME}, RTF_BRDRFRAME},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTHTNLG}, RTF_BRDRTHTNLG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTHTNMG}, RTF_BRDRTHTNMG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTHTNSG}, RTF_BRDRTHTNSG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTNTHLG}, RTF_BRDRTNTHLG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTNTHMG}, RTF_BRDRTNTHMG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG}, RTF_BRDRTNTHSG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTNTHTNLG}, RTF_BRDRTNTHTNLG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTNTHTNMG}, RTF_BRDRTNTHTNMG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTNTHTNSG}, RTF_BRDRTNTHTNSG},
+{{OOO_STRING_SVTOOLS_RTF_BRDRTRIPLE}, RTF_BRDRTRIPLE},
+{{OOO_STRING_SVTOOLS_RTF_BRDRWAVY}, RTF_BRDRWAVY},
+{{OOO_STRING_SVTOOLS_RTF_BRDRWAVYDB}, RTF_BRDRWAVYDB},
+{{OOO_STRING_SVTOOLS_RTF_CATEGORY}, RTF_CATEGORY},
+{{OOO_STRING_SVTOOLS_RTF_CGRID}, RTF_CGRID},
+{{OOO_STRING_SVTOOLS_RTF_CHARSCALEX}, RTF_CHARSCALEX},
+{{OOO_STRING_SVTOOLS_RTF_CHBGBDIAG}, RTF_CHBGBDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CHBGCROSS}, RTF_CHBGCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDCROSS}, RTF_CHBGDCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDKBDIAG}, RTF_CHBGDKBDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDKCROSS}, RTF_CHBGDKCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDKDCROSS}, RTF_CHBGDKDCROSS},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDKFDIAG}, RTF_CHBGDKFDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDKHORIZ}, RTF_CHBGDKHORIZ},
+{{OOO_STRING_SVTOOLS_RTF_CHBGDKVERT}, RTF_CHBGDKVERT},
+{{OOO_STRING_SVTOOLS_RTF_CHBGFDIAG}, RTF_CHBGFDIAG},
+{{OOO_STRING_SVTOOLS_RTF_CHBGHORIZ}, RTF_CHBGHORIZ},
+{{OOO_STRING_SVTOOLS_RTF_CHBGVERT}, RTF_CHBGVERT},
+{{OOO_STRING_SVTOOLS_RTF_CHBRDR}, RTF_CHBRDR},
+{{OOO_STRING_SVTOOLS_RTF_CHCBPAT}, RTF_CHCBPAT},
+{{OOO_STRING_SVTOOLS_RTF_CHCFPAT}, RTF_CHCFPAT},
+{{OOO_STRING_SVTOOLS_RTF_CHSHDNG}, RTF_CHSHDNG},
+{{OOO_STRING_SVTOOLS_RTF_CLTXLRTB}, RTF_CLTXLRTB},
+{{OOO_STRING_SVTOOLS_RTF_CLTXTBRL}, RTF_CLTXTBRL},
+{{OOO_STRING_SVTOOLS_RTF_CLVERTALB}, RTF_CLVERTALB},
+{{OOO_STRING_SVTOOLS_RTF_CLVERTALC}, RTF_CLVERTALC},
+{{OOO_STRING_SVTOOLS_RTF_CLVERTALT}, RTF_CLVERTALT},
+{{OOO_STRING_SVTOOLS_RTF_CLVMGF}, RTF_CLVMGF},
+{{OOO_STRING_SVTOOLS_RTF_CLVMRG}, RTF_CLVMRG},
+{{OOO_STRING_SVTOOLS_RTF_CLTXTBRLV}, RTF_CLTXTBRLV},
+{{OOO_STRING_SVTOOLS_RTF_CLTXBTLR}, RTF_CLTXBTLR},
+{{OOO_STRING_SVTOOLS_RTF_CLTXLRTBV}, RTF_CLTXLRTBV},
+{{OOO_STRING_SVTOOLS_RTF_COMPANY}, RTF_COMPANY},
+{{OOO_STRING_SVTOOLS_RTF_CRAUTH}, RTF_CRAUTH},
+{{OOO_STRING_SVTOOLS_RTF_CRDATE}, RTF_CRDATE},
+{{OOO_STRING_SVTOOLS_RTF_DATE}, RTF_DATE},
+{{OOO_STRING_SVTOOLS_RTF_DEFLANGFE}, RTF_DEFLANGFE},
+{{OOO_STRING_SVTOOLS_RTF_DFRAUTH}, RTF_DFRAUTH},
+{{OOO_STRING_SVTOOLS_RTF_DFRDATE}, RTF_DFRDATE},
+{{OOO_STRING_SVTOOLS_RTF_DFRSTART}, RTF_DFRSTART},
+{{OOO_STRING_SVTOOLS_RTF_DFRSTOP}, RTF_DFRSTOP},
+{{OOO_STRING_SVTOOLS_RTF_DFRXST}, RTF_DFRXST},
+{{OOO_STRING_SVTOOLS_RTF_DGMARGIN}, RTF_DGMARGIN},
+{{OOO_STRING_SVTOOLS_RTF_DNTBLNSBDB}, RTF_DNTBLNSBDB},
+{{OOO_STRING_SVTOOLS_RTF_DOCTYPE}, RTF_DOCTYPE},
+{{OOO_STRING_SVTOOLS_RTF_DOCVAR}, RTF_DOCVAR},
+{{OOO_STRING_SVTOOLS_RTF_DPCODESCENT}, RTF_DPCODESCENT},
+{{OOO_STRING_SVTOOLS_RTF_EMBO}, RTF_EMBO},
+{{OOO_STRING_SVTOOLS_RTF_EMFBLIP}, RTF_EMFBLIP},
+{{OOO_STRING_SVTOOLS_RTF_EXPSHRTN}, RTF_EXPSHRTN},
+{{OOO_STRING_SVTOOLS_RTF_FAAUTO}, RTF_FAAUTO},
+{{OOO_STRING_SVTOOLS_RTF_FBIAS}, RTF_FBIAS},
+{{OOO_STRING_SVTOOLS_RTF_FFDEFRES}, RTF_FFDEFRES},
+{{OOO_STRING_SVTOOLS_RTF_FFDEFTEXT}, RTF_FFDEFTEXT},
+{{OOO_STRING_SVTOOLS_RTF_FFENTRYMCR}, RTF_FFENTRYMCR},
+{{OOO_STRING_SVTOOLS_RTF_FFEXITMCR}, RTF_FFEXITMCR},
+{{OOO_STRING_SVTOOLS_RTF_FFFORMAT}, RTF_FFFORMAT},
+{{OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX}, RTF_FFHASLISTBOX},
+{{OOO_STRING_SVTOOLS_RTF_FFHELPTEXT}, RTF_FFHELPTEXT},
+{{OOO_STRING_SVTOOLS_RTF_FFHPS}, RTF_FFHPS},
+{{OOO_STRING_SVTOOLS_RTF_FFL}, RTF_FFL},
+{{OOO_STRING_SVTOOLS_RTF_FFMAXLEN}, RTF_FFMAXLEN},
+{{OOO_STRING_SVTOOLS_RTF_FFNAME}, RTF_FFNAME},
+{{OOO_STRING_SVTOOLS_RTF_FFOWNHELP}, RTF_FFOWNHELP},
+{{OOO_STRING_SVTOOLS_RTF_FFOWNSTAT}, RTF_FFOWNSTAT},
+{{OOO_STRING_SVTOOLS_RTF_FFPROT}, RTF_FFPROT},
+{{OOO_STRING_SVTOOLS_RTF_FFRECALC}, RTF_FFRECALC},
+{{OOO_STRING_SVTOOLS_RTF_FFRES}, RTF_FFRES},
+{{OOO_STRING_SVTOOLS_RTF_FFSIZE}, RTF_FFSIZE},
+{{OOO_STRING_SVTOOLS_RTF_FFSTATTEXT}, RTF_FFSTATTEXT},
+{{OOO_STRING_SVTOOLS_RTF_FFTYPE}, RTF_FFTYPE},
+{{OOO_STRING_SVTOOLS_RTF_FFTYPETXT}, RTF_FFTYPETXT},
+{{OOO_STRING_SVTOOLS_RTF_FLDTYPE}, RTF_FLDTYPE},
+{{OOO_STRING_SVTOOLS_RTF_FNAME}, RTF_FNAME},
+{{OOO_STRING_SVTOOLS_RTF_FORMFIELD}, RTF_FORMFIELD},
+{{OOO_STRING_SVTOOLS_RTF_FROMTEXT}, RTF_FROMTEXT},
+{{OOO_STRING_SVTOOLS_RTF_FTNNCHOSUNG}, RTF_FTNNCHOSUNG},
+{{OOO_STRING_SVTOOLS_RTF_FTNNCNUM}, RTF_FTNNCNUM},
+{{OOO_STRING_SVTOOLS_RTF_FTNNDBAR}, RTF_FTNNDBAR},
+{{OOO_STRING_SVTOOLS_RTF_FTNNDBNUM}, RTF_FTNNDBNUM},
+{{OOO_STRING_SVTOOLS_RTF_FTNNDBNUMD}, RTF_FTNNDBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_FTNNDBNUMK}, RTF_FTNNDBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_FTNNDBNUMT}, RTF_FTNNDBNUMT},
+{{OOO_STRING_SVTOOLS_RTF_FTNNGANADA}, RTF_FTNNGANADA},
+{{OOO_STRING_SVTOOLS_RTF_FTNNGBNUM}, RTF_FTNNGBNUM},
+{{OOO_STRING_SVTOOLS_RTF_FTNNGBNUMD}, RTF_FTNNGBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_FTNNGBNUMK}, RTF_FTNNGBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_FTNNGBNUML}, RTF_FTNNGBNUML},
+{{OOO_STRING_SVTOOLS_RTF_FTNNZODIAC}, RTF_FTNNZODIAC},
+{{OOO_STRING_SVTOOLS_RTF_FTNNZODIACD}, RTF_FTNNZODIACD},
+{{OOO_STRING_SVTOOLS_RTF_FTNNZODIACL}, RTF_FTNNZODIACL},
+{{OOO_STRING_SVTOOLS_RTF_G}, RTF_G},
+{{OOO_STRING_SVTOOLS_RTF_GCW}, RTF_GCW},
+{{OOO_STRING_SVTOOLS_RTF_GRIDTBL}, RTF_GRIDTBL},
+{{OOO_STRING_SVTOOLS_RTF_HIGHLIGHT}, RTF_HIGHLIGHT},
+{{OOO_STRING_SVTOOLS_RTF_HLFR}, RTF_HLFR},
+{{OOO_STRING_SVTOOLS_RTF_HLINKBASE}, RTF_HLINKBASE},
+{{OOO_STRING_SVTOOLS_RTF_HLLOC}, RTF_HLLOC},
+{{OOO_STRING_SVTOOLS_RTF_HLSRC}, RTF_HLSRC},
+{{OOO_STRING_SVTOOLS_RTF_ILVL}, RTF_ILVL},
+{{OOO_STRING_SVTOOLS_RTF_IMPR}, RTF_IMPR},
+{{OOO_STRING_SVTOOLS_RTF_JPEGBLIP}, RTF_JPEGBLIP},
+{{OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW}, RTF_LEVELFOLLOW},
+{{OOO_STRING_SVTOOLS_RTF_LEVELINDENT}, RTF_LEVELINDENT},
+{{OOO_STRING_SVTOOLS_RTF_LEVELJC}, RTF_LEVELJC},
+{{OOO_STRING_SVTOOLS_RTF_LEVELLEGAL}, RTF_LEVELLEGAL},
+{{OOO_STRING_SVTOOLS_RTF_LEVELNFC}, RTF_LEVELNFC},
+{{OOO_STRING_SVTOOLS_RTF_LEVELNORESTART},RTF_LEVELNORESTART},
+{{OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS}, RTF_LEVELNUMBERS},
+{{OOO_STRING_SVTOOLS_RTF_LEVELOLD}, RTF_LEVELOLD},
+{{OOO_STRING_SVTOOLS_RTF_LEVELPREV}, RTF_LEVELPREV},
+{{OOO_STRING_SVTOOLS_RTF_LEVELPREVSPACE},RTF_LEVELPREVSPACE},
+{{OOO_STRING_SVTOOLS_RTF_LEVELSPACE}, RTF_LEVELSPACE},
+{{OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT}, RTF_LEVELSTARTAT},
+{{OOO_STRING_SVTOOLS_RTF_LEVELTEXT}, RTF_LEVELTEXT},
+{{OOO_STRING_SVTOOLS_RTF_LINKVAL}, RTF_LINKVAL},
+{{OOO_STRING_SVTOOLS_RTF_LIST}, RTF_LIST},
+{{OOO_STRING_SVTOOLS_RTF_LISTID}, RTF_LISTID},
+{{OOO_STRING_SVTOOLS_RTF_LISTLEVEL}, RTF_LISTLEVEL},
+{{OOO_STRING_SVTOOLS_RTF_LISTNAME}, RTF_LISTNAME},
+{{OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE}, RTF_LISTOVERRIDE},
+{{OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT}, RTF_LISTOVERRIDECOUNT},
+{{OOO_STRING_SVTOOLS_RTF_LISTOVERRIDEFORMAT}, RTF_LISTOVERRIDEFORMAT},
+{{OOO_STRING_SVTOOLS_RTF_LISTOVERRIDESTART}, RTF_LISTOVERRIDESTART},
+{{OOO_STRING_SVTOOLS_RTF_LISTOVERRIDETABLE}, RTF_LISTOVERRIDETABLE},
+{{OOO_STRING_SVTOOLS_RTF_LISTRESTARTHDN},RTF_LISTRESTARTHDN},
+{{OOO_STRING_SVTOOLS_RTF_LISTSIMPLE}, RTF_LISTSIMPLE},
+{{OOO_STRING_SVTOOLS_RTF_LISTTABLE}, RTF_LISTTABLE},
+{{OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID},RTF_LISTTEMPLATEID},
+{{OOO_STRING_SVTOOLS_RTF_LISTTEXT}, RTF_LISTTEXT},
+{{OOO_STRING_SVTOOLS_RTF_LS}, RTF_LS},
+{{OOO_STRING_SVTOOLS_RTF_LYTEXCTTP}, RTF_LYTEXCTTP},
+{{OOO_STRING_SVTOOLS_RTF_LYTPRTMET}, RTF_LYTPRTMET},
+{{OOO_STRING_SVTOOLS_RTF_MANAGER}, RTF_MANAGER},
+{{OOO_STRING_SVTOOLS_RTF_MSMCAP}, RTF_MSMCAP},
+{{OOO_STRING_SVTOOLS_RTF_NOFCHARSWS}, RTF_NOFCHARSWS},
+{{OOO_STRING_SVTOOLS_RTF_NOLEAD}, RTF_NOLEAD},
+{{OOO_STRING_SVTOOLS_RTF_NONSHPPICT}, RTF_NONSHPPICT},
+{{OOO_STRING_SVTOOLS_RTF_NOSECTEXPAND}, RTF_NOSECTEXPAND},
+{{OOO_STRING_SVTOOLS_RTF_NOSNAPLINEGRID},RTF_NOSNAPLINEGRID},
+{{OOO_STRING_SVTOOLS_RTF_NOSPACEFORUL}, RTF_NOSPACEFORUL},
+{{OOO_STRING_SVTOOLS_RTF_NOULTRLSPC}, RTF_NOULTRLSPC},
+{{OOO_STRING_SVTOOLS_RTF_NOXLATTOYEN}, RTF_NOXLATTOYEN},
+{{OOO_STRING_SVTOOLS_RTF_OBJATTPH}, RTF_OBJATTPH},
+{{OOO_STRING_SVTOOLS_RTF_OBJHTML}, RTF_OBJHTML},
+{{OOO_STRING_SVTOOLS_RTF_OBJOCX}, RTF_OBJOCX},
+{{OOO_STRING_SVTOOLS_RTF_OLDLINEWRAP}, RTF_OLDLINEWRAP},
+{{OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL}, RTF_OUTLINELEVEL},
+{{OOO_STRING_SVTOOLS_RTF_OVERLAY}, RTF_OVERLAY},
+{{OOO_STRING_SVTOOLS_RTF_PANOSE}, RTF_PANOSE},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRB}, RTF_PGBRDRB},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRFOOT}, RTF_PGBRDRFOOT},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRHEAD}, RTF_PGBRDRHEAD},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRL}, RTF_PGBRDRL},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDROPT}, RTF_PGBRDROPT},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRR}, RTF_PGBRDRR},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRSNAP}, RTF_PGBRDRSNAP},
+{{OOO_STRING_SVTOOLS_RTF_PGBRDRT}, RTF_PGBRDRT},
+{{OOO_STRING_SVTOOLS_RTF_PGNCHOSUNG}, RTF_PGNCHOSUNG},
+{{OOO_STRING_SVTOOLS_RTF_PGNCNUM}, RTF_PGNCNUM},
+{{OOO_STRING_SVTOOLS_RTF_PGNDBNUMK}, RTF_PGNDBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_PGNDBNUMT}, RTF_PGNDBNUMT},
+{{OOO_STRING_SVTOOLS_RTF_PGNGANADA}, RTF_PGNGANADA},
+{{OOO_STRING_SVTOOLS_RTF_PGNGBNUM}, RTF_PGNGBNUM},
+{{OOO_STRING_SVTOOLS_RTF_PGNGBNUMD}, RTF_PGNGBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_PGNGBNUMK}, RTF_PGNGBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_PGNGBNUML}, RTF_PGNGBNUML},
+{{OOO_STRING_SVTOOLS_RTF_PGNZODIAC}, RTF_PGNZODIAC},
+{{OOO_STRING_SVTOOLS_RTF_PGNZODIACD}, RTF_PGNZODIACD},
+{{OOO_STRING_SVTOOLS_RTF_PGNZODIACL}, RTF_PGNZODIACL},
+{{OOO_STRING_SVTOOLS_RTF_PICPROP}, RTF_PICPROP},
+{{OOO_STRING_SVTOOLS_RTF_PNAIUEO}, RTF_PNAIUEO},
+{{OOO_STRING_SVTOOLS_RTF_PNAIUEOD}, RTF_PNAIUEOD},
+{{OOO_STRING_SVTOOLS_RTF_PNCHOSUNG}, RTF_PNCHOSUNG},
+{{OOO_STRING_SVTOOLS_RTF_PNDBNUMD}, RTF_PNDBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_PNDBNUMK}, RTF_PNDBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_PNDBNUML}, RTF_PNDBNUML},
+{{OOO_STRING_SVTOOLS_RTF_PNDBNUMT}, RTF_PNDBNUMT},
+{{OOO_STRING_SVTOOLS_RTF_PNGANADA}, RTF_PNGANADA},
+{{OOO_STRING_SVTOOLS_RTF_PNGBLIP}, RTF_PNGBLIP},
+{{OOO_STRING_SVTOOLS_RTF_PNGBNUM}, RTF_PNGBNUM},
+{{OOO_STRING_SVTOOLS_RTF_PNGBNUMD}, RTF_PNGBNUMD},
+{{OOO_STRING_SVTOOLS_RTF_PNGBNUMK}, RTF_PNGBNUMK},
+{{OOO_STRING_SVTOOLS_RTF_PNGBNUML}, RTF_PNGBNUML},
+{{OOO_STRING_SVTOOLS_RTF_PNRAUTH}, RTF_PNRAUTH},
+{{OOO_STRING_SVTOOLS_RTF_PNRDATE}, RTF_PNRDATE},
+{{OOO_STRING_SVTOOLS_RTF_PNRNFC}, RTF_PNRNFC},
+{{OOO_STRING_SVTOOLS_RTF_PNRNOT}, RTF_PNRNOT},
+{{OOO_STRING_SVTOOLS_RTF_PNRPNBR}, RTF_PNRPNBR},
+{{OOO_STRING_SVTOOLS_RTF_PNRRGB}, RTF_PNRRGB},
+{{OOO_STRING_SVTOOLS_RTF_PNRSTART}, RTF_PNRSTART},
+{{OOO_STRING_SVTOOLS_RTF_PNRSTOP}, RTF_PNRSTOP},
+{{OOO_STRING_SVTOOLS_RTF_PNRXST}, RTF_PNRXST},
+{{OOO_STRING_SVTOOLS_RTF_PNZODIAC}, RTF_PNZODIAC},
+{{OOO_STRING_SVTOOLS_RTF_PNZODIACD}, RTF_PNZODIACD},
+{{OOO_STRING_SVTOOLS_RTF_PNZODIACL}, RTF_PNZODIACL},
+{{OOO_STRING_SVTOOLS_RTF_LFOLEVEL}, RTF_LFOLEVEL},
+{{OOO_STRING_SVTOOLS_RTF_POSYIN}, RTF_POSYIN},
+{{OOO_STRING_SVTOOLS_RTF_POSYOUT}, RTF_POSYOUT},
+{{OOO_STRING_SVTOOLS_RTF_PRIVATE}, RTF_PRIVATE},
+{{OOO_STRING_SVTOOLS_RTF_PROPNAME}, RTF_PROPNAME},
+{{OOO_STRING_SVTOOLS_RTF_PROPTYPE}, RTF_PROPTYPE},
+{{OOO_STRING_SVTOOLS_RTF_REVAUTHDEL}, RTF_REVAUTHDEL},
+{{OOO_STRING_SVTOOLS_RTF_REVDTTMDEL}, RTF_REVDTTMDEL},
+{{OOO_STRING_SVTOOLS_RTF_SAUTOUPD}, RTF_SAUTOUPD},
+{{OOO_STRING_SVTOOLS_RTF_SECTDEFAULTCL}, RTF_SECTDEFAULTCL},
+{{OOO_STRING_SVTOOLS_RTF_SECTEXPAND}, RTF_SECTEXPAND},
+{{OOO_STRING_SVTOOLS_RTF_SECTLINEGRID}, RTF_SECTLINEGRID},
+{{OOO_STRING_SVTOOLS_RTF_SECTSPECIFYCL}, RTF_SECTSPECIFYCL},
+{{OOO_STRING_SVTOOLS_RTF_SECTSPECIFYL}, RTF_SECTSPECIFYL},
+{{OOO_STRING_SVTOOLS_RTF_SHIDDEN}, RTF_SHIDDEN},
+{{OOO_STRING_SVTOOLS_RTF_SHPBOTTOM}, RTF_SHPBOTTOM},
+{{OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN}, RTF_SHPBXCOLUMN},
+{{OOO_STRING_SVTOOLS_RTF_SHPBXMARGIN}, RTF_SHPBXMARGIN},
+{{OOO_STRING_SVTOOLS_RTF_SHPBXPAGE}, RTF_SHPBXPAGE},
+{{OOO_STRING_SVTOOLS_RTF_SHPBYMARGIN}, RTF_SHPBYMARGIN},
+{{OOO_STRING_SVTOOLS_RTF_SHPBYPAGE}, RTF_SHPBYPAGE},
+{{OOO_STRING_SVTOOLS_RTF_SHPBYPARA}, RTF_SHPBYPARA},
+{{OOO_STRING_SVTOOLS_RTF_SHPFBLWTXT}, RTF_SHPFBLWTXT},
+{{OOO_STRING_SVTOOLS_RTF_SHPFHDR}, RTF_SHPFHDR},
+{{OOO_STRING_SVTOOLS_RTF_SHPGRP}, RTF_SHPGRP},
+{{OOO_STRING_SVTOOLS_RTF_SHPLEFT}, RTF_SHPLEFT},
+{{OOO_STRING_SVTOOLS_RTF_SHPLID}, RTF_SHPLID},
+{{OOO_STRING_SVTOOLS_RTF_SHPLOCKANCHOR}, RTF_SHPLOCKANCHOR},
+{{OOO_STRING_SVTOOLS_RTF_SHPPICT}, RTF_SHPPICT},
+{{OOO_STRING_SVTOOLS_RTF_SHPRIGHT}, RTF_SHPRIGHT},
+{{OOO_STRING_SVTOOLS_RTF_SHPRSLT}, RTF_SHPRSLT},
+{{OOO_STRING_SVTOOLS_RTF_SHPTOP}, RTF_SHPTOP},
+{{OOO_STRING_SVTOOLS_RTF_SHPTXT}, RTF_SHPTXT},
+{{OOO_STRING_SVTOOLS_RTF_SHPWRK}, RTF_SHPWRK},
+{{OOO_STRING_SVTOOLS_RTF_SHPWR}, RTF_SHPWR},
+{{OOO_STRING_SVTOOLS_RTF_SHPZ}, RTF_SHPZ},
+{{OOO_STRING_SVTOOLS_RTF_SPRSBSP}, RTF_SPRSBSP},
+{{OOO_STRING_SVTOOLS_RTF_SPRSLNSP}, RTF_SPRSLNSP},
+{{OOO_STRING_SVTOOLS_RTF_SPRSTSM}, RTF_SPRSTSM},
+{{OOO_STRING_SVTOOLS_RTF_STATICVAL}, RTF_STATICVAL},
+{{OOO_STRING_SVTOOLS_RTF_STEXTFLOW}, RTF_STEXTFLOW},
+{{OOO_STRING_SVTOOLS_RTF_STRIKED}, RTF_STRIKED},
+{{OOO_STRING_SVTOOLS_RTF_SUBFONTBYSIZE}, RTF_SUBFONTBYSIZE},
+{{OOO_STRING_SVTOOLS_RTF_TCELLD}, RTF_TCELLD},
+{{OOO_STRING_SVTOOLS_RTF_TIME}, RTF_TIME},
+{{OOO_STRING_SVTOOLS_RTF_TRUNCATEFONTHEIGHT}, RTF_TRUNCATEFONTHEIGHT},
+{{OOO_STRING_SVTOOLS_RTF_UC}, RTF_UC},
+{{OOO_STRING_SVTOOLS_RTF_UD}, RTF_UD},
+{{OOO_STRING_SVTOOLS_RTF_ULDASH}, RTF_ULDASH},
+{{OOO_STRING_SVTOOLS_RTF_ULDASHD}, RTF_ULDASHD},
+{{OOO_STRING_SVTOOLS_RTF_ULDASHDD}, RTF_ULDASHDD},
+{{OOO_STRING_SVTOOLS_RTF_ULTH}, RTF_ULTH},
+{{OOO_STRING_SVTOOLS_RTF_ULWAVE}, RTF_ULWAVE},
+{{OOO_STRING_SVTOOLS_RTF_ULC}, RTF_ULC},
+{{OOO_STRING_SVTOOLS_RTF_U}, RTF_U},
+{{OOO_STRING_SVTOOLS_RTF_UPR}, RTF_UPR},
+{{OOO_STRING_SVTOOLS_RTF_USERPROPS}, RTF_USERPROPS},
+{{OOO_STRING_SVTOOLS_RTF_VIEWKIND}, RTF_VIEWKIND},
+{{OOO_STRING_SVTOOLS_RTF_VIEWSCALE}, RTF_VIEWSCALE},
+{{OOO_STRING_SVTOOLS_RTF_VIEWZK}, RTF_VIEWZK},
+{{OOO_STRING_SVTOOLS_RTF_WIDCTLPAR}, RTF_WIDCTLPAR},
+{{OOO_STRING_SVTOOLS_RTF_WINDOWCAPTION}, RTF_WINDOWCAPTION},
+{{OOO_STRING_SVTOOLS_RTF_WPEQN}, RTF_WPEQN},
+{{OOO_STRING_SVTOOLS_RTF_WPJST}, RTF_WPJST},
+{{OOO_STRING_SVTOOLS_RTF_WPSP}, RTF_WPSP},
+{{OOO_STRING_SVTOOLS_RTF_YXE}, RTF_YXE},
+{{OOO_STRING_SVTOOLS_RTF_FRMTXLRTB}, RTF_FRMTXLRTB},
+{{OOO_STRING_SVTOOLS_RTF_FRMTXTBRL}, RTF_FRMTXTBRL},
+{{OOO_STRING_SVTOOLS_RTF_FRMTXBTLR}, RTF_FRMTXBTLR},
+{{OOO_STRING_SVTOOLS_RTF_FRMTXLRTBV}, RTF_FRMTXLRTBV},
+{{OOO_STRING_SVTOOLS_RTF_FRMTXTBRLV}, RTF_FRMTXTBRLV},
+
+// MS-2000 Tokens
+ {{OOO_STRING_SVTOOLS_RTF_ULTHD}, RTF_ULTHD},
+ {{OOO_STRING_SVTOOLS_RTF_ULTHDASH}, RTF_ULTHDASH},
+ {{OOO_STRING_SVTOOLS_RTF_ULLDASH}, RTF_ULLDASH},
+ {{OOO_STRING_SVTOOLS_RTF_ULTHLDASH}, RTF_ULTHLDASH},
+ {{OOO_STRING_SVTOOLS_RTF_ULTHDASHD}, RTF_ULTHDASHD},
+ {{OOO_STRING_SVTOOLS_RTF_ULTHDASHDD}, RTF_ULTHDASHDD},
+ {{OOO_STRING_SVTOOLS_RTF_ULHWAVE}, RTF_ULHWAVE},
+ {{OOO_STRING_SVTOOLS_RTF_ULULDBWAVE}, RTF_ULULDBWAVE},
+
+ {{OOO_STRING_SVTOOLS_RTF_LOCH}, RTF_LOCH},
+ {{OOO_STRING_SVTOOLS_RTF_HICH}, RTF_HICH},
+ {{OOO_STRING_SVTOOLS_RTF_DBCH}, RTF_DBCH},
+ {{OOO_STRING_SVTOOLS_RTF_LANGFE}, RTF_LANGFE},
+ {{OOO_STRING_SVTOOLS_RTF_ADEFLANG}, RTF_ADEFLANG},
+ {{OOO_STRING_SVTOOLS_RTF_ADEFF}, RTF_ADEFF},
+ {{OOO_STRING_SVTOOLS_RTF_ACCNONE}, RTF_ACCNONE},
+ {{OOO_STRING_SVTOOLS_RTF_ACCDOT}, RTF_ACCDOT},
+ {{OOO_STRING_SVTOOLS_RTF_ACCCOMMA}, RTF_ACCCOMMA},
+ {{OOO_STRING_SVTOOLS_RTF_TWOINONE}, RTF_TWOINONE},
+ {{OOO_STRING_SVTOOLS_RTF_HORZVERT}, RTF_HORZVERT},
+ {{OOO_STRING_SVTOOLS_RTF_FAHANG}, RTF_FAHANG},
+ {{OOO_STRING_SVTOOLS_RTF_FAVAR}, RTF_FAVAR},
+ {{OOO_STRING_SVTOOLS_RTF_FACENTER}, RTF_FACENTER},
+ {{OOO_STRING_SVTOOLS_RTF_FAROMAN}, RTF_FAROMAN},
+ {{OOO_STRING_SVTOOLS_RTF_FAFIXED}, RTF_FAFIXED},
+ {{OOO_STRING_SVTOOLS_RTF_NOCWRAP}, RTF_NOCWRAP},
+ {{OOO_STRING_SVTOOLS_RTF_NOOVERFLOW}, RTF_NOOVERFLOW},
+ {{OOO_STRING_SVTOOLS_RTF_ASPALPHA}, RTF_ASPALPHA},
+
+// SWG spezifische Attribute
+ {{OOO_STRING_SVTOOLS_RTF_GRFALIGNV}, RTF_GRF_ALIGNV},
+ {{OOO_STRING_SVTOOLS_RTF_GRFALIGNH}, RTF_GRF_ALIGNH},
+ {{OOO_STRING_SVTOOLS_RTF_GRFMIRROR}, RTF_GRF_MIRROR},
+ {{OOO_STRING_SVTOOLS_RTF_HEADERYB}, RTF_HEADER_YB},
+ {{OOO_STRING_SVTOOLS_RTF_HEADERXL}, RTF_HEADER_XL},
+ {{OOO_STRING_SVTOOLS_RTF_HEADERXR}, RTF_HEADER_XR},
+ {{OOO_STRING_SVTOOLS_RTF_FOOTERYT}, RTF_FOOTER_YT},
+ {{OOO_STRING_SVTOOLS_RTF_FOOTERXL}, RTF_FOOTER_XL},
+ {{OOO_STRING_SVTOOLS_RTF_FOOTERXR}, RTF_FOOTER_XR},
+ {{OOO_STRING_SVTOOLS_RTF_HEADERYH}, RTF_HEADER_YH},
+ {{OOO_STRING_SVTOOLS_RTF_FOOTERYH}, RTF_FOOTER_YH},
+ {{OOO_STRING_SVTOOLS_RTF_BALANCEDCOLUMN},RTF_BALANCED_COLUMN},
+ {{OOO_STRING_SVTOOLS_RTF_UPDNPROP}, RTF_SWG_ESCPROP},
+ {{OOO_STRING_SVTOOLS_RTF_PRTDATA}, RTF_SWG_PRTDATA},
+ {{OOO_STRING_SVTOOLS_RTF_BKMKKEY}, RTF_BKMK_KEY},
+
+// Attribute fuer die freifliegenden Rahmen
+ {{OOO_STRING_SVTOOLS_RTF_FLYPRINT}, RTF_FLYPRINT},
+ {{OOO_STRING_SVTOOLS_RTF_FLYOPAQUE}, RTF_FLYOPAQUE},
+ {{OOO_STRING_SVTOOLS_RTF_FLYPRTCTD}, RTF_FLYPRTCTD},
+ {{OOO_STRING_SVTOOLS_RTF_FLYMAINCNT}, RTF_FLYMAINCNT},
+ {{OOO_STRING_SVTOOLS_RTF_FLYVERT}, RTF_FLYVERT},
+ {{OOO_STRING_SVTOOLS_RTF_FLYHORZ}, RTF_FLYHORZ},
+ {{OOO_STRING_SVTOOLS_RTF_DFRMTXTL}, RTF_FLYOUTLEFT},
+ {{OOO_STRING_SVTOOLS_RTF_DFRMTXTR}, RTF_FLYOUTRIGHT},
+ {{OOO_STRING_SVTOOLS_RTF_DFRMTXTU}, RTF_FLYOUTUPPER},
+ {{OOO_STRING_SVTOOLS_RTF_DFRMTXTW}, RTF_FLYOUTLOWER},
+ {{OOO_STRING_SVTOOLS_RTF_FLYANCHOR}, RTF_FLYANCHOR},
+ {{OOO_STRING_SVTOOLS_RTF_FLYCNTNT}, RTF_FLY_CNTNT},
+ {{OOO_STRING_SVTOOLS_RTF_FLYCOLUMN}, RTF_FLY_COLUMN},
+ {{OOO_STRING_SVTOOLS_RTF_FLYPAGE}, RTF_FLY_PAGE},
+
+ {{OOO_STRING_SVTOOLS_RTF_BRDBOX}, RTF_BRDBOX},
+ {{OOO_STRING_SVTOOLS_RTF_BRDLNCOL}, RTF_BRDLINE_COL},
+ {{OOO_STRING_SVTOOLS_RTF_BRDLNIN}, RTF_BRDLINE_IN},
+ {{OOO_STRING_SVTOOLS_RTF_BRDLNOUT}, RTF_BRDLINE_OUT},
+ {{OOO_STRING_SVTOOLS_RTF_BRDLNDIST}, RTF_BRDLINE_DIST},
+
+ {{OOO_STRING_SVTOOLS_RTF_SHADOW}, RTF_SHADOW},
+ {{OOO_STRING_SVTOOLS_RTF_SHDWDIST}, RTF_SHDW_DIST},
+ {{OOO_STRING_SVTOOLS_RTF_SHDWSTYLE}, RTF_SHDW_STYLE},
+ {{OOO_STRING_SVTOOLS_RTF_SHDWCOL}, RTF_SHDW_COL},
+ {{OOO_STRING_SVTOOLS_RTF_SHDWFCOL}, RTF_SHDW_FCOL},
+
+ {{OOO_STRING_SVTOOLS_RTF_FLYINPARA}, RTF_FLY_INPARA},
+
+ {{OOO_STRING_SVTOOLS_RTF_PGDSCTBL}, RTF_PGDSCTBL},
+ {{OOO_STRING_SVTOOLS_RTF_PGDSC}, RTF_PGDSC},
+ {{OOO_STRING_SVTOOLS_RTF_PGDSCUSE}, RTF_PGDSCUSE},
+ {{OOO_STRING_SVTOOLS_RTF_PGDSCNXT}, RTF_PGDSCNXT},
+
+ {{OOO_STRING_SVTOOLS_RTF_HYPHEN}, RTF_HYPHEN},
+ {{OOO_STRING_SVTOOLS_RTF_HYPHLEAD}, RTF_HYPHLEAD},
+ {{OOO_STRING_SVTOOLS_RTF_HYPHTRAIL}, RTF_HYPHTRAIL},
+ {{OOO_STRING_SVTOOLS_RTF_HYPHMAX}, RTF_HYPHMAX},
+
+ {{OOO_STRING_SVTOOLS_RTF_TLSWG}, RTF_TLSWG},
+ {{OOO_STRING_SVTOOLS_RTF_PGBRK}, RTF_PGBRK},
+
+ {{OOO_STRING_SVTOOLS_RTF_PGDSCNO}, RTF_PGDSCNO},
+ {{OOO_STRING_SVTOOLS_RTF_SOUTLVL}, RTF_SOUTLVL},
+
+ {{OOO_STRING_SVTOOLS_RTF_SHP}, RTF_SHP},
+ /*
+ {{OOO_STRING_SVTOOLS_RTF_SHPLEFT}, RTF_SHPLEFT}
+ {{OOO_STRING_SVTOOLS_RTF_SHPTOP}, RTF_SHPTOP}
+ {{OOO_STRING_SVTOOLS_RTF_SHPBOTTOM}, RTF_SHPBOTTOM}
+ {{OOO_STRING_SVTOOLS_RTF_SHPRIGHT}, RTF_SHPRIGHT}
+ */
+ {{OOO_STRING_SVTOOLS_RTF_SN}, RTF_SN},
+ {{OOO_STRING_SVTOOLS_RTF_SV}, RTF_SV},
+
+// Support for overline attributes
+ {{OOO_STRING_SVTOOLS_RTF_OL}, RTF_OL},
+ {{OOO_STRING_SVTOOLS_RTF_OLW}, RTF_OLW},
+ {{OOO_STRING_SVTOOLS_RTF_OLD}, RTF_OLD},
+ {{OOO_STRING_SVTOOLS_RTF_OLDB}, RTF_OLDB},
+ {{OOO_STRING_SVTOOLS_RTF_OLNONE}, RTF_OLNONE},
+ {{OOO_STRING_SVTOOLS_RTF_OLDASH}, RTF_OLDASH},
+ {{OOO_STRING_SVTOOLS_RTF_OLDASHD}, RTF_OLDASHD},
+ {{OOO_STRING_SVTOOLS_RTF_OLDASHDD}, RTF_OLDASHDD},
+ {{OOO_STRING_SVTOOLS_RTF_OLTH}, RTF_OLTH},
+ {{OOO_STRING_SVTOOLS_RTF_OLWAVE}, RTF_OLWAVE},
+ {{OOO_STRING_SVTOOLS_RTF_OLC}, RTF_OLC},
+ {{OOO_STRING_SVTOOLS_RTF_OLTHD}, RTF_OLTHD},
+ {{OOO_STRING_SVTOOLS_RTF_OLTHDASH}, RTF_OLTHDASH},
+ {{OOO_STRING_SVTOOLS_RTF_OLLDASH}, RTF_OLLDASH},
+ {{OOO_STRING_SVTOOLS_RTF_OLTHLDASH}, RTF_OLTHLDASH},
+ {{OOO_STRING_SVTOOLS_RTF_OLTHDASHD}, RTF_OLTHDASHD},
+ {{OOO_STRING_SVTOOLS_RTF_OLTHDASHDD}, RTF_OLTHDASHDD},
+ {{OOO_STRING_SVTOOLS_RTF_OLHWAVE}, RTF_OLHWAVE},
+ {{OOO_STRING_SVTOOLS_RTF_OLOLDBWAVE}, RTF_OLOLDBWAVE}
+};
+
+
+extern "C" {
+static int
+#if defined( WNT )
+ __cdecl
+#endif
+#if defined( ICC ) && defined( OS2 )
+_Optlink
+#endif
+ RTFKeyCompare( const void *pFirst, const void *pSecond)
+{
+ int nRet = 0;
+ if( -1 == ((RTF_TokenEntry*)pFirst)->nToken )
+ {
+ if( -1 == ((RTF_TokenEntry*)pSecond)->nToken )
+ nRet = ((RTF_TokenEntry*)pFirst)->pUToken->CompareTo(
+ *((RTF_TokenEntry*)pSecond)->pUToken );
+ else
+ nRet = ((RTF_TokenEntry*)pFirst)->pUToken->CompareToAscii(
+ ((RTF_TokenEntry*)pSecond)->sToken );
+ }
+ else
+ {
+ if( -1 == ((RTF_TokenEntry*)pSecond)->nToken )
+ nRet = -1 * ((RTF_TokenEntry*)pSecond)->pUToken->CompareToAscii(
+ ((RTF_TokenEntry*)pFirst)->sToken );
+ else
+ nRet = strcmp( ((RTF_TokenEntry*)pFirst)->sToken,
+ ((RTF_TokenEntry*)pSecond)->sToken );
+ }
+
+ return nRet;
+}
+
+}
+
+int GetRTFToken( const String& rSearch )
+{
+ if( !bSortKeyWords )
+ {
+ qsort( (void*) aRTFTokenTab,
+ sizeof( aRTFTokenTab ) / sizeof( RTF_TokenEntry ),
+ sizeof( RTF_TokenEntry ),
+ RTFKeyCompare );
+ bSortKeyWords = TRUE;
+ }
+
+ int nRet = 0;
+ void* pFound;
+ RTF_TokenEntry aSrch;
+ aSrch.pUToken = &rSearch;
+ aSrch.nToken = -1;
+
+ if( 0 != ( pFound = bsearch( (char *) &aSrch,
+ (void*) aRTFTokenTab,
+ sizeof( aRTFTokenTab ) / sizeof( RTF_TokenEntry ),
+ sizeof( RTF_TokenEntry ),
+ RTFKeyCompare )))
+ nRet = ((RTF_TokenEntry*)pFound)->nToken;
+ return nRet;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/svtools/source/svrtf/rtfout.cxx b/svtools/source/svrtf/rtfout.cxx
new file mode 100644
index 000000000000..d97e838d2450
--- /dev/null
+++ b/svtools/source/svrtf/rtfout.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtfkeywd.hxx>
+#include <rtfout.hxx>
+
+using namespace rtl;
+
+#if defined(UNX)
+const sal_Char RTFOutFuncs::sNewLine = '\012';
+#else
+const sal_Char __FAR_DATA RTFOutFuncs::sNewLine[] = "\015\012";
+#endif
+
+
+SvStream& RTFOutFuncs::Out_Char(SvStream& rStream, sal_Unicode c,
+ int *pUCMode, rtl_TextEncoding eDestEnc, BOOL bWriteHelpFile)
+{
+ const sal_Char* pStr = 0;
+ switch (c)
+ {
+ case 0x1:
+ case 0x2:
+ // this are control character of our textattributes and will never be
+ // written
+ break;
+ case 0xA0:
+ rStream << "\\~";
+ break;
+ case 0xAD:
+ rStream << "\\-";
+ break;
+ case 0x2011:
+ rStream << "\\_";
+ break;
+ case '\n':
+ pStr = OOO_STRING_SVTOOLS_RTF_LINE;
+ break;
+ case '\t':
+ pStr = OOO_STRING_SVTOOLS_RTF_TAB;
+ break;
+ default:
+ if(!bWriteHelpFile)
+ {
+ switch(c)
+ {
+ case 149:
+ pStr = OOO_STRING_SVTOOLS_RTF_BULLET;
+ break;
+ case 150:
+ pStr = OOO_STRING_SVTOOLS_RTF_ENDASH;
+ break;
+ case 151:
+ pStr = OOO_STRING_SVTOOLS_RTF_EMDASH;
+ break;
+ case 145:
+ pStr = OOO_STRING_SVTOOLS_RTF_LQUOTE;
+ break;
+ case 146:
+ pStr = OOO_STRING_SVTOOLS_RTF_RQUOTE;
+ break;
+ case 147:
+ pStr = OOO_STRING_SVTOOLS_RTF_LDBLQUOTE;
+ break;
+ case 148:
+ pStr = OOO_STRING_SVTOOLS_RTF_RDBLQUOTE;
+ break;
+ }
+
+ if (pStr)
+ break;
+ }
+
+ switch (c)
+ {
+ case '\\':
+ case '}':
+ case '{':
+ rStream << '\\' << (sal_Char)c;
+ break;
+ default:
+ if (c >= ' ' && c <= '~')
+ rStream << (sal_Char)c;
+ else
+ {
+ //If we can't convert to the dest encoding, or if
+ //its an uncommon multibyte sequence which most
+ //readers won't be able to handle correctly, then
+ //If we can't convert to the dest encoding, then
+ //export as unicode
+ OUString sBuf(&c, 1);
+ OString sConverted;
+ sal_uInt32 nFlags =
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
+ bool bWriteAsUnicode = !(sBuf.convertToString(&sConverted,
+ eDestEnc, nFlags))
+ || (RTL_TEXTENCODING_UTF8==eDestEnc); // #i43933# do not export UTF-8 chars in RTF;
+ if (bWriteAsUnicode)
+ {
+ sBuf.convertToString(&sConverted,
+ eDestEnc, OUSTRING_TO_OSTRING_CVTFLAGS);
+ }
+ const sal_Int32 nLen = sConverted.getLength();
+
+ if (bWriteAsUnicode && pUCMode)
+ {
+ // then write as unicode - character
+ if (*pUCMode != nLen)
+ {
+ rStream << "\\uc" << ByteString::CreateFromInt32(nLen).GetBuffer() << " "; // #i47831# add an additional whitespace, so that "document whitespaces" are not ignored.;
+ *pUCMode = nLen;
+ }
+ ByteString sNo(ByteString::CreateFromInt32(c));
+ rStream << "\\u" << sNo.GetBuffer();
+ }
+
+ for (sal_Int32 nI = 0; nI < nLen; ++nI)
+ {
+ rStream << "\\'";
+ Out_Hex(rStream, sConverted.getStr()[nI], 2);
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ if (pStr)
+ rStream << pStr << ' ';
+
+ return rStream;
+}
+
+SvStream& RTFOutFuncs::Out_String( SvStream& rStream, const String& rStr,
+ rtl_TextEncoding eDestEnc, BOOL bWriteHelpFile)
+{
+ int nUCMode = 1;
+ for (xub_StrLen n = 0; n < rStr.Len(); ++n)
+ Out_Char(rStream, rStr.GetChar(n), &nUCMode, eDestEnc, bWriteHelpFile);
+ if (nUCMode != 1)
+ rStream << "\\uc1"<< " "; // #i47831# add an additional whitespace, so that "document whitespaces" are not ignored.;
+ return rStream;
+}
+
+SvStream& RTFOutFuncs::Out_Fontname(SvStream& rStream, const String& rStr,
+ rtl_TextEncoding eDestEnc, BOOL bWriteHelpFile)
+{
+ //Fontnames in word have a quirk in that \uc and usage of ansi replacement
+ //chars after a \u don't work and in wordpad \u doesn't work, so we are
+ //left with forcing ansi characters only for fontnames
+ for (xub_StrLen n = 0; n < rStr.Len(); ++n)
+ Out_Char(rStream, rStr.GetChar(n), 0, eDestEnc, bWriteHelpFile);
+ return rStream;
+}
+
+SvStream& RTFOutFuncs::Out_Hex( SvStream& rStream, ULONG nHex, BYTE nLen )
+{
+ sal_Char aNToABuf[] = "0000000000000000";
+
+ DBG_ASSERT( nLen < sizeof(aNToABuf), "zu viele Stellen" );
+ if( nLen >= sizeof(aNToABuf) )
+ nLen = (sizeof(aNToABuf)-1);
+
+ // Pointer an das Bufferende setzen
+ sal_Char* pStr = aNToABuf + (sizeof(aNToABuf)-1);
+ for( BYTE n = 0; n < nLen; ++n )
+ {
+ *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
+ if( *pStr > '9' )
+ *pStr += 39;
+ nHex >>= 4;
+ }
+ return rStream << pStr;
+}
+
+
+
diff --git a/svtools/source/svrtf/svparser.cxx b/svtools/source/svrtf/svparser.cxx
new file mode 100644
index 000000000000..53b7ee497754
--- /dev/null
+++ b/svtools/source/svrtf/svparser.cxx
@@ -0,0 +1,726 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include <stdio.h>
+#include <svtools/svparser.hxx>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include <rtl/textcvt.h>
+#include <rtl/tencinfo.h>
+
+#define SVPAR_CSM_
+
+#define SVPAR_CSM_ANSI 0x0001U
+#define SVPAR_CSM_UTF8 0x0002U
+#define SVPAR_CSM_UCS2B 0x0004U
+#define SVPAR_CSM_UCS2L 0x0008U
+#define SVPAR_CSM_SWITCH 0x8000U
+
+// Struktur, um sich die akt. Daten zumerken
+struct SvParser_Impl
+{
+ String aToken; // gescanntes Token
+ ULONG nFilePos; // akt. Position im Stream
+ ULONG nlLineNr; // akt. Zeilen Nummer
+ ULONG nlLinePos; // akt. Spalten Nummer
+ long nTokenValue; // zusaetzlicher Wert (RTF)
+ BOOL bTokenHasValue; // indicates whether nTokenValue is valid
+ int nToken; // akt. Token
+ sal_Unicode nNextCh; // akt. Zeichen
+
+ int nSaveToken; // das Token vom Continue
+
+ rtl_TextToUnicodeConverter hConv;
+ rtl_TextToUnicodeContext hContext;
+
+#ifdef DBG_UTIL
+ SvFileStream aOut;
+#endif
+
+ SvParser_Impl() :
+ nSaveToken(0), hConv( 0 ), hContext( (rtl_TextToUnicodeContext)1 )
+ {
+ }
+
+};
+
+
+
+// Konstruktor
+SvParser::SvParser( SvStream& rIn, BYTE nStackSize )
+ : rInput( rIn )
+ , nlLineNr( 1 )
+ , nlLinePos( 1 )
+ , pImplData( 0 )
+ , nTokenValue( 0 )
+ , bTokenHasValue( false )
+ , eState( SVPAR_NOTSTARTED )
+ , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
+ , bDownloadingFile( FALSE )
+ , nTokenStackSize( nStackSize )
+ , nTokenStackPos( 0 )
+{
+ bUCS2BSrcEnc = bSwitchToUCS2 = FALSE;
+ eState = SVPAR_NOTSTARTED;
+ if( nTokenStackSize < 3 )
+ nTokenStackSize = 3;
+ pTokenStack = new TokenStackType[ nTokenStackSize ];
+ pTokenStackPos = pTokenStack;
+
+#ifdef DBG_UTIL
+
+ // wenn die Datei schon existiert, dann Anhaengen:
+ if( !pImplData )
+ pImplData = new SvParser_Impl;
+ pImplData->aOut.Open( String::CreateFromAscii( "\\parser.dmp" ),
+ STREAM_STD_WRITE | STREAM_NOCREATE );
+ if( pImplData->aOut.GetError() || !pImplData->aOut.IsOpen() )
+ pImplData->aOut.Close();
+ else
+ {
+ pImplData->aOut.Seek( STREAM_SEEK_TO_END );
+ pImplData->aOut << "\x0c\n\n >>>>>>>>>>>>>>> Dump Start <<<<<<<<<<<<<<<\n";
+ }
+#endif
+}
+
+SvParser::~SvParser()
+{
+#ifdef DBG_UTIL
+ if( pImplData->aOut.IsOpen() )
+ pImplData->aOut << "\n\n >>>>>>>>>>>>>>> Dump Ende <<<<<<<<<<<<<<<\n";
+ pImplData->aOut.Close();
+#endif
+
+ if( pImplData && pImplData->hConv )
+ {
+ rtl_destroyTextToUnicodeContext( pImplData->hConv,
+ pImplData->hContext );
+ rtl_destroyTextToUnicodeConverter( pImplData->hConv );
+ }
+
+ delete pImplData;
+
+ delete [] pTokenStack;
+}
+
+void SvParser::ClearTxtConvContext()
+{
+ if( pImplData && pImplData->hConv )
+ rtl_resetTextToUnicodeContext( pImplData->hConv, pImplData->hContext );
+}
+
+void SvParser::SetSrcEncoding( rtl_TextEncoding eEnc )
+{
+
+ if( eEnc != eSrcEnc )
+ {
+ if( pImplData && pImplData->hConv )
+ {
+ rtl_destroyTextToUnicodeContext( pImplData->hConv,
+ pImplData->hContext );
+ rtl_destroyTextToUnicodeConverter( pImplData->hConv );
+ pImplData->hConv = 0;
+ pImplData->hContext = (rtl_TextToUnicodeContext )1;
+ }
+
+ if( rtl_isOctetTextEncoding(eEnc) ||
+ RTL_TEXTENCODING_UCS2 == eEnc )
+ {
+ eSrcEnc = eEnc;
+ if( !pImplData )
+ pImplData = new SvParser_Impl;
+ pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
+ DBG_ASSERT( pImplData->hConv,
+ "SvParser::SetSrcEncoding: no converter for source encoding" );
+ if( !pImplData->hConv )
+ eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
+ else
+ pImplData->hContext =
+ rtl_createTextToUnicodeContext( pImplData->hConv );
+ }
+ else
+ {
+ DBG_ASSERT( !this,
+ "SvParser::SetSrcEncoding: invalid source encoding" );
+ eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
+ }
+ }
+}
+
+void SvParser::RereadLookahead()
+{
+ rInput.Seek(nNextChPos);
+ nNextCh = GetNextChar();
+}
+
+sal_Unicode SvParser::GetNextChar()
+{
+ sal_Unicode c = 0U;
+
+ // When reading muliple bytes, we don't have to care about the file
+ // position when we run inti the pending state. The file position is
+ // maintained by SaveState/RestoreState.
+ BOOL bErr;
+ if( bSwitchToUCS2 && 0 == rInput.Tell() )
+ {
+ sal_uChar c1, c2;
+ BOOL bSeekBack = TRUE;
+
+ rInput >> c1;
+ bErr = rInput.IsEof() || rInput.GetError();
+ if( !bErr )
+ {
+ if( 0xff == c1 || 0xfe == c1 )
+ {
+ rInput >> c2;
+ bErr = rInput.IsEof() || rInput.GetError();
+ if( !bErr )
+ {
+ if( 0xfe == c1 && 0xff == c2 )
+ {
+ eSrcEnc = RTL_TEXTENCODING_UCS2;
+ bUCS2BSrcEnc = TRUE;
+ bSeekBack = FALSE;
+ }
+ else if( 0xff == c1 && 0xfe == c2 )
+ {
+ eSrcEnc = RTL_TEXTENCODING_UCS2;
+ bUCS2BSrcEnc = FALSE;
+ bSeekBack = FALSE;
+ }
+ }
+ }
+ }
+ if( bSeekBack )
+ rInput.Seek( 0 );
+
+ bSwitchToUCS2 = FALSE;
+ }
+
+ nNextChPos = rInput.Tell();
+
+ if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
+ {
+ sal_Unicode cUC = USHRT_MAX;
+ sal_uChar c1, c2;
+
+ rInput >> c1 >> c2;
+ if( 2 == rInput.Tell() &&
+ !(rInput.IsEof() || rInput.GetError()) &&
+ ( (bUCS2BSrcEnc && 0xfe == c1 && 0xff == c2) ||
+ (!bUCS2BSrcEnc && 0xff == c1 && 0xfe == c2) ) )
+ rInput >> c1 >> c2;
+
+ bErr = rInput.IsEof() || rInput.GetError();
+ if( !bErr )
+ {
+ if( bUCS2BSrcEnc )
+ cUC = (sal_Unicode(c1) << 8) | c2;
+ else
+ cUC = (sal_Unicode(c2) << 8) | c1;
+ }
+
+ if( !bErr )
+ {
+ c = cUC;
+ }
+ }
+ else
+ {
+ sal_Size nChars = 0;
+ do
+ {
+ sal_Char c1; // signed, that's the text converter expects
+ rInput >> c1;
+ bErr = rInput.IsEof() || rInput.GetError();
+ if( !bErr )
+ {
+ if (
+ RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
+ RTL_TEXTENCODING_SYMBOL == eSrcEnc
+ )
+ {
+ // no convserion shall take place
+ c = (sal_Unicode)c1;
+ nChars = 1;
+ }
+ else
+ {
+ DBG_ASSERT( pImplData && pImplData->hConv,
+ "no text converter!" );
+
+ sal_Unicode cUC;
+ sal_uInt32 nInfo = 0;
+ sal_Size nCvtBytes;
+ nChars = rtl_convertTextToUnicode(
+ pImplData->hConv, pImplData->hContext,
+ &c1, 1, &cUC, 1,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
+ &nInfo, &nCvtBytes);
+ if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
+ {
+ // The conversion wasn't successfull because we haven't
+ // read enough characters.
+ if( pImplData->hContext != (rtl_TextToUnicodeContext)1 )
+ {
+ while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
+ {
+ rInput >> c1;
+ bErr = rInput.IsEof() || rInput.GetError();
+ if( bErr )
+ break;
+
+ nChars = rtl_convertTextToUnicode(
+ pImplData->hConv, pImplData->hContext,
+ &c1, 1, &cUC, 1,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
+ &nInfo, &nCvtBytes);
+ }
+ if( !bErr )
+ {
+ if( 1 == nChars && 0 == nInfo )
+ {
+ c = cUC;
+ }
+ else if( 0 != nChars || 0 != nInfo )
+ {
+ DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
+ "source buffer is to small" );
+ DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
+ "there is a conversion error" );
+ DBG_ASSERT( 0 == nChars,
+ "there is a converted character, but an error" );
+ // There are still errors, but nothing we can
+ // do
+ c = (sal_Unicode)'?';
+ nChars = 1;
+ }
+ }
+ }
+ else
+ {
+ sal_Char sBuffer[10];
+ sBuffer[0] = c1;
+ sal_uInt16 nLen = 1;
+ while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 &&
+ nLen < 10 )
+ {
+ rInput >> c1;
+ bErr = rInput.IsEof() || rInput.GetError();
+ if( bErr )
+ break;
+
+ sBuffer[nLen++] = c1;
+ nChars = rtl_convertTextToUnicode(
+ pImplData->hConv, 0, sBuffer, nLen, &cUC, 1,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
+ &nInfo, &nCvtBytes);
+ }
+ if( !bErr )
+ {
+ if( 1 == nChars && 0 == nInfo )
+ {
+ DBG_ASSERT( nCvtBytes == nLen,
+ "no all bytes have been converted!" );
+ c = cUC;
+ }
+ else
+ {
+ DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
+ "source buffer is to small" );
+ DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
+ "there is a conversion error" );
+ DBG_ASSERT( 0 == nChars,
+ "there is a converted character, but an error" );
+
+ // There are still errors, so we use the first
+ // character and restart after that.
+ c = (sal_Unicode)sBuffer[0];
+ rInput.SeekRel( -(nLen-1) );
+ nChars = 1;
+ }
+ }
+ }
+ }
+ else if( 1 == nChars && 0 == nInfo )
+ {
+ // The conversion was successfull
+ DBG_ASSERT( nCvtBytes == 1,
+ "no all bytes have been converted!" );
+ c = cUC;
+ }
+ else if( 0 != nChars || 0 != nInfo )
+ {
+ DBG_ASSERT( 0 == nChars,
+ "there is a converted character, but an error" );
+ DBG_ASSERT( 0 != nInfo,
+ "there is no converted character and no error" );
+ // #73398#: If the character could not be converted,
+ // because a conversion is not available, do no conversion at all.
+ c = (sal_Unicode)c1;
+ nChars = 1;
+
+ }
+ }
+ }
+ }
+ while( 0 == nChars && !bErr );
+ }
+ if( bErr )
+ {
+ if( ERRCODE_IO_PENDING == rInput.GetError() )
+ {
+ eState = SVPAR_PENDING;
+ return c;
+ }
+ else
+ return sal_Unicode(EOF);
+ }
+
+#ifdef DBG_UTIL
+ if( pImplData->aOut.IsOpen() )
+ pImplData->aOut << ByteString::ConvertFromUnicode( c,
+ RTL_TEXTENCODING_MS_1251 );
+#endif
+
+ if( c == '\n' )
+ {
+ IncLineNr();
+ SetLinePos( 1L );
+ }
+ else
+ IncLinePos();
+ return c;
+}
+
+int SvParser::GetNextToken()
+{
+ int nRet = 0;
+
+ if( !nTokenStackPos )
+ {
+ aToken.Erase(); // Token-Buffer loeschen
+ nTokenValue = -1; // Kennzeichen fuer kein Value gelesen
+ bTokenHasValue = false;
+
+ nRet = _GetNextToken();
+ if( SVPAR_PENDING == eState )
+ return nRet;
+ }
+
+ ++pTokenStackPos;
+ if( pTokenStackPos == pTokenStack + nTokenStackSize )
+ pTokenStackPos = pTokenStack;
+
+ // vom Stack holen ??
+ if( nTokenStackPos )
+ {
+ --nTokenStackPos;
+ nTokenValue = pTokenStackPos->nTokenValue;
+ bTokenHasValue = pTokenStackPos->bTokenHasValue;
+ aToken = pTokenStackPos->sToken;
+ nRet = pTokenStackPos->nTokenId;
+ }
+ // nein, dann das aktuelle auf den Stack
+ else if( SVPAR_WORKING == eState )
+ {
+ pTokenStackPos->sToken = aToken;
+ pTokenStackPos->nTokenValue = nTokenValue;
+ pTokenStackPos->bTokenHasValue = bTokenHasValue;
+ pTokenStackPos->nTokenId = nRet;
+ }
+ else if( SVPAR_ACCEPTED != eState && SVPAR_PENDING != eState )
+ eState = SVPAR_ERROR; // irgend ein Fehler
+
+ return nRet;
+}
+
+int SvParser::SkipToken( short nCnt ) // n Tokens zurueck "skippen"
+{
+ pTokenStackPos = GetStackPtr( nCnt );
+ short nTmp = nTokenStackPos - nCnt;
+ if( nTmp < 0 )
+ nTmp = 0;
+ else if( nTmp > nTokenStackSize )
+ nTmp = nTokenStackSize;
+ nTokenStackPos = BYTE(nTmp);
+
+ // und die Werte zurueck
+ aToken = pTokenStackPos->sToken;
+ nTokenValue = pTokenStackPos->nTokenValue;
+ bTokenHasValue = pTokenStackPos->bTokenHasValue;
+
+ return pTokenStackPos->nTokenId;
+}
+
+SvParser::TokenStackType* SvParser::GetStackPtr( short nCnt )
+{
+ BYTE nAktPos = BYTE(pTokenStackPos - pTokenStack );
+ if( nCnt > 0 )
+ {
+ if( nCnt >= nTokenStackSize )
+ nCnt = (nTokenStackSize-1);
+ if( nAktPos + nCnt < nTokenStackSize )
+ nAktPos = sal::static_int_cast< BYTE >(nAktPos + nCnt);
+ else
+ nAktPos = sal::static_int_cast< BYTE >(
+ nAktPos + (nCnt - nTokenStackSize));
+ }
+ else if( nCnt < 0 )
+ {
+ if( -nCnt >= nTokenStackSize )
+ nCnt = -nTokenStackSize+1;
+ if( -nCnt <= nAktPos )
+ nAktPos = sal::static_int_cast< BYTE >(nAktPos + nCnt);
+ else
+ nAktPos = sal::static_int_cast< BYTE >(
+ nAktPos + (nCnt + nTokenStackSize));
+ }
+ return pTokenStack + nAktPos;
+}
+
+// wird fuer jedes Token gerufen, das in CallParser erkannt wird
+void SvParser::NextToken( int )
+{
+}
+
+
+// fuers asynchrone lesen aus dem SvStream
+
+int SvParser::GetSaveToken() const
+{
+ return pImplData ? pImplData->nSaveToken : 0;
+}
+
+void SvParser::SaveState( int nToken )
+{
+ // aktuellen Status merken
+ if( !pImplData )
+ {
+ pImplData = new SvParser_Impl;
+ pImplData->nSaveToken = 0;
+ }
+
+ pImplData->nFilePos = rInput.Tell();
+ pImplData->nToken = nToken;
+
+ pImplData->aToken = aToken;
+ pImplData->nlLineNr = nlLineNr;
+ pImplData->nlLinePos = nlLinePos;
+ pImplData->nTokenValue= nTokenValue;
+ pImplData->bTokenHasValue = bTokenHasValue;
+ pImplData->nNextCh = nNextCh;
+}
+
+void SvParser::RestoreState()
+{
+ // alten Status wieder zurueck setzen
+ if( pImplData )
+ {
+ if( ERRCODE_IO_PENDING == rInput.GetError() )
+ rInput.ResetError();
+ aToken = pImplData->aToken;
+ nlLineNr = pImplData->nlLineNr;
+ nlLinePos = pImplData->nlLinePos;
+ nTokenValue= pImplData->nTokenValue;
+ bTokenHasValue=pImplData->bTokenHasValue;
+ nNextCh = pImplData->nNextCh;
+
+ pImplData->nSaveToken = pImplData->nToken;
+
+ rInput.Seek( pImplData->nFilePos );
+ }
+}
+
+void SvParser::Continue( int )
+{
+}
+
+void SvParser::BuildWhichTbl( SvUShorts &rWhichMap,
+ USHORT *pWhichIds,
+ USHORT nWhichIds )
+{
+ USHORT aNewRange[2];
+
+ for( USHORT nCnt = 0; nCnt < nWhichIds; ++nCnt, ++pWhichIds )
+ if( *pWhichIds )
+ {
+ aNewRange[0] = aNewRange[1] = *pWhichIds;
+ BOOL bIns = TRUE;
+
+ // Position suchen
+ for ( USHORT nOfs = 0; rWhichMap[nOfs]; nOfs += 2 )
+ {
+ if( *pWhichIds < rWhichMap[nOfs] - 1 )
+ {
+ // neuen Range davor
+ rWhichMap.Insert( aNewRange, 2, nOfs );
+ bIns = FALSE;
+ break;
+ }
+ else if( *pWhichIds == rWhichMap[nOfs] - 1 )
+ {
+ // diesen Range nach unten erweitern
+ rWhichMap[nOfs] = *pWhichIds;
+ bIns = FALSE;
+ break;
+ }
+ else if( *pWhichIds == rWhichMap[nOfs+1] + 1 )
+ {
+ if( rWhichMap[nOfs+2] != 0 && rWhichMap[nOfs+2] == *pWhichIds + 1 )
+ {
+ // mit dem naechsten Bereich mergen
+ rWhichMap[nOfs+1] = rWhichMap[nOfs+3];
+ rWhichMap.Remove( nOfs+2, 2 );
+ }
+ else
+ // diesen Range nach oben erweitern
+ rWhichMap[nOfs+1] = *pWhichIds;
+ bIns = FALSE;
+ break;
+ }
+ }
+
+ // einen Range hinten anhaengen
+ if( bIns )
+ rWhichMap.Insert( aNewRange, 2, rWhichMap.Count()-1 );
+ }
+}
+
+
+IMPL_STATIC_LINK( SvParser, NewDataRead, void*, EMPTYARG )
+{
+ switch( pThis->eState )
+ {
+ case SVPAR_PENDING:
+ // Wenn gerade ein File geladen wird duerfen wir nicht weiterlaufen,
+ // sondern muessen den Aufruf ignorieren.
+ if( pThis->IsDownloadingFile() )
+ break;
+
+ pThis->eState = SVPAR_WORKING;
+ pThis->RestoreState();
+
+ pThis->Continue( pThis->pImplData->nToken );
+
+ if( ERRCODE_IO_PENDING == pThis->rInput.GetError() )
+ pThis->rInput.ResetError();
+
+ if( SVPAR_PENDING != pThis->eState )
+ pThis->ReleaseRef(); // ansonsten sind wir fertig!
+ break;
+
+ case SVPAR_WAITFORDATA:
+ pThis->eState = SVPAR_WORKING;
+ break;
+
+ case SVPAR_NOTSTARTED:
+ case SVPAR_WORKING:
+ break;
+
+ default:
+ pThis->ReleaseRef(); // ansonsten sind wir fertig!
+ break;
+ }
+
+ return 0;
+}
+
+/*========================================================================
+ *
+ * SvKeyValueIterator.
+ *
+ *======================================================================*/
+SV_DECL_PTRARR_DEL(SvKeyValueList_Impl, SvKeyValue*, 0, 4)
+SV_IMPL_PTRARR(SvKeyValueList_Impl, SvKeyValue*);
+
+/*
+ * SvKeyValueIterator.
+ */
+SvKeyValueIterator::SvKeyValueIterator (void)
+ : m_pList (new SvKeyValueList_Impl),
+ m_nPos (0)
+{
+}
+
+/*
+ * ~SvKeyValueIterator.
+ */
+SvKeyValueIterator::~SvKeyValueIterator (void)
+{
+ delete m_pList;
+}
+
+/*
+ * GetFirst.
+ */
+BOOL SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal)
+{
+ m_nPos = m_pList->Count();
+ return GetNext (rKeyVal);
+}
+
+/*
+ * GetNext.
+ */
+BOOL SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal)
+{
+ if (m_nPos > 0)
+ {
+ rKeyVal = *m_pList->GetObject(--m_nPos);
+ return TRUE;
+ }
+ else
+ {
+ // Nothing to do.
+ return FALSE;
+ }
+}
+
+/*
+ * Append.
+ */
+void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal)
+{
+ SvKeyValue *pKeyVal = new SvKeyValue (rKeyVal);
+ m_pList->C40_INSERT(SvKeyValue, pKeyVal, m_pList->Count());
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/svtools/source/table/defaultinputhandler.cxx b/svtools/source/table/defaultinputhandler.cxx
new file mode 100644
index 000000000000..ad8f7a7562d3
--- /dev/null
+++ b/svtools/source/table/defaultinputhandler.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_svtools.hxx"
+
+#include "svtools/table/defaultinputhandler.hxx"
+#include "svtools/table/abstracttablecontrol.hxx"
+
+#include <tools/debug.hxx>
+#include <vcl/event.hxx>
+#include <vcl/cursor.hxx>
+#include "svtools/table/tabledatawindow.hxx"
+
+//........................................................................
+namespace svt { namespace table
+{
+//.......................................................................
+
+ struct DefaultInputHandler_Impl
+ {
+ };
+
+ //====================================================================
+ //= DefaultInputHandler
+ //====================================================================
+ //--------------------------------------------------------------------
+ DefaultInputHandler::DefaultInputHandler()
+ :m_pImpl( new DefaultInputHandler_Impl )
+ ,m_bResize(false)
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DefaultInputHandler::~DefaultInputHandler()
+ {
+ DELETEZ( m_pImpl );
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::MouseMove( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt )
+ {
+ Point aPoint = _rMEvt.GetPosPixel();
+ if(m_bResize)
+ {
+ _rControl.resizeColumn(aPoint);
+ return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::MouseButtonDown( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt )
+ {
+ bool bHandled = false;
+ Point aPoint = _rMEvt.GetPosPixel();
+ RowPos nRow = _rControl.getCurrentRow(aPoint);
+ if(nRow == -1)
+ {
+ m_bResize = _rControl.startResizeColumn(aPoint);
+ bHandled = true;
+ }
+ else if(nRow >= 0)
+ {
+ if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION)
+ {
+ _rControl.setCursorAtCurrentCell(aPoint);
+ bHandled = true;
+ }
+ else
+ {
+ if(!_rControl.isRowSelected(nRow))
+ bHandled = _rControl.getSelEngine()->SelMouseButtonDown(_rMEvt);
+ else
+ bHandled = true;
+ }
+ }
+ return bHandled;
+ }
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::MouseButtonUp( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt )
+ {
+ bool bHandled = false;
+ Point aPoint = _rMEvt.GetPosPixel();
+ if(_rControl.getCurrentRow(aPoint) >= 0)
+ {
+ if(m_bResize)
+ {
+ m_bResize = _rControl.endResizeColumn(aPoint);
+ bHandled = true;
+ }
+ else if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION)
+ {
+ bHandled = true;
+ }
+ else
+ {
+ bHandled = _rControl.getSelEngine()->SelMouseButtonUp(_rMEvt);
+ }
+ }
+ else
+ {
+ if(m_bResize)
+ {
+ m_bResize = _rControl.endResizeColumn(aPoint);
+ bHandled = true;
+ }
+ }
+ return bHandled;
+ }
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::KeyInput( IAbstractTableControl& _rControl, const KeyEvent& rKEvt )
+ {
+ bool bHandled = false;
+
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ USHORT nKeyCode = rKeyCode.GetCode();
+
+ struct _ActionMapEntry
+ {
+ USHORT nKeyCode;
+ USHORT nKeyModifier;
+ TableControlAction eAction;
+ }
+ static aKnownActions[] = {
+ { KEY_DOWN, 0, cursorDown },
+ { KEY_UP, 0, cursorUp },
+ { KEY_LEFT, 0, cursorLeft },
+ { KEY_RIGHT, 0, cursorRight },
+ { KEY_HOME, 0, cursorToLineStart },
+ { KEY_END, 0, cursorToLineEnd },
+ { KEY_PAGEUP, 0, cursorPageUp },
+ { KEY_PAGEDOWN, 0, cursorPageDown },
+ { KEY_PAGEUP, KEY_MOD1, cursorToFirstLine },
+ { KEY_PAGEDOWN, KEY_MOD1, cursorToLastLine },
+ { KEY_HOME, KEY_MOD1, cursorTopLeft },
+ { KEY_END, KEY_MOD1, cursorBottomRight },
+ { KEY_SPACE, KEY_MOD1, cursorSelectRow },
+ { KEY_UP, KEY_SHIFT, cursorSelectRowUp },
+ { KEY_DOWN, KEY_SHIFT, cursorSelectRowDown },
+ { KEY_END, KEY_SHIFT, cursorSelectRowAreaBottom },
+ { KEY_HOME, KEY_SHIFT, cursorSelectRowAreaTop },
+
+ { 0, 0, invalidTableControlAction }
+ };
+
+ const _ActionMapEntry* pActions = aKnownActions;
+ for ( ; pActions->eAction != invalidTableControlAction; ++pActions )
+ {
+ if ( ( pActions->nKeyCode == nKeyCode ) && ( pActions->nKeyModifier == rKeyCode.GetAllModifier() ) )
+ {
+ bHandled = _rControl.dispatchAction( pActions->eAction );
+ break;
+ }
+ }
+
+ return bHandled;
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::GetFocus( IAbstractTableControl& _rControl )
+ {
+ _rControl.showCursor();
+ return false; // continue processing
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::LoseFocus( IAbstractTableControl& _rControl )
+ {
+ _rControl.hideCursor();
+ return false; // continue processing
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::RequestHelp( IAbstractTableControl& _rControl, const HelpEvent& _rHEvt )
+ {
+ (void)_rControl;
+ (void)_rHEvt;
+ // TODO
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::Command( IAbstractTableControl& _rControl, const CommandEvent& _rCEvt )
+ {
+ (void)_rControl;
+ (void)_rCEvt;
+ // TODO
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::PreNotify( IAbstractTableControl& _rControl, NotifyEvent& _rNEvt )
+ {
+ (void)_rControl;
+ (void)_rNEvt;
+ // TODO
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultInputHandler::Notify( IAbstractTableControl& _rControl, NotifyEvent& _rNEvt )
+ {
+ (void)_rControl;
+ (void)_rNEvt;
+ // TODO
+ return false;
+ }
+//........................................................................
+} } // namespace svt::table
+//........................................................................
diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx
new file mode 100644
index 000000000000..8e5bd181a583
--- /dev/null
+++ b/svtools/source/table/gridtablerenderer.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_svtools.hxx"
+
+#include "svtools/table/gridtablerenderer.hxx"
+
+#include <tools/debug.hxx>
+#include <vcl/window.hxx>
+#include <vcl/image.hxx>
+
+//........................................................................
+namespace svt { namespace table
+{
+//........................................................................
+
+ struct GridTableRenderer_Impl
+ {
+ ITableModel& rModel;
+ RowPos nCurrentRow;
+
+ GridTableRenderer_Impl( ITableModel& _rModel )
+ :rModel( _rModel )
+ ,nCurrentRow( ROW_INVALID )
+ {
+ }
+ };
+
+ //====================================================================
+ //= GridTableRenderer
+ //====================================================================
+ //--------------------------------------------------------------------
+ GridTableRenderer::GridTableRenderer( ITableModel& _rModel )
+ :m_pImpl( new GridTableRenderer_Impl( _rModel ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ GridTableRenderer::~GridTableRenderer()
+ {
+ DELETEZ( m_pImpl );
+ }
+
+ //--------------------------------------------------------------------
+ RowPos GridTableRenderer::getCurrentRow()
+ {
+ return m_pImpl->nCurrentRow;
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::PaintHeaderArea(
+ OutputDevice& _rDevice, const Rectangle& _rArea, bool _bIsColHeaderArea, bool _bIsRowHeaderArea,
+ const StyleSettings& _rStyle )
+ {
+ OSL_PRECOND( _bIsColHeaderArea || _bIsRowHeaderArea,
+ "GridTableRenderer::PaintHeaderArea: invalid area flags!" );
+
+ _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR);
+ Color background = m_pImpl->rModel.getHeaderBackgroundColor();
+ if( background != 0xFFFFFF)
+ _rDevice.SetFillColor(background);
+ else
+ _rDevice.SetFillColor(_rStyle.GetDialogColor());
+ _rDevice.SetLineColor(_rStyle.GetSeparatorColor());
+ _rDevice.DrawRect( _rArea );
+ // delimiter lines at bottom/right
+ _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
+ _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() );
+
+ _rDevice.Pop();
+ (void)_bIsColHeaderArea;
+ (void)_bIsRowHeaderArea;
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::PaintColumnHeader( ColPos _nCol, bool _bActive, bool _bSelected,
+ OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle )
+ {
+ _rDevice.Push( PUSH_LINECOLOR);
+ _rDevice.SetLineColor(_rStyle.GetSeparatorColor());
+ _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight());
+
+ String sHeaderText;
+ PColumnModel pColumn = m_pImpl->rModel.getColumnModel( _nCol );
+ DBG_ASSERT( !!pColumn, "GridTableRenderer::PaintColumnHeader: invalid column model object!" );
+ if ( !!pColumn )
+ sHeaderText = pColumn->getName();
+ if(m_pImpl->rModel.getTextColor() != 0x000000)
+ _rDevice.SetTextColor(m_pImpl->rModel.getTextColor());
+ else
+ _rDevice.SetTextColor(_rStyle.GetFieldTextColor());
+ ULONG nHorFlag = TEXT_DRAW_LEFT;
+ ULONG nVerFlag = TEXT_DRAW_TOP;
+ if(m_pImpl->rModel.getVerticalAlign() == 1)
+ nVerFlag = TEXT_DRAW_VCENTER;
+ else if(m_pImpl->rModel.getVerticalAlign() == 2)
+ nVerFlag = TEXT_DRAW_BOTTOM;
+ if(m_pImpl->rModel.getColumnModel(_nCol)->getHorizontalAlign() == 1)
+ nHorFlag = TEXT_DRAW_CENTER;
+ else if(m_pImpl->rModel.getColumnModel(_nCol)->getHorizontalAlign() == 2)
+ nHorFlag = TEXT_DRAW_RIGHT;
+ Rectangle aRect(_rArea);
+ aRect.Left()+=4; aRect.Right()-=4;
+ aRect.Bottom()-=2;
+ _rDevice.DrawText( aRect, sHeaderText, nHorFlag | nVerFlag | TEXT_DRAW_CLIP);
+ _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
+ _rDevice.Pop();
+
+ (void)_bActive;
+ // no special painting for the active column at the moment
+
+ (void)_bSelected;
+ //selection for column header not yet implemented
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::PrepareRow( RowPos _nRow, bool _bActive, bool _bSelected,
+ OutputDevice& _rDevice, const Rectangle& _rRowArea, const StyleSettings& _rStyle )
+ {
+ // remember the row for subsequent calls to the other ->ITableRenderer methods
+ m_pImpl->nCurrentRow = _nRow;
+
+ _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR);
+
+ Color aRowBackground = m_pImpl->rModel.getOddRowBackgroundColor();
+ Color line = m_pImpl->rModel.getLineColor();
+ Color aRowBackground2 = m_pImpl->rModel.getEvenRowBackgroundColor();
+ Color fieldColor = _rStyle.GetFieldColor();
+ if(aRowBackground == 0xFFFFFF)
+ aRowBackground = fieldColor;
+ if(aRowBackground2 == 0xFFFFFF)
+ aRowBackground2 = fieldColor;
+ //if row is selected background color becomes blue, and lines should be also blue
+ //if they aren't user defined
+ if(_bSelected)
+ {
+ Color aSelected(_rStyle.GetHighlightColor());
+ aRowBackground = aSelected;
+ if(line == 0xFFFFFF)
+ _rDevice.SetLineColor(aRowBackground);
+ else
+ _rDevice.SetLineColor(line);
+ }
+ //if row not selected, check the cases whether user defined backgrounds are set
+ //and set line color to be the same
+ else
+ {
+ if(aRowBackground2 != fieldColor && _nRow%2)
+ {
+ aRowBackground = aRowBackground2;
+ if(line == 0xFFFFFF)
+ _rDevice.SetLineColor(aRowBackground);
+ else
+ _rDevice.SetLineColor(line);
+ }
+ //fill the rows with alternating background colors if second background color is specified
+ else if(aRowBackground != fieldColor && line == 0xFFFFFF)
+ _rDevice.SetLineColor(aRowBackground);
+ else
+ {
+ //if Line color is set, then it was user defined and should be visible
+ //if it wasn't set, it'll be the same as the default background color, so lines still won't be visible
+ _rDevice.SetLineColor(line);
+ }
+ }
+ _rDevice.SetFillColor( aRowBackground );
+ _rDevice.DrawRect( _rRowArea );
+
+ // TODO: active?
+
+ _rDevice.Pop();
+ (void)_bActive;
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::PaintRowHeader( bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea,
+ const StyleSettings& _rStyle, rtl::OUString& _rText )
+ {
+ _rDevice.Push( PUSH_LINECOLOR);
+ _rDevice.SetLineColor(_rStyle.GetSeparatorColor());
+ _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
+ if(m_pImpl->rModel.getTextColor() != 0x000000)
+ _rDevice.SetTextColor(m_pImpl->rModel.getTextColor());
+ else
+ _rDevice.SetTextColor(_rStyle.GetFieldTextColor());
+ ULONG nHorFlag = TEXT_DRAW_LEFT;
+ ULONG nVerFlag = TEXT_DRAW_TOP;
+ if(m_pImpl->rModel.getVerticalAlign() == 1)
+ nVerFlag = TEXT_DRAW_VCENTER;
+ else if(m_pImpl->rModel.getVerticalAlign() == 2)
+ nVerFlag = TEXT_DRAW_BOTTOM;
+ if(m_pImpl->rModel.getColumnModel(0)->getHorizontalAlign() == 1)
+ nHorFlag = TEXT_DRAW_CENTER;
+ else if(m_pImpl->rModel.getColumnModel(0)->getHorizontalAlign() == 2)
+ nHorFlag = TEXT_DRAW_RIGHT;
+ Rectangle aRect(_rArea);
+ aRect.Left()+=4; aRect.Right()-=4;
+ aRect.Bottom()-=2;
+ _rDevice.DrawText( aRect, _rText, nHorFlag | nVerFlag | TEXT_DRAW_CLIP);
+ // TODO: active? selected?
+ (void)_bActive;
+ (void)_bSelected;
+ //at the moment no special paint for selected row header
+ _rDevice.Pop();
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::PaintCellImage( ColPos _nColumn, bool _bSelected, bool _bActive,
+ OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, Image* _pCellData )
+ {
+ _rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR);
+ Color background1 = m_pImpl->rModel.getOddRowBackgroundColor();
+ Color background2 = m_pImpl->rModel.getEvenRowBackgroundColor();
+ Color line = m_pImpl->rModel.getLineColor();
+ //if row is selected and line color isn't user specified, set it blue
+ if(_bSelected)
+ {
+ if(line == 0xFFFFFF)
+ _rDevice.SetLineColor(_rStyle.GetHighlightColor());
+ else
+ _rDevice.SetLineColor(line);
+ }
+ //else set line color to the color of row background
+ else
+ {
+ if(background2 != 0xFFFFFF && m_pImpl->nCurrentRow%2)
+ {
+ if(line == 0xFFFFFF)
+ _rDevice.SetLineColor(background2);
+ else
+ _rDevice.SetLineColor(line);
+ }
+ else if(background1 != 0xFFFFFF && line == 0xFFFFFF)
+ _rDevice.SetLineColor(background1);
+ else
+ {
+ //if line color is set, then it was user defined and should be visible
+ //if it wasn't set, it'll be the same as the default background color, so lines still won't be visible
+ _rDevice.SetLineColor(line);
+ }
+ }
+ _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() );
+
+ Rectangle aRect( _rArea );
+ ++aRect.Left(); --aRect.Right();
+ aRect.Top(); aRect.Bottom();
+ Point imagePos(Point(aRect.Left(), aRect.Top()));
+ Size imageSize = _pCellData->GetSizePixel();
+ if(aRect.GetWidth() > imageSize.Width())
+ {
+ if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 1)
+ imagePos.X() = aRect.Left()+((double)(aRect.GetWidth() - imageSize.Width()))/2;
+ else if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 2)
+ imagePos.X() = aRect.Right() - imageSize.Width();
+ }
+ else
+ imageSize.Width() = aRect.GetWidth();
+ if(aRect.GetHeight() > imageSize.Height())
+ {
+ if(m_pImpl->rModel.getVerticalAlign() == 1)
+ imagePos.Y() = aRect.Top()+((double)(aRect.GetHeight() - imageSize.Height()))/2;
+ else if(m_pImpl->rModel.getVerticalAlign() == 2)
+ imagePos.Y() = aRect.Bottom() - imageSize.Height();
+ }
+ else
+ imageSize.Height() = aRect.GetHeight()-1;
+ Image& image (*_pCellData);
+ _rDevice.DrawImage(imagePos, imageSize, image, 0);
+ _rDevice.Pop();
+
+ (void)_bActive;
+ // no special painting for the active cell at the moment
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::PaintCellString( ColPos _nColumn, bool _bSelected, bool _bActive,
+ OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, rtl::OUString& _rText )
+ {
+ _rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ Color background1 = m_pImpl->rModel.getOddRowBackgroundColor();
+ Color background2 = m_pImpl->rModel.getEvenRowBackgroundColor();
+ Color line = m_pImpl->rModel.getLineColor();
+ //if row is selected and line color isn't user specified, set it blue
+ if(_bSelected)
+ {
+ if(line == 0xFFFFFF)
+ _rDevice.SetLineColor(_rStyle.GetHighlightColor());
+ else
+ _rDevice.SetLineColor(line);
+ }
+ //else set line color to the color of row background
+ else
+ {
+ if(background2 != 0xFFFFFF && m_pImpl->nCurrentRow%2)
+ {
+ if(line == 0xFFFFFF)
+ _rDevice.SetLineColor(background2);
+ else
+ _rDevice.SetLineColor(line);
+ }
+ else if(background1 != 0xFFFFFF && line == 0xFFFFFF)
+ _rDevice.SetLineColor(background1);
+ else
+ {
+ //if Line color is set, then it was user defined and should be visible
+ //if it wasn't set, it'll be the same as the default background color, so lines still won't be visible
+ _rDevice.SetLineColor(line);
+ }
+ }
+ _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() );
+
+ Rectangle aRect( _rArea );
+ ++aRect.Left(); --aRect.Right();
+ aRect.Top(); aRect.Bottom();
+ if(_bSelected)
+ _rDevice.SetTextColor(_rStyle.GetHighlightTextColor());
+ else if(m_pImpl->rModel.getTextColor() != 0x000000)
+ _rDevice.SetTextColor(m_pImpl->rModel.getTextColor());
+ else
+ _rDevice.SetTextColor(_rStyle.GetFieldTextColor());
+ ULONG nHorFlag = TEXT_DRAW_LEFT;
+ ULONG nVerFlag = TEXT_DRAW_TOP;
+ if(m_pImpl->rModel.getVerticalAlign() == 1)
+ nVerFlag = TEXT_DRAW_VCENTER;
+ else if(m_pImpl->rModel.getVerticalAlign() == 2)
+ nVerFlag = TEXT_DRAW_BOTTOM;
+ if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 1)
+ nHorFlag = TEXT_DRAW_CENTER;
+ else if(m_pImpl->rModel.getColumnModel(_nColumn)->getHorizontalAlign() == 2)
+ nHorFlag = TEXT_DRAW_RIGHT;
+ Rectangle textRect(_rArea);
+ textRect.Left()+=4; textRect.Right()-=4;
+ textRect.Bottom()-=2;
+ _rDevice.DrawText( textRect, _rText, nHorFlag | nVerFlag | TEXT_DRAW_CLIP);
+
+ _rDevice.Pop();
+ (void)_bActive;
+ // no special painting for the active cell at the moment
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::ShowCellCursor( Window& _rView, const Rectangle& _rCursorRect)
+ {
+ _rView.ShowFocus( _rCursorRect );
+ }
+
+ //--------------------------------------------------------------------
+ void GridTableRenderer::HideCellCursor( Window& _rView, const Rectangle& _rCursorRect)
+ {
+ (void)_rCursorRect;
+ _rView.HideFocus();
+
+ }
+
+//........................................................................
+} } // namespace svt::table
+//........................................................................
+
diff --git a/svtools/source/table/makefile.mk b/svtools/source/table/makefile.mk
new file mode 100644
index 000000000000..cf1adc76fe92
--- /dev/null
+++ b/svtools/source/table/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=..$/..
+
+ENABLE_EXCEPTIONS=TRUE
+PRJNAME=svtools
+TARGET=table
+#LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/tablecontrol.obj \
+ $(SLO)$/tablecontrol_impl.obj \
+ $(SLO)$/gridtablerenderer.obj \
+ $(SLO)$/tablegeometry.obj \
+ $(SLO)$/defaultinputhandler.obj \
+ $(SLO)$/tabledatawindow.obj
+
+#LIB1TARGET= $(SLB)$/$(TARGET).lib
+#LIB1OBJFILES= $(SLOFILES)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx
new file mode 100644
index 000000000000..33c80e642118
--- /dev/null
+++ b/svtools/source/table/tablecontrol.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_svtools.hxx"
+
+#include "svtools/table/tablecontrol.hxx"
+#include "tablegeometry.hxx"
+#include "tablecontrol_impl.hxx"
+#include "accessibletableimp.hxx"
+#include "svtools/table/tabledatawindow.hxx"
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+using namespace ::com::sun::star::uno;
+using ::com::sun::star::accessibility::XAccessible;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::lang;
+using namespace utl;
+//using namespace rtl;
+//........................................................................
+namespace svt { namespace table
+{
+ //====================================================================
+ //= AccessibleTableControl_Impl
+ //====================================================================
+ // ----------------------------------------------------------------------------
+ Reference< XAccessible > AccessibleTableControl_Impl::getAccessibleTableHeader( AccessibleTableControlObjType _eObjType )
+ {
+ if ( m_pAccessible && m_pAccessible->isAlive() )
+ return m_pAccessible->getTableHeader( _eObjType );
+ return NULL;
+ }
+ // ----------------------------------------------------------------------------
+ Reference< XAccessible > AccessibleTableControl_Impl::getAccessibleTable( )
+ {
+ if ( m_pAccessible && m_pAccessible->isAlive() )
+ return m_pAccessible->getTable( );
+ return NULL;
+ }
+
+ //====================================================================
+ //= TableControl
+ //====================================================================
+ //--------------------------------------------------------------------
+ TableControl::TableControl( Window* _pParent, WinBits _nStyle )
+ :Control( _pParent, _nStyle )
+ ,m_pImpl( new TableControl_Impl( *this ) )
+ ,m_bSelectionChanged(false)
+ ,m_bTooltip(false)
+ {
+ TableDataWindow* aTableData = m_pImpl->getDataWindow();
+ aTableData->SetMouseButtonDownHdl( LINK( this, TableControl, ImplMouseButtonDownHdl ) );
+ aTableData->SetMouseButtonUpHdl( LINK( this, TableControl, ImplMouseButtonUpHdl ) );
+ aTableData->SetSelectHdl( LINK( this, TableControl, ImplSelectHdl ) );
+ m_pAccessTable.reset(new ::svt::table::AccessibleTableControl_Impl());
+
+ // by default, use the background as determined by the style settings
+ const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() );
+ SetBackground( Wallpaper( aWindowColor ) );
+ SetFillColor( aWindowColor );
+ }
+
+ //--------------------------------------------------------------------
+ TableControl::~TableControl()
+ {
+ ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
+ DELETEZ( m_pImpl );
+ if ( m_pAccessTable->m_pAccessible )
+ {
+ m_pAccessTable->m_pAccessible->dispose();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl::GetFocus()
+ {
+ if ( !m_pImpl->getInputHandler()->GetFocus( *m_pImpl ) )
+ {
+ Control::GetFocus();
+ Control::GrabFocus();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl::LoseFocus()
+ {
+ if ( !m_pImpl->getInputHandler()->LoseFocus( *m_pImpl ) )
+ Control::LoseFocus();
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl::KeyInput( const KeyEvent& rKEvt )
+ {
+ if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) )
+ Control::KeyInput( rKEvt );
+ else
+ {
+ if(m_bSelectionChanged)
+ {
+ Select();
+ m_bSelectionChanged = false;
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void TableControl::StateChanged( StateChangedType i_nStateChange )
+ {
+ Control::StateChanged( i_nStateChange );
+
+ // forward certain settings to the data window
+ switch ( i_nStateChange )
+ {
+ case STATE_CHANGE_CONTROLBACKGROUND:
+ if ( IsControlBackground() )
+ getDataWindow()->SetControlBackground( GetControlBackground() );
+ else
+ getDataWindow()->SetControlBackground();
+ break;
+
+ case STATE_CHANGE_CONTROLFOREGROUND:
+ if ( IsControlForeground() )
+ getDataWindow()->SetControlForeground( GetControlForeground() );
+ else
+ getDataWindow()->SetControlForeground();
+ break;
+
+ case STATE_CHANGE_CONTROLFONT:
+ if ( IsControlFont() )
+ getDataWindow()->SetControlFont( GetControlFont() );
+ else
+ getDataWindow()->SetControlFont();
+ break;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl::Resize()
+ {
+ Control::Resize();
+ m_pImpl->onResize();
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl::SetModel( PTableModel _pModel )
+ {
+ m_pImpl->setModel( _pModel );
+ }
+
+ //--------------------------------------------------------------------
+ PTableModel TableControl::GetModel() const
+ {
+ return m_pImpl->getModel();
+ }
+
+ //--------------------------------------------------------------------
+ RowPos TableControl::GetTopRow() const
+ {
+ return m_pImpl->getTopRow();
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl::SetTopRow( RowPos _nRow )
+ {
+ // TODO
+ (void)_nRow;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 TableControl::GetCurrentRow() const
+ {
+ return m_pImpl->getCurRow();
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 TableControl::GetCurrentColumn() const
+ {
+ return m_pImpl->getCurColumn();
+ }
+
+ //--------------------------------------------------------------------
+ bool TableControl::GoTo( ColPos _nColumn, RowPos _nRow )
+ {
+ return m_pImpl->goTo( _nColumn, _nRow );
+ }
+ //--------------------------------------------------------------------
+ sal_Bool TableControl::GoToCell(sal_Int32 _nColPos, sal_Int32 _nRowPos)
+ {
+ return m_pImpl->goTo( _nColPos, _nRowPos );
+ }
+ //--------------------------------------------------------------------
+ void TableControl::clearSelection()
+ {
+ m_pImpl->clearSelection();
+ }
+ //--------------------------------------------------------------------
+ void TableControl::InvalidateDataWindow(RowPos _nRowStart, RowPos _nRowEnd, bool _bRemoved)
+ {
+ Rectangle _rRect;
+ if(_bRemoved)
+ m_pImpl->invalidateRows();
+ else
+ {
+ if(m_bSelectionChanged)
+ {
+ m_pImpl->invalidateSelectedRegion(_nRowStart, _nRowEnd, _rRect);
+ m_bSelectionChanged = false;
+ }
+ else
+ m_pImpl->invalidateRow(_nRowStart, _rRect);
+ }
+ }
+ //--------------------------------------------------------------------
+ std::vector<sal_Int32>& TableControl::GetSelectedRows()
+ {
+ return m_pImpl->getSelectedRows();
+ }
+ //--------------------------------------------------------------------
+ void TableControl::RemoveSelectedRow(RowPos _nRowPos)
+ {
+ m_pImpl->removeSelectedRow(_nRowPos);
+ }
+ //--------------------------------------------------------------------
+
+ RowPos TableControl::GetCurrentRow(const Point& rPoint)
+ {
+ return m_pImpl->getCurrentRow( rPoint );
+ }
+
+ SelectionEngine* TableControl::getSelEngine()
+ {
+ return m_pImpl->getSelEngine();
+ }
+
+ TableDataWindow* TableControl::getDataWindow()
+ {
+ return m_pImpl->getDataWindow();
+ }
+
+ Reference< XAccessible > TableControl::CreateAccessible()
+ {
+ Window* pParent = GetAccessibleParentWindow();
+ DBG_ASSERT( pParent, "TableControl::CreateAccessible - parent not found" );
+
+ if( pParent && !m_pAccessTable->m_pAccessible)
+ {
+ Reference< XAccessible > xAccParent = pParent->GetAccessible();
+ if( xAccParent.is() )
+ {
+ m_pAccessTable->m_pAccessible = getAccessibleFactory().createAccessibleTableControl(
+ xAccParent, *this
+ );
+ }
+ }
+ Reference< XAccessible > xAccessible;
+ if ( m_pAccessTable->m_pAccessible )
+ xAccessible = m_pAccessTable->m_pAccessible->getMyself();
+ return xAccessible;
+ }
+ Reference<XAccessible> TableControl::CreateAccessibleControl( sal_Int32 _nIndex )
+ {
+ (void)_nIndex;
+ DBG_ASSERT( FALSE, "TableControl::CreateAccessibleControl: to be overwritten!" );
+ return NULL;
+ }
+ ::rtl::OUString TableControl::GetAccessibleObjectName( AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const
+ {
+ ::rtl::OUString aRetText;
+ //Window* pWin;
+ switch( eObjType )
+ {
+ case TCTYPE_GRIDCONTROL:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridControl" ) );
+ break;
+ case TCTYPE_TABLE:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Table" ) );
+ break;
+ case TCTYPE_ROWHEADERBAR:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderBar" ) );
+ break;
+ case TCTYPE_COLUMNHEADERBAR:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) );
+ break;
+ case TCTYPE_TABLECELL:
+ aRetText = GetAccessibleCellText(_nRow, _nCol);
+ break;
+ case TCTYPE_ROWHEADERCELL:
+ aRetText = GetRowName(_nRow);
+ break;
+ case TCTYPE_COLUMNHEADERCELL:
+ aRetText = GetColumnName(_nCol);
+ break;
+ default:
+ OSL_ENSURE(0,"GridControl::GetAccessibleName: invalid enum!");
+ }
+ return aRetText;
+ }
+// -----------------------------------------------------------------------------
+
+::rtl::OUString TableControl::GetAccessibleObjectDescription( AccessibleTableControlObjType eObjType, sal_Int32 ) const
+{
+ ::rtl::OUString aRetText;
+ switch( eObjType )
+ {
+ case TCTYPE_GRIDCONTROL:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridControl description" ) );
+ break;
+ case TCTYPE_TABLE:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLE description" ) );
+ break;
+ case TCTYPE_ROWHEADERBAR:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERBAR description" ) );
+ break;
+ case TCTYPE_COLUMNHEADERBAR:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERBAR description" ) );
+ break;
+ case TCTYPE_TABLECELL:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLECELL description" ) );
+ break;
+ case TCTYPE_ROWHEADERCELL:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERCELL description" ) );
+ break;
+ case TCTYPE_COLUMNHEADERCELL:
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERCELL description" ) );
+ break;
+ }
+ return aRetText;
+}
+// -----------------------------------------------------------------------------
+
+::rtl::OUString TableControl::GetRowDescription( sal_Int32 _nRow) const
+{
+ (void)_nRow;
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "row description" ) );
+}
+// -----------------------------------------------------------------------------
+
+::rtl::OUString TableControl::GetRowName( sal_Int32 _nIndex) const
+{
+ return GetModel()->getRowHeaderName()[_nIndex];
+}
+// -----------------------------------------------------------------------------
+
+::rtl::OUString TableControl::GetColumnDescription( sal_uInt16 _nColumn) const
+{
+ (void)_nColumn;
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "col description" ) );
+}
+// -----------------------------------------------------------------------------
+
+::rtl::OUString TableControl::GetColumnName( sal_Int32 _nIndex) const
+{
+ return GetModel()->getColumnModel(_nIndex)->getName();
+}
+
+// -----------------------------------------------------------------------------
+
+::com::sun::star::uno::Any TableControl::GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos) const
+{
+ ::com::sun::star::uno::Any cellContent(::com::sun::star::uno::Any(::rtl::OUString::createFromAscii("")));
+ std::vector<std::vector< ::com::sun::star::uno::Any > >& aTableContent = GetModel()->getCellContent();
+ if(&aTableContent)
+ cellContent = aTableContent[_nRowPos][_nColPos];
+ return cellContent;
+}
+// -----------------------------------------------------------------------------
+
+::rtl::OUString TableControl::GetAccessibleCellText( sal_Int32 _nRowPos, sal_Int32 _nColPos) const
+{
+ const ::com::sun::star::uno::Any cellContent = GetCellContent(_nRowPos, _nColPos);
+ return m_pImpl->convertToString(cellContent);
+}
+// -----------------------------------------------------------------------------
+
+void TableControl::FillAccessibleStateSet(
+ ::utl::AccessibleStateSetHelper& rStateSet,
+ AccessibleTableControlObjType eObjType ) const
+{
+ switch( eObjType )
+ {
+ case TCTYPE_GRIDCONTROL:
+ case TCTYPE_TABLE:
+
+ rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE);
+ if ( HasFocus() )
+ rStateSet.AddState( AccessibleStateType::FOCUSED );
+ if ( IsActive() )
+ rStateSet.AddState( AccessibleStateType::ACTIVE );
+ if ( IsEnabled() )
+ rStateSet.AddState( AccessibleStateType::ENABLED );
+ if ( IsReallyVisible() )
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+
+ break;
+ case TCTYPE_ROWHEADERBAR:
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ break;
+ case TCTYPE_COLUMNHEADERBAR:
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ break;
+ case TCTYPE_TABLECELL:
+ {
+ rStateSet.AddState( AccessibleStateType::TRANSIENT );
+ rStateSet.AddState( AccessibleStateType::SELECTABLE);
+ if( GetSelectedRowCount()>0)
+ rStateSet.AddState( AccessibleStateType::SELECTED);
+ }
+ break;
+ case TCTYPE_ROWHEADERCELL:
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ rStateSet.AddState( AccessibleStateType::TRANSIENT );
+ break;
+ case TCTYPE_COLUMNHEADERCELL:
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ break;
+ }
+}
+
+Rectangle TableControl::GetWindowExtentsRelative( Window *pRelativeWindow ) const
+{
+ return Control::GetWindowExtentsRelative( pRelativeWindow );
+}
+//-----------------------------------------------------------------------------
+void TableControl::GrabFocus()
+{
+ Control::GrabFocus();
+}
+// -----------------------------------------------------------------------------
+Reference< XAccessible > TableControl::GetAccessible( BOOL bCreate )
+{
+ return Control::GetAccessible( bCreate );
+}
+// -----------------------------------------------------------------------------
+Window* TableControl::GetAccessibleParentWindow() const
+{
+ return Control::GetAccessibleParentWindow();
+}
+// -----------------------------------------------------------------------------
+Window* TableControl::GetWindowInstance()
+{
+ return this;
+}
+
+sal_Bool TableControl::HasRowHeader()
+{
+ return GetModel()->hasRowHeaders();
+}
+//--------------------------------------------------------------------------------
+sal_Bool TableControl::HasColHeader()
+{
+ return GetModel()->hasColumnHeaders();
+}
+//--------------------------------------------------------------------------------
+sal_Int32 TableControl::GetAccessibleControlCount() const
+{
+ sal_Int32 count = 0;
+ if(GetRowCount()>0)
+ count+=1;
+ if(GetModel()->hasRowHeaders())
+ count+=1;
+ if(GetModel()->hasColumnHeaders())
+ count+=1;
+ return count;
+}
+sal_Bool TableControl::ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint )
+{
+ sal_Int32 nRow = m_pImpl->getCurrentRow(_rPoint);
+ sal_Int32 nCol = GetCurrentColumn();
+ _rnIndex = nRow * GetColumnCount() + nCol;
+ return nRow>=0 ? sal_True : sal_False;
+}
+
+long TableControl::GetRowCount() const
+{
+ return m_pImpl->getRowCount();
+}
+long TableControl::GetColumnCount() const
+{
+ return m_pImpl->getColumnCount();
+}
+sal_Bool TableControl::HasRowHeader() const
+{
+ PTableModel pModel = GetModel();
+ return pModel->hasRowHeaders();
+}
+sal_Int32 TableControl::GetSelectedRowCount() const
+{
+ return m_pImpl->getSelectedRows().size();
+}
+bool TableControl::IsRowSelected( long _nRow ) const
+{
+ return m_pImpl->isRowSelected(m_pImpl->getSelectedRows(), _nRow);
+}
+sal_Bool TableControl::ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint )
+{
+ _rnRow = m_pImpl->getCurrentRow(_rPoint);
+ _rnColPos = GetCurrentColumn();
+ return _rnRow>=0 ? sal_True : sal_False;
+}
+void TableControl::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const
+{
+ if ( GetCurrentRow() == _nRow && GetCurrentColumn() == _nColumnPos )
+ _rStateSet.AddState( AccessibleStateType::FOCUSED );
+ else // only transient when column is not focused
+ _rStateSet.AddState( AccessibleStateType::TRANSIENT );
+}
+Rectangle TableControl::GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex)
+{
+ (void)_nRow;
+ (void)_nColumnPos;
+ return GetCharacterBounds(nIndex);
+}
+sal_Int32 TableControl::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
+{
+ (void)_nRow;
+ (void)_nColumnPos;
+ return GetIndexForPoint(_rPoint);
+;
+}
+ // -----------------------------------------------------------------------------
+sal_Bool TableControl::isAccessibleAlive( ) const
+{
+ return ( NULL != m_pAccessTable->m_pAccessible ) && m_pAccessTable->m_pAccessible->isAlive();
+}
+
+// -----------------------------------------------------------------------------
+::svt::IAccessibleFactory& TableControl::getAccessibleFactory()
+{
+ return m_pAccessTable->m_aFactoryAccess.getFactory();
+}
+// -----------------------------------------------------------------------------
+void TableControl::commitGridControlEvent( sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
+{
+ if ( isAccessibleAlive() )
+ m_pAccessTable->m_pAccessible->commitEvent( _nEventId, _rNewValue, _rOldValue);
+}
+// -----------------------------------------------------------------------------
+Rectangle TableControl::calcHeaderRect(sal_Bool _bIsColumnBar,BOOL _bOnScreen)
+{
+ (void)_bOnScreen;
+ return m_pImpl->calcHeaderRect(_bIsColumnBar);
+}
+// -----------------------------------------------------------------------------
+Rectangle TableControl::calcTableRect(BOOL _bOnScreen)
+{
+ (void)_bOnScreen;
+ return m_pImpl->calcTableRect();
+}
+//--------------------------------------------------------------------
+::com::sun::star::uno::Sequence< sal_Int32 >& TableControl::getColumnsForTooltip()
+{
+ return m_nCols;
+}
+//--------------------------------------------------------------------
+::com::sun::star::uno::Sequence< ::rtl::OUString >& TableControl::getTextForTooltip()
+{
+ return m_aText;
+}
+//--------------------------------------------------------------------
+void TableControl::setTooltip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aText, const ::com::sun::star::uno::Sequence< sal_Int32 >& nCols )
+{
+ m_aText = aText;
+ m_nCols = nCols;
+ m_bTooltip = true;
+}
+// -----------------------------------------------------------------------
+void TableControl::selectionChanged(bool _bChanged)
+{
+ m_bSelectionChanged = _bChanged;
+}
+// -----------------------------------------------------------------------
+bool TableControl::isTooltip()
+{
+ return m_bTooltip;
+}
+// -----------------------------------------------------------------------
+IMPL_LINK( TableControl, ImplSelectHdl, void*, EMPTYARG )
+{
+ Select();
+ return 1;
+}
+IMPL_LINK( TableControl, ImplMouseButtonDownHdl, MouseEvent*, pData )
+{
+ CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pData );
+ return 1;
+}
+IMPL_LINK( TableControl, ImplMouseButtonUpHdl, MouseEvent*, pData )
+{
+ CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, pData );
+ return 1;
+}
+// -----------------------------------------------------------------------
+void TableControl::Select()
+{
+ ImplCallEventListenersAndHandler( VCLEVENT_TABLEROW_SELECT, m_aSelectHdl, this );
+}
+//........................................................................
+}} // namespace svt::table
+//........................................................................
diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx
new file mode 100644
index 000000000000..90bc4899209b
--- /dev/null
+++ b/svtools/source/table/tablecontrol_impl.cxx
@@ -0,0 +1,2363 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "svtools/table/tablecontrol.hxx"
+#include "svtools/table/defaultinputhandler.hxx"
+#include "svtools/table/tablemodel.hxx"
+#include "tablecontrol_impl.hxx"
+#include "tablegeometry.hxx"
+#include "svtools/table/tabledatawindow.hxx"
+#include <com/sun/star/awt/XControl.hpp>
+#include <vcl/scrbar.hxx>
+#include <vcl/seleng.hxx>
+#include <rtl/ref.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <vcl/image.hxx>
+#include <com/sun/star/graphic/XGraphic.hpp>
+
+#include <functional>
+#include <stdlib.h>
+
+//........................................................................
+namespace svt { namespace table
+{
+//........................................................................
+
+ //====================================================================
+ //= TempHideCursor
+ //====================================================================
+ class TempHideCursor
+ {
+ private:
+ IAbstractTableControl& m_rTable;
+
+ public:
+ TempHideCursor( IAbstractTableControl& _rTable )
+ :m_rTable( _rTable )
+ {
+ m_rTable.hideCursor();
+ }
+ ~TempHideCursor()
+ {
+ m_rTable.showCursor();
+ }
+ };
+
+ //====================================================================
+ //= EmptyTableModel
+ //====================================================================
+ /** default implementation of an ->ITableModel, used as fallback when no
+ real model is present
+
+ Instances of this class are static in any way, and provide the least
+ necessary default functionality for a table model.
+ */
+ class EmptyTableModel : public ITableModel
+ {
+ public:
+ EmptyTableModel()
+ {
+ }
+
+ // ITableModel overridables
+ virtual TableSize getColumnCount() const
+ {
+ return 0;
+ }
+ virtual TableSize getRowCount() const
+ {
+ return 0;
+ }
+ virtual bool hasColumnHeaders() const
+ {
+ return false;
+ }
+ virtual bool hasRowHeaders() const
+ {
+ return false;
+ }
+ virtual void setRowHeaders(bool _bRowHeaders)
+ {
+ (void)_bRowHeaders;
+ }
+ virtual void setColumnHeaders(bool _bColumnHeaders)
+ {
+ (void)_bColumnHeaders;
+ }
+ void setColumnCount(TableSize _nColCount)
+ {
+ (void) _nColCount;
+ }
+ void setRowCount(TableSize _nRowCount)
+ {
+ (void)_nRowCount;
+ }
+ virtual bool isCellEditable( ColPos col, RowPos row ) const
+ {
+ (void)col;
+ (void)row;
+ return false;
+ }
+ virtual void addTableModelListener( const PTableModelListener& listener )
+ {
+ (void)listener;
+ // ignore
+ }
+ virtual void removeTableModelListener( const PTableModelListener& listener )
+ {
+ (void)listener;
+ // ignore
+ }
+ virtual PColumnModel getColumnModel( ColPos column )
+ {
+ DBG_ERROR( "EmptyTableModel::getColumnModel: invalid call!" );
+ (void)column;
+ return PColumnModel();
+ }
+ virtual PColumnModel getColumnModelByID( ColumnID id )
+ {
+ DBG_ERROR( "EmptyTableModel::getColumnModel: invalid call!" );
+ (void)id;
+ return PColumnModel();
+ }
+ virtual PTableRenderer getRenderer() const
+ {
+ return PTableRenderer();
+ }
+ virtual PTableInputHandler getInputHandler() const
+ {
+ return PTableInputHandler();
+ }
+ virtual TableMetrics getRowHeight() const
+ {
+ return 5 * 100;
+ }
+ virtual void setRowHeight(TableMetrics _nRowHeight)
+ {
+ (void)_nRowHeight;
+ }
+ virtual TableMetrics getColumnHeaderHeight() const
+ {
+ return 0;
+ }
+ virtual TableMetrics getRowHeaderWidth() const
+ {
+ return 0;
+ }
+ virtual ScrollbarVisibility getVerticalScrollbarVisibility(int , int ) const
+ {
+ return ScrollbarShowNever;
+ }
+ virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int , int ) const
+ {
+ return ScrollbarShowNever;
+ }
+ virtual bool hasVerticalScrollbar()
+ {
+ return false;
+ }
+ virtual bool hasHorizontalScrollbar()
+ {
+ return false;
+ }
+ virtual void setCellContent(const std::vector<std::vector< ::com::sun::star::uno::Any > >& )
+ {
+ }
+ virtual ::com::sun::star::util::Color getLineColor()
+ {
+ return 0;
+ }
+ virtual void setLineColor(::com::sun::star::util::Color )
+ {
+ }
+ virtual ::com::sun::star::util::Color getHeaderBackgroundColor()
+ {
+ return -1;
+ }
+ virtual void setHeaderBackgroundColor(::com::sun::star::util::Color )
+ {
+ }
+ virtual ::com::sun::star::util::Color getTextColor()
+ {
+ return 0;
+ }
+ virtual void setTextColor(::com::sun::star::util::Color )
+ {
+ }
+ virtual ::com::sun::star::util::Color getOddRowBackgroundColor()
+ {
+ return -1;
+ }
+ virtual void setOddRowBackgroundColor(::com::sun::star::util::Color )
+ {
+ }
+ virtual ::com::sun::star::style::VerticalAlignment getVerticalAlign()
+ {
+ return com::sun::star::style::VerticalAlignment(0);
+ }
+ virtual void setVerticalAlign(com::sun::star::style::VerticalAlignment )
+ {
+ }
+ virtual ::com::sun::star::util::Color getEvenRowBackgroundColor()
+ {
+ return -1;
+ }
+ virtual void setEvenRowBackgroundColor(::com::sun::star::util::Color )
+ {
+ }
+ virtual std::vector<std::vector< ::com::sun::star::uno::Any > >& getCellContent()
+ {
+ return m_aCellContent;
+ }
+ virtual void setRowHeaderName(const std::vector<rtl::OUString>& )
+ {
+ }
+ virtual std::vector<rtl::OUString>& getRowHeaderName()
+ {
+ aRowHeaderNames.clear();
+ aRowHeaderNames.push_back(rtl::OUString::createFromAscii(""));
+ return aRowHeaderNames;
+ }
+ private:
+ std::vector<rtl::OUString> aRowHeaderNames;
+ std::vector<std::vector< ::com::sun::star::uno::Any > > m_aCellContent;
+ };
+
+
+ //====================================================================
+ //= TableControl_Impl
+ //====================================================================
+ DBG_NAME( TableControl_Impl )
+
+#if DBG_UTIL
+ //====================================================================
+ //= SuspendInvariants
+ //====================================================================
+ class SuspendInvariants
+ {
+ private:
+ const TableControl_Impl& m_rTable;
+ sal_Int32 m_nSuspendFlags;
+
+ public:
+ SuspendInvariants( const TableControl_Impl& _rTable, sal_Int32 _nSuspendFlags )
+ :m_rTable( _rTable )
+ ,m_nSuspendFlags( _nSuspendFlags )
+ {
+ //DBG_ASSERT( ( m_rTable.m_nRequiredInvariants & m_nSuspendFlags ) == m_nSuspendFlags,
+ // "SuspendInvariants: cannot suspend what is already suspended!" );
+ const_cast< TableControl_Impl& >( m_rTable ).m_nRequiredInvariants &= ~m_nSuspendFlags;
+ }
+ ~SuspendInvariants()
+ {
+ const_cast< TableControl_Impl& >( m_rTable ).m_nRequiredInvariants |= m_nSuspendFlags;
+ }
+ };
+ #define DBG_SUSPEND_INV( flags ) \
+ SuspendInvariants aSuspendInv( *this, flags );
+#else
+ #define DBG_SUSPEND_INV( flags )
+#endif
+
+#if DBG_UTIL
+ //====================================================================
+ const char* TableControl_Impl_checkInvariants( const void* _pInstance )
+ {
+ return static_cast< const TableControl_Impl* >( _pInstance )->impl_checkInvariants();
+ }
+
+ namespace
+ {
+ template< typename SCALAR_TYPE >
+ bool lcl_checkLimitsExclusive( SCALAR_TYPE _nValue, SCALAR_TYPE _nMin, SCALAR_TYPE _nMax )
+ {
+ return ( _nValue > _nMin ) && ( _nValue < _nMax );
+ }
+
+ template< typename SCALAR_TYPE >
+ bool lcl_checkLimitsExclusive_OrDefault_OrFallback( SCALAR_TYPE _nValue, SCALAR_TYPE _nMin, SCALAR_TYPE _nMax,
+ PTableModel _pModel, SCALAR_TYPE _nDefaultOrFallback )
+ {
+ if ( !_pModel )
+ return _nValue == _nDefaultOrFallback;
+ if ( _nMax <= _nMin )
+ return _nDefaultOrFallback == _nValue;
+ return lcl_checkLimitsExclusive( _nValue, _nMin, _nMax );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ const sal_Char* TableControl_Impl::impl_checkInvariants() const
+ {
+ if ( !m_pModel )
+ return "no model, not even an EmptyTableModel";
+
+ if ( !m_pDataWindow )
+ return "invalid data window!";
+
+ if ( m_pModel->getColumnCount() != m_nColumnCount )
+ return "column counts are inconsistent!";
+
+ if ( m_pModel->getRowCount() != m_nRowCount )
+ return "row counts are inconsistent!";
+
+ if ( ( m_nCurColumn != COL_INVALID ) && !m_aColumnWidthsPixel.empty() && ( m_nCurColumn < 0 ) || ( m_nCurColumn >= (ColPos)m_aColumnWidthsPixel.size() ) )
+ return "current column is invalid!";
+
+ if ( m_aColumnWidthsPixel.size() != m_aAccColumnWidthsPixel.size() )
+ return "columnd width caches are inconsistent!";
+
+ if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nTopRow, (RowPos)-1, m_nRowCount, getModel(), (RowPos)0 ) )
+ return "invalid top row value!";
+
+ if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nCurRow, (RowPos)-1, m_nRowCount, getModel(), ROW_INVALID ) )
+ return "invalid current row value!";
+
+ if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nLeftColumn, (ColPos)-1, m_nColumnCount, getModel(), (ColPos)0 ) )
+ return "invalid current column value!";
+
+ if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nCurColumn, (ColPos)-1, m_nColumnCount, getModel(), COL_INVALID ) )
+ return "invalid current column value!";
+
+ if ( m_pInputHandler != m_pModel->getInputHandler() )
+ return "input handler is not the model-provided one!";
+
+ // m_nColHeaderHeightPixel consistent with the model's value?
+ {
+ TableMetrics nHeaderHeight = m_pModel->hasColumnHeaders() ? m_pModel->getColumnHeaderHeight() : 0;
+ nHeaderHeight = m_rAntiImpl.LogicToPixel( Size( 0, nHeaderHeight ), MAP_APPFONT ).Height();
+ if ( nHeaderHeight != m_nColHeaderHeightPixel )
+ return "column header heights are inconsistent!";
+ }
+
+ bool isDummyModel = dynamic_cast< const EmptyTableModel* >( m_pModel.get() ) != NULL;
+ if ( !isDummyModel )
+ {
+ TableMetrics nRowHeight = m_pModel->getRowHeight();
+ nRowHeight = m_rAntiImpl.LogicToPixel( Size( 0, nRowHeight ), MAP_APPFONT).Height();
+ if ( nRowHeight != m_nRowHeightPixel )
+ return "row heights are inconsistent!";
+ }
+
+ // m_nRowHeaderWidthPixel consistent with the model's value?
+ {
+ TableMetrics nHeaderWidth = m_pModel->hasRowHeaders() ? m_pModel->getRowHeaderWidth() : 0;
+ nHeaderWidth = m_rAntiImpl.LogicToPixel( Size( nHeaderWidth, 0 ), MAP_APPFONT ).Width();
+ if ( nHeaderWidth != m_nRowHeaderWidthPixel )
+ return "row header widths are inconsistent!";
+ }
+
+ // TODO: check m_aColumnWidthsPixel and m_aAccColumnWidthsPixel
+ if ( m_nCursorHidden < 0 )
+ return "invalid hidden count for the cursor!";
+
+ if ( ( m_nRequiredInvariants & INV_SCROLL_POSITION ) && m_pVScroll )
+ {
+ DBG_SUSPEND_INV( INV_SCROLL_POSITION );
+ // prevent infinite recursion
+
+ if ( m_pVScroll->GetThumbPos() != m_nTopRow )
+ return "vertical scroll bar |position| is incorrect!";
+ if ( m_pVScroll->GetRange().Max() != m_nRowCount )
+ return "vertical scroll bar |range| is incorrect!";
+ if ( m_pVScroll->GetVisibleSize() != impl_getVisibleRows( false ) )
+ return "vertical scroll bar |visible size| is incorrect!";
+ }
+
+ if ( ( m_nRequiredInvariants & INV_SCROLL_POSITION ) && m_pHScroll )
+ {
+ DBG_SUSPEND_INV( INV_SCROLL_POSITION );
+ // prevent infinite recursion
+
+ if ( m_pHScroll->GetThumbPos() != m_nLeftColumn )
+ return "horizontal scroll bar |position| is incorrect!";
+ if ( m_pHScroll->GetRange().Max() != m_nColumnCount )
+ return "horizontal scroll bar |range| is incorrect!";
+ if ( m_pHScroll->GetVisibleSize() != impl_getVisibleColumns( false ) )
+ return "horizontal scroll bar |visible size| is incorrect!";
+ }
+
+ return NULL;
+ }
+#endif
+
+#define DBG_CHECK_ME() \
+ DBG_CHKTHIS( TableControl_Impl, TableControl_Impl_checkInvariants )
+
+ //--------------------------------------------------------------------
+ TableControl_Impl::TableControl_Impl( TableControl& _rAntiImpl )
+ :m_rAntiImpl ( _rAntiImpl )
+ ,m_pModel ( new EmptyTableModel )
+ ,m_pInputHandler ( )
+ ,m_nRowHeightPixel ( 15 )
+ ,m_nColHeaderHeightPixel( 0 )
+ ,m_nRowHeaderWidthPixel ( 0 )
+ ,m_nColumnCount ( 0 )
+ ,m_nRowCount ( 0 )
+ ,m_nCurColumn ( COL_INVALID )
+ ,m_nCurRow ( ROW_INVALID )
+ ,m_nLeftColumn ( 0 )
+ ,m_nTopRow ( 0 )
+ ,m_nCursorHidden ( 1 )
+ ,m_pDataWindow ( new TableDataWindow( *this ) )
+ ,m_pVScroll ( NULL )
+ ,m_pHScroll ( NULL )
+ ,m_pScrollCorner ( NULL )
+ ,m_pSelEngine ( )
+ ,m_nRowSelected ( )
+ ,m_pTableFunctionSet ( new TableFunctionSet(this ) )
+ ,m_nAnchor (-1 )
+ ,m_bResizing ( false )
+ ,m_nResizingColumn ( 0 )
+ ,m_bResizingGrid ( false )
+#if DBG_UTIL
+ ,m_nRequiredInvariants ( INV_SCROLL_POSITION )
+#endif
+ {
+ DBG_CTOR( TableControl_Impl, TableControl_Impl_checkInvariants );
+ m_pSelEngine = new SelectionEngine(m_pDataWindow, m_pTableFunctionSet);
+ m_pSelEngine->SetSelectionMode(SINGLE_SELECTION);
+ m_pDataWindow->SetPosPixel( Point( 0, 0 ) );
+ m_pDataWindow->Show();
+ }
+
+ //--------------------------------------------------------------------
+ TableControl_Impl::~TableControl_Impl()
+ {
+ DBG_DTOR( TableControl_Impl, TableControl_Impl_checkInvariants );
+
+ DELETEZ( m_pVScroll );
+ DELETEZ( m_pHScroll );
+ DELETEZ( m_pScrollCorner );
+ DELETEZ( m_pTableFunctionSet );
+ DELETEZ( m_pSelEngine );
+ DELETEZ( m_pDataWindow );
+ }
+
+ //--------------------------------------------------------------------
+ PTableModel TableControl_Impl::getModel() const
+ {
+ if ( dynamic_cast< const EmptyTableModel* >( m_pModel.get() ) != NULL )
+ // if it's an EmptyTableModel, pretend that there is no model
+ return PTableModel();
+
+ return m_pModel;
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::setModel( PTableModel _pModel )
+ {
+ DBG_CHECK_ME();
+
+ TempHideCursor aHideCursor( *this );
+
+ m_pModel = _pModel;
+ if ( !m_pModel)
+ m_pModel.reset( new EmptyTableModel );
+
+ m_nCurRow = ROW_INVALID;
+ m_nCurColumn = COL_INVALID;
+
+ // recalc some model-dependent cached info
+ impl_ni_updateCachedModelValues();
+
+ // completely invalidate
+ m_rAntiImpl.Invalidate();
+
+ // reset cursor to (0,0)
+ if ( m_nRowCount ) m_nCurRow = 0;
+ if ( m_nColumnCount ) m_nCurColumn = 0;
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const
+ {
+ DBG_CHECK_ME();
+
+ _rCellArea.Left() = 0;
+ _rCellArea.Top() = 0;
+
+ // determine the right-most border of the last column which is
+ // at least partially visible
+ _rCellArea.Right() = m_nRowHeaderWidthPixel;
+ if ( !m_aAccColumnWidthsPixel.empty() )
+ {
+ // the number of pixels which are scroll out of the left hand
+ // side of the window
+ long nScrolledOutLeft = m_nLeftColumn == 0 ? 0 : m_aAccColumnWidthsPixel[ m_nLeftColumn - 1 ];
+
+ ArrayOfLong::const_reverse_iterator loop = m_aAccColumnWidthsPixel.rbegin();
+ do
+ {
+ _rCellArea.Right() = *loop++ - nScrolledOutLeft + m_nRowHeaderWidthPixel;
+ }
+ while ( ( loop != m_aAccColumnWidthsPixel.rend() )
+ && ( *loop - nScrolledOutLeft >= _rCellArea.Right() )
+ );
+ }
+ // so far, _rCellArea.Right() denotes the first pixel *after* the cell area
+ --_rCellArea.Right();
+
+ // determine the last row which is at least partially visible
+ _rCellArea.Bottom() =
+ m_nColHeaderHeightPixel
+ + impl_getVisibleRows( true ) * m_nRowHeightPixel
+ - 1;
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const
+ {
+ DBG_CHECK_ME();
+
+ impl_getAllVisibleCellsArea( _rCellArea );
+ _rCellArea.Left() = m_nRowHeaderWidthPixel;
+ _rCellArea.Top() = m_nColHeaderHeightPixel;
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_ni_updateCachedModelValues()
+ {
+ m_nRowHeightPixel = 15;
+ m_nColHeaderHeightPixel = 0;
+ m_nRowHeaderWidthPixel = 0;
+ m_pInputHandler.reset();
+ m_nColumnCount = m_nRowCount = 0;
+
+ m_nRowHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getRowHeight() ), MAP_APPFONT ).Height();
+ if ( m_pModel->hasColumnHeaders() )
+ m_nColHeaderHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getColumnHeaderHeight() ), MAP_APPFONT ).Height();
+ if ( m_pModel->hasRowHeaders() )
+ m_nRowHeaderWidthPixel = m_rAntiImpl.LogicToPixel( Size( m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT).Width();
+
+ impl_ni_updateColumnWidths();
+
+ m_pInputHandler = m_pModel->getInputHandler();
+ if ( !m_pInputHandler )
+ m_pInputHandler.reset( new DefaultInputHandler );
+
+ m_nColumnCount = m_pModel->getColumnCount();
+ m_nRowCount = m_pModel->getRowCount();
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_ni_updateColumnWidths()
+ {
+ m_aColumnWidthsPixel.resize( 0 );
+ m_aAccColumnWidthsPixel.resize( 0 );
+ if ( !m_pModel )
+ return;
+
+ TableSize colCount = m_pModel->getColumnCount();
+
+ m_aColumnWidthsPixel.reserve( colCount );
+ m_aAccColumnWidthsPixel.reserve( colCount );
+ if(colCount>0)
+ {
+ std::vector<sal_Int32> aPrePixelWidths(0);
+ long accumulatedPixelWidth = 0;
+ int lastResizableCol = -1;
+ double gridWidth = m_rAntiImpl.GetOutputSizePixel().Width();
+ if(m_pModel->hasRowHeaders())
+ {
+ TableMetrics rowHeaderWidth = m_pModel->getRowHeaderWidth();
+ gridWidth-= m_rAntiImpl.LogicToPixel( Size( rowHeaderWidth, 0 ), MAP_APPFONT ).Width();
+ }
+ if(m_pModel->hasVerticalScrollbar())
+ {
+ sal_Int32 scrollbarWidth = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize();
+ gridWidth-=scrollbarWidth;
+ }
+ double colWidthsSum = 0.0;
+ double colWithoutFixedWidthsSum = 0.0;
+ double minColWithoutFixedSum = 0.0;
+ for ( ColPos col = 0; col < colCount; ++col )
+ {
+ PColumnModel pColumn = m_pModel->getColumnModel( col );
+ DBG_ASSERT( !!pColumn, "TableControl_Impl::impl_ni_updateColumnWidths: invalid column returned by the model!" );
+ if ( !pColumn )
+ continue;
+ TableMetrics colWidth = 0;
+ TableMetrics colPrefWidth = pColumn->getPreferredWidth();
+ bool bResizable = pColumn->isResizable();
+ if(pColumn->getMinWidth() == 0 && bResizable)
+ {
+ pColumn->setMinWidth(1);
+ minColWithoutFixedSum+=m_rAntiImpl.PixelToLogic( Size( 1, 0 ), MAP_APPFONT ).Width();
+ }
+ if(pColumn->getMaxWidth() == 0 && bResizable)
+ pColumn->setMaxWidth(m_rAntiImpl.PixelToLogic( Size( (int)gridWidth, 0 ), MAP_APPFONT ).Width());
+ if( colPrefWidth != 0)
+ {
+ if(m_bResizingGrid)
+ {
+ colWidth = pColumn->getWidth();
+ pColumn->setPreferredWidth(0);
+ }
+ else
+ {
+ colWidth = colPrefWidth;
+ pColumn->setWidth(colPrefWidth);
+ }
+ }
+ else
+ colWidth = pColumn->getWidth();
+ long pixelWidth = m_rAntiImpl.LogicToPixel( Size( colWidth, 0 ), MAP_APPFONT ).Width();
+ if(bResizable && colPrefWidth == 0)
+ {
+ colWithoutFixedWidthsSum+=pixelWidth;
+ lastResizableCol = col;
+ }
+ colWidthsSum+=pixelWidth;
+ aPrePixelWidths.push_back(pixelWidth);
+ }
+ double gridWidthWithoutFixed = gridWidth - colWidthsSum + colWithoutFixedWidthsSum;
+ double scalingFactor = 1.0;
+ if(m_bResizingGrid)
+ {
+ if(gridWidthWithoutFixed > (minColWithoutFixedSum+colWidthsSum - colWithoutFixedWidthsSum))
+ scalingFactor = gridWidthWithoutFixed/colWithoutFixedWidthsSum;
+ }
+ else
+ {
+ if(colWidthsSum < gridWidthWithoutFixed)
+ {
+ if(colWithoutFixedWidthsSum>0)
+ scalingFactor = gridWidthWithoutFixed/colWithoutFixedWidthsSum;
+ }
+ }
+ for ( ColPos i = 0; i < colCount; ++i )
+ {
+ PColumnModel pColumn = m_pModel->getColumnModel( i );
+ DBG_ASSERT( !!pColumn, "TableControl_Impl::impl_ni_updateColumnWidths: invalid column returned by the model!" );
+ if ( !pColumn )
+ continue;
+ if(pColumn->isResizable() && pColumn->getPreferredWidth() == 0)
+ {
+ aPrePixelWidths[i]*=scalingFactor;
+ TableMetrics logicColWidth = m_rAntiImpl.PixelToLogic( Size( aPrePixelWidths[i], 0 ), MAP_APPFONT ).Width();
+ pColumn->setWidth(logicColWidth);
+ }
+ m_aColumnWidthsPixel.push_back( aPrePixelWidths[i] );
+ m_aAccColumnWidthsPixel.push_back( accumulatedPixelWidth += aPrePixelWidths[i] );
+ }
+ if(gridWidth > m_aAccColumnWidthsPixel[colCount-1])
+ {
+ if(lastResizableCol >= 0)
+ {
+ PColumnModel pColumn = m_pModel->getColumnModel(lastResizableCol);
+ m_aColumnWidthsPixel[lastResizableCol]+=gridWidth-m_aAccColumnWidthsPixel[colCount-1];
+ TableMetrics logicColWidth1 = m_rAntiImpl.PixelToLogic( Size( m_aColumnWidthsPixel[lastResizableCol], 0 ), MAP_APPFONT ).Width();
+ pColumn->setWidth(logicColWidth1);
+ while(lastResizableCol < colCount)
+ {
+ if(lastResizableCol == 0)
+ m_aAccColumnWidthsPixel[0] = m_aColumnWidthsPixel[lastResizableCol];
+ else
+ m_aAccColumnWidthsPixel[lastResizableCol]=m_aAccColumnWidthsPixel[lastResizableCol-1]+m_aColumnWidthsPixel[lastResizableCol];
+ ++lastResizableCol;
+ }
+ }
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //................................................................
+ /// determines whether a scrollbar is needed for the given values
+ bool lcl_determineScrollbarNeed( ScrollbarVisibility _eVisibility,
+ long _nVisibleUnits, long _nRange )
+ {
+ if ( _eVisibility == ScrollbarShowNever )
+ return false;
+ if ( _eVisibility == ScrollbarShowAlways )
+ return true;
+ return _nVisibleUnits > _nRange;
+ }
+
+ //................................................................
+ void lcl_setButtonRepeat( Window& _rWindow, ULONG _nDelay )
+ {
+ AllSettings aSettings = _rWindow.GetSettings();
+ MouseSettings aMouseSettings = aSettings.GetMouseSettings();
+
+ aMouseSettings.SetButtonRepeat( _nDelay );
+ aSettings.SetMouseSettings( aMouseSettings );
+
+ _rWindow.SetSettings( aSettings, TRUE );
+ }
+
+ //................................................................
+ void lcl_updateScrollbar( Window& _rParent, ScrollBar*& _rpBar,
+ ScrollbarVisibility _eVisibility, long _nVisibleUnits,
+ long _nPosition, long _nLineSize, long _nRange,
+ bool _bHorizontal, const Link& _rScrollHandler )
+ {
+ // do we need the scrollbar?
+ bool bNeedBar = lcl_determineScrollbarNeed( _eVisibility, _nVisibleUnits, _nRange );
+
+ // do we currently have the scrollbar?
+ bool bHaveBar = _rpBar != NULL;
+
+ // do we need to correct the scrollbar visibility?
+ if ( bHaveBar && !bNeedBar )
+ {
+ DELETEZ( _rpBar );
+ }
+ else if ( !bHaveBar && bNeedBar )
+ {
+ _rpBar = new ScrollBar(
+ &_rParent,
+ WB_DRAG | ( _bHorizontal ? WB_HSCROLL : WB_VSCROLL )
+ );
+ _rpBar->SetScrollHdl( _rScrollHandler );
+ // get some speed into the scrolling ....
+ lcl_setButtonRepeat( *_rpBar, 0 );
+ }
+
+ if ( _rpBar )
+ {
+ _rpBar->SetRange( Range( 0, _nRange ) );
+ _rpBar->SetVisibleSize( _nVisibleUnits );
+ _rpBar->SetPageSize( _nVisibleUnits );
+ _rpBar->SetLineSize( _nLineSize );
+ _rpBar->SetThumbPos( _nPosition );
+ _rpBar->Show();
+ }
+ }
+
+ //................................................................
+ /** returns the number of rows fitting into the given range,
+ for the given row height. Partially fitting rows are counted, too, if the
+ respective parameter says so.
+ */
+ TableSize lcl_getRowsFittingInto( long _nOverallHeight, long _nRowHeightPixel, bool _bAcceptPartialRow = false )
+ {
+ return _bAcceptPartialRow
+ ? ( _nOverallHeight + ( _nRowHeightPixel - 1 ) ) / _nRowHeightPixel
+ : _nOverallHeight / _nRowHeightPixel;
+ }
+
+ //................................................................
+ /** returns the number of columns fitting into the given area,
+ with the first visible column as given. Partially fitting columns are counted, too,
+ if the respective parameter says so.
+ */
+ TableSize lcl_getColumnsVisibleWithin( const Rectangle& _rArea, ColPos _nFirstVisibleColumn,
+ const TableControl_Impl& _rControl, bool _bAcceptPartialRow )
+ {
+ TableSize visibleColumns = 0;
+ TableColumnGeometry aColumn( _rControl, _rArea, _nFirstVisibleColumn );
+ while ( aColumn.isValid() )
+ {
+ if ( !_bAcceptPartialRow )
+ if ( aColumn.getRect().Right() > _rArea.Right() )
+ // this column is only partially visible, and this is not allowed
+ break;
+
+ aColumn.moveRight();
+ ++visibleColumns;
+ }
+ return visibleColumns;
+ }
+
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_ni_updateScrollbars()
+ {
+ TempHideCursor aHideCursor( *this );
+
+ // the width/height of a scrollbar, needed several times below
+ long nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( m_rAntiImpl.IsZoom() )
+ nScrollbarMetrics = (long)( nScrollbarMetrics * (double)m_rAntiImpl.GetZoom() );
+
+ // determine the playground for the data cells (excluding headers)
+ // TODO: what if the control is smaller than needed for the headers/scrollbars?
+ Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() );
+ aDataCellPlayground.Left() = m_nRowHeaderWidthPixel;
+ aDataCellPlayground.Top() = m_nColHeaderHeightPixel;
+ m_nRowCount = m_pModel->getRowCount();
+ m_nColumnCount = m_pModel->getColumnCount();
+
+ if(m_aAccColumnWidthsPixel.empty())
+ {
+ impl_ni_updateColumnWidths();
+ }
+
+ // do we need a vertical scrollbar?
+ bool bFirstRoundVScrollNeed = false;
+ if ( lcl_determineScrollbarNeed(
+ m_pModel->getVerticalScrollbarVisibility(aDataCellPlayground.GetHeight(), m_nRowHeightPixel*m_nRowCount),
+ lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ),
+ m_nRowCount ) )
+ {
+ aDataCellPlayground.Right() -= nScrollbarMetrics;
+ bFirstRoundVScrollNeed = true;
+ }
+ // do we need a horizontal scrollbar?
+ if ( lcl_determineScrollbarNeed(
+ m_pModel->getHorizontalScrollbarVisibility(aDataCellPlayground.GetWidth(), m_aAccColumnWidthsPixel[m_nColumnCount-1]),
+ lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false ),
+ m_nColumnCount ) )
+ {
+ aDataCellPlayground.Bottom() -= nScrollbarMetrics;
+
+ // now that we just found that we need a horizontal scrollbar,
+ // the need for a vertical one may have changed, since the horizontal
+ // SB might just occupy enough space so that not all rows do fit
+ // anymore
+ if ( !bFirstRoundVScrollNeed && lcl_determineScrollbarNeed(
+ m_pModel->getVerticalScrollbarVisibility(aDataCellPlayground.GetHeight(),m_nRowHeightPixel*m_nRowCount),
+ lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ),
+ m_nRowCount ) )
+ {
+ aDataCellPlayground.Right() -= nScrollbarMetrics;
+ }
+ }
+ // create or destroy the vertical scrollbar, as needed
+ lcl_updateScrollbar(
+ m_rAntiImpl,
+ m_pVScroll,
+ m_pModel->getVerticalScrollbarVisibility(aDataCellPlayground.GetHeight(),m_nRowHeightPixel*m_nRowCount),
+ lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ),
+ // visible units
+ m_nTopRow, // current position
+ 1, // line size
+ m_nRowCount, // range
+ false, // vertical
+ LINK( this, TableControl_Impl, OnScroll ) // scroll handler
+ );
+ // position it
+ if ( m_pVScroll )
+ {
+ Rectangle aScrollbarArea(
+ Point( aDataCellPlayground.Right() + 1, 0 ),
+ Size( nScrollbarMetrics, aDataCellPlayground.Bottom() + 1 )
+ );
+ m_pVScroll->SetPosSizePixel(
+ aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() );
+ }
+
+ // create or destroy the horizontal scrollbar, as needed
+ lcl_updateScrollbar(
+ m_rAntiImpl,
+ m_pHScroll,
+ m_pModel->getHorizontalScrollbarVisibility(aDataCellPlayground.GetWidth(), m_aAccColumnWidthsPixel[m_nColumnCount-1]),
+ lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false ),
+ // visible units
+ m_nLeftColumn, // current position
+ 1, // line size
+ m_nColumnCount, // range
+ true, // horizontal
+ LINK( this, TableControl_Impl, OnScroll ) // scroll handler
+ );
+ // position it
+ if ( m_pHScroll )
+ {
+ TableSize nVisibleUnits = lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false );
+ int nRange = m_nColumnCount;
+ if( m_nLeftColumn + nVisibleUnits == nRange-1)
+ {
+ if(m_aAccColumnWidthsPixel[nRange-2] - m_aAccColumnWidthsPixel[m_nLeftColumn] + m_aColumnWidthsPixel[nRange-1]>aDataCellPlayground.GetWidth())
+ {
+ m_pHScroll->SetVisibleSize( nVisibleUnits -1 );
+ m_pHScroll->SetPageSize(nVisibleUnits -1);
+ }
+ }
+ Rectangle aScrollbarArea(
+ Point( 0, aDataCellPlayground.Bottom() + 1 ),
+ Size( aDataCellPlayground.Right() + 1, nScrollbarMetrics )
+ );
+ m_pHScroll->SetPosSizePixel(
+ aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() );
+ }
+
+ // the corner window connecting the two scrollbars in the lower right corner
+ bool bHaveScrollCorner = NULL != m_pScrollCorner;
+ bool bNeedScrollCorner = ( NULL != m_pHScroll ) && ( NULL != m_pVScroll );
+ if ( bHaveScrollCorner && !bNeedScrollCorner )
+ {
+ DELETEZ( m_pScrollCorner );
+ }
+ else if ( !bHaveScrollCorner && bNeedScrollCorner )
+ {
+ m_pScrollCorner = new ScrollBarBox( &m_rAntiImpl );
+ m_pScrollCorner->SetSizePixel( Size( nScrollbarMetrics, nScrollbarMetrics ) );
+ m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) );
+ m_pScrollCorner->Show();
+ }
+ else if(bHaveScrollCorner && bNeedScrollCorner)
+ {
+ m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) );
+ m_pScrollCorner->Show();
+ }
+
+ // resize the data window
+ m_pDataWindow->SetSizePixel( Size(
+ aDataCellPlayground.GetWidth() + m_nRowHeaderWidthPixel,
+ aDataCellPlayground.GetHeight() + m_nColHeaderHeightPixel
+ ) );
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::onResize()
+ {
+ DBG_CHECK_ME();
+ if(m_nRowCount != 0)
+ {
+ if(m_nColumnCount != 0)
+ {
+ if(m_bResizingGrid)
+ impl_ni_updateColumnWidths();
+ invalidateRows();
+ m_bResizingGrid = true;
+ }
+ }
+ else
+ {
+ //In the case that column headers are defined but data hasn't yet been set,
+ //only column headers will be shown
+ if(m_pModel->hasColumnHeaders())
+ if(m_nColHeaderHeightPixel>1)
+ m_pDataWindow->SetSizePixel( m_rAntiImpl.GetOutputSizePixel());
+ if(m_nColumnCount != 0)
+ impl_ni_updateScrollbars();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::doPaintContent( const Rectangle& _rUpdateRect )
+ {
+ DBG_CHECK_ME();
+
+ if ( !getModel() )
+ return;
+ PTableRenderer pRenderer = getModel()->getRenderer();
+ DBG_ASSERT( !!pRenderer, "TableDataWindow::Paint: invalid renderer!" );
+ if ( !pRenderer )
+ return;
+
+ // our current style settings, to be passed to the renderer
+ const StyleSettings& rStyle = m_rAntiImpl.GetSettings().GetStyleSettings();
+ m_nRowCount = m_pModel->getRowCount();
+ TableSize nVisibleRows = impl_getVisibleRows(true);
+ TableSize nActualRows = m_nRowCount;
+ if(m_nRowCount>nVisibleRows)
+ nActualRows = nVisibleRows;
+ // the area occupied by all (at least partially) visible cells, including
+ // headers
+ Rectangle aAllCellsWithHeaders;
+ impl_getAllVisibleCellsArea( aAllCellsWithHeaders );
+
+ // ............................
+ // draw the header column area
+ if ( m_pModel->hasColumnHeaders() )
+ {
+ TableRowGeometry aHeaderRow( *this, Rectangle( Point( 0, 0 ),
+ aAllCellsWithHeaders.BottomRight() ), ROW_COL_HEADERS );
+ Rectangle aColRect(aHeaderRow.getRect());
+ //to avoid double lines when scrolling horizontally
+ if(m_nLeftColumn != 0)
+ --aColRect.Left();
+ pRenderer->PaintHeaderArea(
+ *m_pDataWindow, aColRect, true, false, rStyle
+ );
+ // Note that strictly, aHeaderRow.getRect() also contains the intersection between column
+ // and row header area. However, below we go to paint this intersection, again,
+ // so this hopefully doesn't hurt if we already paint it here.
+
+ for ( TableCellGeometry aCell( aHeaderRow, m_nLeftColumn );
+ aCell.isValid();
+ aCell.moveRight()
+ )
+ {
+ if ( _rUpdateRect.GetIntersection( aCell.getRect() ).IsEmpty() )
+ continue;
+
+ bool isActiveColumn = ( aCell.getColumn() == getCurColumn() );
+ bool isSelectedColumn = false;
+ pRenderer->PaintColumnHeader( aCell.getColumn(), isActiveColumn, isSelectedColumn,
+ *m_pDataWindow, aCell.getRect(), rStyle );
+ }
+ }
+ // the area occupied by the row header, if any
+ Rectangle aRowHeaderArea;
+ if ( m_pModel->hasRowHeaders() )
+ {
+ aRowHeaderArea = aAllCellsWithHeaders;
+ aRowHeaderArea.Right() = m_nRowHeaderWidthPixel - 1;
+ if(m_nTopRow+nActualRows>m_nRowCount)
+ aRowHeaderArea.Bottom() = m_nRowHeightPixel * (nActualRows -1)+ m_nColHeaderHeightPixel - 1;
+ else
+ aRowHeaderArea.Bottom() = m_nRowHeightPixel * nActualRows + m_nColHeaderHeightPixel - 1;
+ //to avoid double lines when scrolling vertically
+ if(m_nTopRow != 0)
+ --aRowHeaderArea.Top();
+ --aRowHeaderArea.Right();
+ pRenderer->PaintHeaderArea(*m_pDataWindow, aRowHeaderArea, false, true, rStyle);
+ // Note that strictly, aRowHeaderArea also contains the intersection between column
+ // and row header area. However, below we go to paint this intersection, again,
+ // so this hopefully doesn't hurt if we already paint it here.
+
+ if ( m_pModel->hasColumnHeaders() )
+ {
+ TableCellGeometry aIntersection( *this, Rectangle( Point( 0, 0 ),
+ aAllCellsWithHeaders.BottomRight() ), COL_ROW_HEADERS, ROW_COL_HEADERS );
+ Rectangle aInters(aIntersection.getRect());
+ //to avoid double line when scrolling vertically
+ if( m_nTopRow != 0 )
+ {
+ --aInters.Top();
+ --aInters.Bottom();
+ }
+ --aInters.Right();
+ pRenderer->PaintHeaderArea(
+ *m_pDataWindow, aInters, true, true, rStyle
+ );
+ }
+ }
+
+ // ............................
+ // draw the table content row by row
+
+ TableSize colCount = getModel()->getColumnCount();
+
+ // paint all rows
+ Rectangle aAllDataCellsArea;
+ impl_getAllVisibleDataCellArea( aAllDataCellsArea );
+ ::std::vector< std::vector< ::com::sun::star::uno::Any > >& aCellContent = m_pModel->getCellContent();
+ for ( TableRowGeometry aRowIterator( *this, aAllCellsWithHeaders, getTopRow() );
+ aRowIterator.isValid();
+ aRowIterator.moveDown() )
+ {
+ if ( _rUpdateRect.GetIntersection( aRowIterator.getRect() ).IsEmpty() )
+ continue;
+ bool isActiveRow = ( aRowIterator.getRow() == getCurRow() );
+ bool isSelectedRow = false;
+ if(!m_nRowSelected.empty())
+ {
+ for(std::vector<RowPos>::iterator itSel=m_nRowSelected.begin();
+ itSel!=m_nRowSelected.end();++itSel)
+ {
+ if(*itSel == aRowIterator.getRow())
+ isSelectedRow = true;
+ }
+ }
+ Rectangle aRect = aRowIterator.getRect().GetIntersection( aAllDataCellsArea );
+ //to avoid double lines
+ if( aRowIterator.getRow() != 0 )
+ --aRect.Top();
+ if(m_nLeftColumn != 0)
+ --aRect.Left();
+ else
+ {
+ if(m_pModel->hasRowHeaders())
+ --aRect.Left();
+ }
+ // give the redenderer a chance to prepare the row
+ pRenderer->PrepareRow( aRowIterator.getRow(), isActiveRow, isSelectedRow,
+ *m_pDataWindow, aRect, rStyle );
+
+ // paint the row header
+ if ( m_pModel->hasRowHeaders() )
+ {
+ Rectangle aCurrentRowHeader( aRowHeaderArea.GetIntersection( aRowIterator.getRect() ) );
+ rtl::OUString rowHeaderName = m_pModel->getRowHeaderName()[aRowIterator.getRow()];
+ pRenderer->PaintRowHeader( isActiveRow, isSelectedRow, *m_pDataWindow, aCurrentRowHeader,
+ rStyle, rowHeaderName );
+ }
+ if ( !colCount )
+ continue;
+ // paint all cells in this row
+ for ( TableCellGeometry aCell( aRowIterator, m_nLeftColumn );
+ aCell.isValid();
+ aCell.moveRight()
+ )
+ {
+ bool isSelectedColumn = false;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >xGraphic;
+ ::com::sun::star::uno::Any rCellData = aCellContent[aRowIterator.getRow()][aCell.getColumn()];
+ if(rCellData>>=xGraphic)
+ {
+ Image* pImage = new Image(xGraphic);
+ if(pImage!=NULL)
+ pRenderer->PaintCellImage( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow,
+ *m_pDataWindow, aCell.getRect(), rStyle, pImage );
+ }
+ else
+ {
+ ::rtl::OUString sContent = convertToString(rCellData);
+ pRenderer->PaintCellString( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow,
+ *m_pDataWindow, aCell.getRect(), rStyle, sContent );
+ }
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+ void TableControl_Impl::hideCursor()
+ {
+ DBG_CHECK_ME();
+
+ if ( ++m_nCursorHidden == 1 )
+ impl_ni_doSwitchCursor( false );
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::showCursor()
+ {
+ DBG_CHECK_ME();
+
+ DBG_ASSERT( m_nCursorHidden > 0, "TableControl_Impl::showCursor: cursor not hidden!" );
+ if ( --m_nCursorHidden == 0 )
+ impl_ni_doSwitchCursor( true );
+ }
+
+ //--------------------------------------------------------------------
+ bool TableControl_Impl::dispatchAction( TableControlAction _eAction )
+ {
+ DBG_CHECK_ME();
+
+ bool bSuccess = false;
+ Rectangle rCells;
+ switch ( _eAction )
+ {
+ case cursorDown:
+ if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ {
+ //if other rows already selected, deselect them
+ if(m_nRowSelected.size()>0)
+ {
+ for(std::vector<RowPos>::iterator it=m_nRowSelected.begin();
+ it!=m_nRowSelected.end();++it)
+ {
+ invalidateSelectedRegion(*it, *it, rCells);
+ }
+ m_nRowSelected.clear();
+ }
+ if(m_nCurRow < m_nRowCount-1)
+ {
+ ++m_nCurRow;
+ m_nRowSelected.push_back(m_nCurRow);
+ }
+ else
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ ensureVisible(m_nCurColumn,m_nCurRow,false);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ else
+ {
+ if ( m_nCurRow < m_nRowCount - 1 )
+ bSuccess = goTo( m_nCurColumn, m_nCurRow + 1 );
+ }
+ break;
+
+ case cursorUp:
+ if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ {
+ if(m_nRowSelected.size()>0)
+ {
+ for(std::vector<RowPos>::iterator it=m_nRowSelected.begin();
+ it!=m_nRowSelected.end();++it)
+ {
+ invalidateSelectedRegion(*it, *it, rCells);
+ }
+ m_nRowSelected.clear();
+ }
+ if(m_nCurRow>0)
+ {
+ --m_nCurRow;
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ else
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ ensureVisible(m_nCurColumn,m_nCurRow,false);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ else
+ {
+ if ( m_nCurRow > 0 )
+ bSuccess = goTo( m_nCurColumn, m_nCurRow - 1 );
+ }
+ break;
+ case cursorLeft:
+ if ( m_nCurColumn > 0 )
+ bSuccess = goTo( m_nCurColumn - 1, m_nCurRow );
+ else
+ if ( ( m_nCurColumn == 0) && ( m_nCurRow > 0 ) )
+ bSuccess = goTo( m_nColumnCount - 1, m_nCurRow - 1 );
+ break;
+
+ case cursorRight:
+ if ( m_nCurColumn < m_nColumnCount - 1 )
+ bSuccess = goTo( m_nCurColumn + 1, m_nCurRow );
+ else
+ if ( ( m_nCurColumn == m_nColumnCount - 1 ) && ( m_nCurRow < m_nRowCount - 1 ) )
+ bSuccess = goTo( 0, m_nCurRow + 1 );
+ break;
+
+ case cursorToLineStart:
+ bSuccess = goTo( 0, m_nCurRow );
+ break;
+
+ case cursorToLineEnd:
+ bSuccess = goTo( m_nColumnCount - 1, m_nCurRow );
+ break;
+
+ case cursorToFirstLine:
+ bSuccess = goTo( m_nCurColumn, 0 );
+ break;
+
+ case cursorToLastLine:
+ bSuccess = goTo( m_nCurColumn, m_nRowCount - 1 );
+ break;
+
+ case cursorPageUp:
+ {
+ RowPos nNewRow = ::std::max( (RowPos)0, m_nCurRow - impl_getVisibleRows( false ) );
+ bSuccess = goTo( m_nCurColumn, nNewRow );
+ }
+ break;
+
+ case cursorPageDown:
+ {
+ RowPos nNewRow = ::std::min( m_nRowCount - 1, m_nCurRow + impl_getVisibleRows( false ) );
+ bSuccess = goTo( m_nCurColumn, nNewRow );
+ }
+ break;
+
+ case cursorTopLeft:
+ bSuccess = goTo( 0, 0 );
+ break;
+
+ case cursorBottomRight:
+ bSuccess = goTo( m_nColumnCount - 1, m_nRowCount - 1 );
+ break;
+ case cursorSelectRow:
+ {
+ if(m_pSelEngine->GetSelectionMode() == NO_SELECTION)
+ return bSuccess = false;
+ //pos is the position of the current row in the vector of selected rows, if current row is selected
+ int pos = getRowSelectedNumber(m_nRowSelected, m_nCurRow);
+ //if current row is selected, it should be deselected, when ALT+SPACE are pressed
+ if(pos>-1)
+ {
+ m_nRowSelected.erase(m_nRowSelected.begin()+pos);
+ if(m_nRowSelected.empty() && m_nAnchor != -1)
+ m_nAnchor = -1;
+ }
+ //else select the row->put it in the vector
+ else
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ break;
+ case cursorSelectRowUp:
+ {
+ if(m_pSelEngine->GetSelectionMode() == NO_SELECTION)
+ return bSuccess = false;
+ else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ {
+ //if there are other selected rows, deselect them
+ return false;
+ }
+ else
+ {
+ //there are other selected rows
+ if(m_nRowSelected.size()>0)
+ {
+ //the anchor wasn't set -> a region is not selected, that's why clear all selection
+ //and select the current row
+ if(m_nAnchor==-1)
+ {
+ for(std::vector<RowPos>::iterator it=m_nRowSelected.begin();
+ it!=m_nRowSelected.end();++it)
+ {
+ invalidateSelectedRegion(*it, *it, rCells);
+ }
+ m_nRowSelected.clear();
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ else
+ {
+ //a region is already selected, prevRow is last selected row and the row above - nextRow - should be selected
+ int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow);
+ int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow-1);
+ if(prevRow>-1)
+ {
+ //if m_nCurRow isn't the upper one, can move up, otherwise not
+ if(m_nCurRow>0)
+ m_nCurRow--;
+ else
+ return bSuccess = true;
+ //if nextRow already selected, deselect it, otherwise select it
+ if(nextRow>-1 && m_nRowSelected[nextRow] == m_nCurRow)
+ {
+ m_nRowSelected.erase(m_nRowSelected.begin()+prevRow);
+ invalidateSelectedRegion(m_nCurRow+1, m_nCurRow+1, rCells);
+ }
+ else
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ }
+ else
+ {
+ if(m_nCurRow>0)
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ m_nCurRow--;
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells);
+ }
+ }
+ }
+ }
+ else
+ {
+ //if nothing is selected and the current row isn't the upper one
+ //select the current and one row above
+ //otherwise select only the upper row
+ if(m_nCurRow>0)
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ m_nCurRow--;
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells);
+ }
+ else
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ }
+ m_pSelEngine->SetAnchor(TRUE);
+ m_nAnchor = m_nCurRow;
+ ensureVisible(m_nCurColumn, m_nCurRow, false);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ }
+ break;
+ case cursorSelectRowDown:
+ {
+ if(m_pSelEngine->GetSelectionMode() == NO_SELECTION)
+ bSuccess = false;
+ else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ {
+ bSuccess = false;
+ }
+ else
+ {
+ if(m_nRowSelected.size()>0)
+ {
+ //the anchor wasn't set -> a region is not selected, that's why clear all selection
+ //and select the current row
+ if(m_nAnchor==-1)
+ {
+ for(std::vector<RowPos>::iterator it=m_nRowSelected.begin();
+ it!=m_nRowSelected.end();++it)
+ {
+ invalidateSelectedRegion(*it, *it, rCells);
+ }
+ m_nRowSelected.clear();
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ else
+ {
+ //a region is already selected, prevRow is last selected row and the row beneath - nextRow - should be selected
+ int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow);
+ int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow+1);
+ if(prevRow>-1)
+ {
+ //if m_nCurRow isn't the last one, can move down, otherwise not
+ if(m_nCurRow<m_nRowCount-1)
+ m_nCurRow++;
+ else
+ return bSuccess = true;
+ //if next row already selected, deselect it, otherwise select it
+ if(nextRow>-1 && m_nRowSelected[nextRow] == m_nCurRow)
+ {
+ m_nRowSelected.erase(m_nRowSelected.begin()+prevRow);
+ invalidateSelectedRegion(m_nCurRow-1, m_nCurRow-1, rCells);
+ }
+ else
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ }
+ else
+ {
+ if(m_nCurRow<m_nRowCount-1)
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ m_nCurRow++;
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells);
+ }
+ }
+ }
+ }
+ else
+ {
+ //there wasn't any selection, select current and row beneath, otherwise only row beneath
+ if(m_nCurRow<m_nRowCount-1)
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ m_nCurRow++;
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells);
+ }
+ else
+ {
+ m_nRowSelected.push_back(m_nCurRow);
+ invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ }
+ }
+ m_pSelEngine->SetAnchor(TRUE);
+ m_nAnchor = m_nCurRow;
+ ensureVisible(m_nCurColumn, m_nCurRow, false);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ }
+ break;
+ case cursorSelectRowAreaTop:
+ {
+ if(m_pSelEngine->GetSelectionMode() == NO_SELECTION)
+ bSuccess = false;
+ else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ bSuccess = false;
+ else
+ {
+ //select the region between the current and the upper row
+ RowPos iter = m_nCurRow;
+ invalidateSelectedRegion(m_nCurRow, 0, rCells);
+ //put the rows in vector
+ while(iter>=0)
+ {
+ if(!isRowSelected(m_nRowSelected, iter))
+ m_nRowSelected.push_back(iter);
+ --iter;
+ }
+ m_nCurRow = 0;
+ m_nAnchor = m_nCurRow;
+ m_pSelEngine->SetAnchor(TRUE);
+ ensureVisible(m_nCurColumn, 0, false);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ }
+ break;
+ case cursorSelectRowAreaBottom:
+ {
+ if(m_pSelEngine->GetSelectionMode() == NO_SELECTION)
+ return bSuccess = false;
+ else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ return bSuccess = false;
+ //select the region between the current and the last row
+ RowPos iter = m_nCurRow;
+ invalidateSelectedRegion(m_nCurRow, m_nRowCount-1, rCells);
+ //put the rows in the vector
+ while(iter<=m_nRowCount)
+ {
+ if(!isRowSelected(m_nRowSelected, iter))
+ m_nRowSelected.push_back(iter);
+ ++iter;
+ }
+ m_nCurRow = m_nRowCount-1;
+ m_nAnchor = m_nCurRow;
+ m_pSelEngine->SetAnchor(TRUE);
+ ensureVisible(m_nCurColumn, m_nRowCount-1, false);
+ m_rAntiImpl.selectionChanged(true);
+ bSuccess = true;
+ }
+ break;
+ default:
+ DBG_ERROR( "TableControl_Impl::dispatchAction: unsupported action!" );
+ }
+ return bSuccess;
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_ni_doSwitchCursor( bool _bShow )
+ {
+ PTableRenderer pRenderer = !!m_pModel ? m_pModel->getRenderer() : PTableRenderer();
+ if ( !!pRenderer )
+ {
+ Rectangle aCellRect;
+ impl_getCellRect( m_nCurColumn, m_nCurRow, aCellRect );
+ if(!m_pModel->hasRowHeaders() && m_nCurColumn == 0)
+ aCellRect.Left()++;
+ if ( _bShow )
+ pRenderer->ShowCellCursor( *m_pDataWindow, aCellRect);
+ else
+ pRenderer->HideCellCursor( *m_pDataWindow, aCellRect);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::impl_getCellRect( ColPos _nColumn, RowPos _nRow, Rectangle& _rCellRect ) const
+ {
+ DBG_CHECK_ME();
+
+ if ( !m_pModel
+ || ( COL_INVALID == _nColumn )
+ || ( ROW_INVALID == _nRow )
+ )
+ {
+ _rCellRect.SetEmpty();
+ return;
+ }
+
+ Rectangle aAllCells;
+ impl_getAllVisibleCellsArea( aAllCells );
+
+ TableCellGeometry aCell( *this, aAllCells, _nColumn, _nRow );
+ _rCellRect = aCell.getRect();
+ _rCellRect.Top()--;_rCellRect.Left()--;
+ }
+ //-------------------------------------------------------------------------------
+ RowPos TableControl_Impl::getCurrentRow(const Point& rPoint)
+ {
+ DBG_CHECK_ME();
+ Rectangle rCellRect;
+ RowPos newRowPos = -2;//-1 is HeaderRow
+ ColPos newColPos = 0;
+ for(int i=-1;i<m_nRowCount;i++)
+ {
+ for(int j=-1;j<m_nColumnCount;j++)
+ {
+ impl_getCellRect(j,i,rCellRect);
+ if((rPoint.X() >= rCellRect.Left() && rPoint.X() <= rCellRect.Right()) && rPoint.Y() >= rCellRect.Top() && rPoint.Y() <= rCellRect.Bottom())
+ {
+ newRowPos = i;
+ newColPos = j;
+ if(newColPos != -1)
+ m_nCurColumn = newColPos;
+ return newRowPos;
+ }
+ }
+ }
+ return newRowPos;
+ }
+ //-------------------------------------------------------------------------------
+ void TableControl_Impl::setCursorAtCurrentCell(const Point& rPoint)
+ {
+ DBG_CHECK_ME();
+ hideCursor();
+ Rectangle rCellRect;
+ RowPos newRowPos = -2;//-1 is HeaderRow
+ ColPos newColPos = 0;
+ for(int i=0;i<m_nRowCount;i++)
+ {
+ for(int j=-1;j<m_nColumnCount;j++)
+ {
+ impl_getCellRect(j,i,rCellRect);
+ if((rPoint.X() >= rCellRect.Left() && rPoint.X() <= rCellRect.Right()) && rPoint.Y() >= rCellRect.Top() && rPoint.Y() <= rCellRect.Bottom())
+ {
+ newRowPos = i;
+ m_nCurRow = newRowPos;
+ newColPos = j;
+ if(newColPos == -1)
+ m_nCurColumn = 0;
+ else
+ m_nCurColumn = newColPos;
+ }
+ }
+ }
+ showCursor();
+ }
+ //-------------------------------------------------------------------------------
+ void TableControl_Impl::invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect)
+ {
+ DBG_CHECK_ME();
+ Rectangle aAllCells;
+ //get the visible area of the table control and set the Left and right border of the region to be repainted
+ impl_getAllVisibleCellsArea( aAllCells );
+ _rCellRect.Left() = aAllCells.Left();
+ _rCellRect.Right() = aAllCells.Right();
+ Rectangle rCells;
+ //if only one row is selected
+ if(_nPrevRow == _nCurRow)
+ {
+ impl_getCellRect(m_nCurColumn,_nCurRow,rCells);
+ _rCellRect.Top()=--rCells.Top();
+ _rCellRect.Bottom()=rCells.Bottom();
+ }
+ //if the region is above the current row
+ else if(_nPrevRow < _nCurRow )
+ {
+ impl_getCellRect(m_nCurColumn,_nPrevRow,rCells);
+ _rCellRect.Top()= --rCells.Top();
+ impl_getCellRect(m_nCurColumn,_nCurRow,rCells);
+ _rCellRect.Bottom()=rCells.Bottom();
+ }
+ //if the region is beneath the current row
+ else
+ {
+ impl_getCellRect(m_nCurColumn,_nCurRow,rCells);
+ _rCellRect.Top()= --rCells.Top();
+ impl_getCellRect(m_nCurColumn,_nPrevRow,rCells);
+ _rCellRect.Bottom()=rCells.Bottom();
+ }
+ m_pDataWindow->Invalidate(_rCellRect);
+ }
+ //-------------------------------------------------------------------------------
+ //this method is to be called, when a new row is added
+ void TableControl_Impl::invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect)
+ {
+ if(m_nCurRow < 0)
+ m_nCurRow = 0;
+ if(m_nCursorHidden == 2)
+ --m_nCursorHidden;
+ impl_getAllVisibleCellsArea( _rCellRect );
+ TableRowGeometry _rRow( *this, _rCellRect, _nRowPos);
+ impl_ni_updateScrollbars();
+ m_pDataWindow->Invalidate(_rRow.getRect());
+ }
+ //-------------------------------------------------------------------------------
+ std::vector<RowPos>& TableControl_Impl::getSelectedRows()
+ {
+ return m_nRowSelected;
+ }
+ //--------------------------------------------------------------------
+ void TableControl_Impl::clearSelection()
+ {
+ m_nRowSelected.clear();
+ }
+ //--------------------------------------------------------------------
+ //-------------------------------------------------------------------------------
+ void TableControl_Impl::removeSelectedRow(RowPos _nRowPos)
+ {
+ int i =0;
+ //if the row is selected, remove it from the selection vector
+ if(isRowSelected(m_nRowSelected, _nRowPos))
+ {
+ if(m_nRowSelected.size()>1)
+ m_nRowSelected.erase(m_nRowSelected.begin()+_nRowPos);
+ else
+ m_nRowSelected.clear();
+ }
+ //after removing a row, row positions must be updated, so selected rows could stay selected
+ if(m_nRowSelected.size()>1)
+ {
+ for(std::vector<RowPos>::iterator it=m_nRowSelected.begin();it!=m_nRowSelected.end();++it)
+ {
+ if(*it > _nRowPos)
+ m_nRowSelected[i]=*it-1;
+ ++i;
+ }
+ }
+ if(_nRowPos == 0)
+ m_nCurRow = 0;
+ else
+ m_nCurRow = _nRowPos-1;
+ }
+ //------------------------------------------------------------------------------
+ void TableControl_Impl::invalidateRows()
+ {
+ impl_ni_updateScrollbars();
+ TableSize nVisibleRows = impl_getVisibleRows(true);
+ TableSize nVisibleCols = impl_getVisibleColumns(true);
+ if(m_nTopRow+nVisibleRows>m_nRowCount && m_nRowCount>=nVisibleRows)
+ m_nTopRow--;
+ else
+ m_nTopRow = 0;
+ if(m_nLeftColumn+nVisibleCols>m_nColumnCount && m_nColumnCount>=nVisibleCols)
+ m_nLeftColumn--;
+ else
+ m_nLeftColumn = 0;
+ m_pDataWindow->Invalidate();
+ }
+
+ //--------------------------------------------------------------------
+ TableSize TableControl_Impl::impl_getVisibleRows( bool _bAcceptPartialRow ) const
+ {
+ DBG_CHECK_ME();
+
+ DBG_ASSERT( m_pDataWindow, "TableControl_Impl::impl_getVisibleRows: no data window!" );
+
+ return lcl_getRowsFittingInto(
+ m_pDataWindow->GetOutputSizePixel().Height() - m_nColHeaderHeightPixel,
+ m_nRowHeightPixel,
+ _bAcceptPartialRow
+ );
+ }
+
+ //--------------------------------------------------------------------
+ TableSize TableControl_Impl::impl_getVisibleColumns( bool _bAcceptPartialRow ) const
+ {
+ DBG_CHECK_ME();
+
+ DBG_ASSERT( m_pDataWindow, "TableControl_Impl::impl_getVisibleColumns: no data window!" );
+
+ return lcl_getColumnsVisibleWithin(
+ Rectangle( Point( 0, 0 ), m_pDataWindow->GetOutputSizePixel() ),
+ m_nLeftColumn,
+ *this,
+ _bAcceptPartialRow
+ );
+ }
+
+ //--------------------------------------------------------------------
+ bool TableControl_Impl::goTo( ColPos _nColumn, RowPos _nRow )
+ {
+ DBG_CHECK_ME();
+
+ // TODO: give veto listeners a chance
+
+ if ( ( _nColumn < -1 ) || ( _nColumn >= m_nColumnCount )
+ || ( _nRow < -1 ) || ( _nRow >= m_nRowCount )
+ )
+ return false;
+
+ TempHideCursor aHideCursor( *this );
+ m_nCurColumn = _nColumn;
+ m_nCurRow = _nRow;
+
+ // ensure that the new cell is visible
+ ensureVisible( m_nCurColumn, m_nCurRow, false );
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility )
+ {
+ DBG_CHECK_ME();
+ DBG_ASSERT( ( _nColumn >= 0 ) && ( _nColumn < m_nColumnCount )
+ && ( _nRow >= 0 ) && ( _nRow < m_nRowCount ),
+ "TableControl_Impl::ensureVisible: invalid coordinates!" );
+
+ TempHideCursor aHideCursor( *this );
+
+ if ( _nColumn < m_nLeftColumn )
+ impl_ni_ScrollColumns( _nColumn - m_nLeftColumn );
+ else
+ {
+ TableSize nVisibleColumns = impl_getVisibleColumns( _bAcceptPartialVisibility );
+ if ( _nColumn > m_nLeftColumn + nVisibleColumns - 1 )
+ {
+ impl_ni_ScrollColumns( _nColumn - ( m_nLeftColumn + nVisibleColumns - 1 ) );
+ // TODO: since not all columns have the same width, this might in theory result
+ // in the column still not being visible.
+ }
+ }
+
+ if ( _nRow < m_nTopRow )
+ impl_ni_ScrollRows( _nRow - m_nTopRow );
+ else
+ {
+ TableSize nVisibleRows = impl_getVisibleRows( _bAcceptPartialVisibility );
+ if ( _nRow > m_nTopRow + nVisibleRows - 1 )
+ impl_ni_ScrollRows( _nRow - ( m_nTopRow + nVisibleRows - 1 ) );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ TableSize TableControl_Impl::impl_ni_ScrollRows( TableSize _nRowDelta )
+ {
+ // compute new top row
+ RowPos nNewTopRow =
+ ::std::max(
+ ::std::min( (RowPos)( m_nTopRow + _nRowDelta ), (RowPos)( m_nRowCount - 1 ) ),
+ (RowPos)0
+ );
+
+ RowPos nOldTopRow = m_nTopRow;
+ m_nTopRow = nNewTopRow;
+
+ // if updates are enabled currently, scroll the viewport
+ if ( m_rAntiImpl.IsUpdateMode() && ( m_nTopRow != nOldTopRow ) )
+ {
+ DBG_SUSPEND_INV( INV_SCROLL_POSITION );
+ TempHideCursor aHideCursor( *this );
+ // TODO: call a onStartScroll at our listener (or better an own onStartScroll,
+ // which hides the cursor and then calls the listener)
+ // Same for onEndScroll
+
+ // scroll the view port, if possible
+ long nPixelDelta = m_nRowHeightPixel * ( m_nTopRow - nOldTopRow );
+
+ Rectangle aDataArea( Point( 0, m_nColHeaderHeightPixel ), m_pDataWindow->GetOutputSizePixel() );
+
+ if ( m_pDataWindow->GetBackground().IsScrollable()
+ && abs( nPixelDelta ) < aDataArea.GetHeight()
+ )
+ {
+ m_pDataWindow->Scroll( 0, (long)-nPixelDelta, aDataArea, SCROLL_CLIP | SCROLL_UPDATE | SCROLL_CHILDREN);
+ }
+ else
+ m_pDataWindow->Invalidate( INVALIDATE_UPDATE );
+
+ // update the position at the vertical scrollbar
+ m_pVScroll->SetThumbPos( m_nTopRow );
+ }
+
+ return (TableSize)( m_nTopRow - nOldTopRow );
+ }
+
+ //--------------------------------------------------------------------
+ TableSize TableControl_Impl::impl_ni_ScrollColumns( TableSize _nColumnDelta )
+ {
+ // compute new left column
+ ColPos nNewLeftColumn =
+ ::std::max(
+ ::std::min( (ColPos)( m_nLeftColumn + _nColumnDelta ), (ColPos)( m_nColumnCount - 1 ) ),
+ (ColPos)0
+ );
+
+ ColPos nOldLeftColumn = m_nLeftColumn;
+ m_nLeftColumn = nNewLeftColumn;
+
+ // if updates are enabled currently, scroll the viewport
+ if ( m_rAntiImpl.IsUpdateMode() && ( m_nLeftColumn != nOldLeftColumn ) )
+ {
+ DBG_SUSPEND_INV( INV_SCROLL_POSITION );
+ TempHideCursor aHideCursor( *this );
+ // TODO: call a onStartScroll at our listener (or better an own onStartScroll,
+ // which hides the cursor and then calls the listener)
+ // Same for onEndScroll
+
+ // scroll the view port, if possible
+ Rectangle aDataArea( Point( m_nRowHeaderWidthPixel, 0 ), m_pDataWindow->GetOutputSizePixel() );
+
+ long nPixelDelta =
+ ( m_nLeftColumn > 0 ? m_aAccColumnWidthsPixel[ m_nLeftColumn - 1 ] : 0 )
+ - ( nOldLeftColumn > 0 ? m_aAccColumnWidthsPixel[ nOldLeftColumn - 1 ] : 0 );
+
+ if ( m_pDataWindow->GetBackground().IsScrollable()
+ && abs( nPixelDelta ) < aDataArea.GetWidth()
+ )
+ {
+ m_pDataWindow->Scroll( (long)-nPixelDelta, 0, aDataArea, SCROLL_CLIP | SCROLL_UPDATE );
+ }
+ else
+ m_pDataWindow->Invalidate( INVALIDATE_UPDATE );
+
+ // update the position at the horizontal scrollbar
+ m_pHScroll->SetThumbPos( m_nLeftColumn );
+ }
+
+ return (TableSize)( m_nLeftColumn - nOldLeftColumn );
+ }
+ //-------------------------------------------------------------------------------
+ SelectionEngine* TableControl_Impl::getSelEngine()
+ {
+ return m_pSelEngine;
+ }
+ //-------------------------------------------------------------------------------
+ TableDataWindow* TableControl_Impl::getDataWindow()
+ {
+ return m_pDataWindow;
+ }
+ //-------------------------------------------------------------------------------
+ ScrollBar* TableControl_Impl::getHorzScrollbar()
+ {
+ return m_pHScroll;
+ }
+ //-------------------------------------------------------------------------------
+ ScrollBar* TableControl_Impl::getVertScrollbar()
+ {
+ return m_pVScroll;
+ }
+ //-------------------------------------------------------------------------------
+ BOOL TableControl_Impl::isRowSelected(const ::std::vector<RowPos>& selectedRows, RowPos current)
+ {
+ return ::std::find(selectedRows.begin(),selectedRows.end(),current) != selectedRows.end();
+ }
+ //-------------------------------------------------------------------------------
+ bool TableControl_Impl::isRowSelected(RowPos current)
+ {
+ return ::std::find(m_nRowSelected.begin(),m_nRowSelected.end(),current) != m_nRowSelected.end();
+ }
+ //-------------------------------------------------------------------------------
+ int TableControl_Impl::getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current)
+ {
+ std::vector<RowPos>::const_iterator it = ::std::find(selectedRows.begin(),selectedRows.end(),current);
+ if ( it != selectedRows.end() )
+ {
+ return it - selectedRows.begin();
+ }
+ return -1;
+ }
+ //-------------------------------------------------------------------------------
+ bool TableControl_Impl::isTooltipActive()
+ {
+ return m_rAntiImpl.isTooltip();
+ }
+ //-------------------------------------------------------------------------------
+ ::rtl::OUString& TableControl_Impl::setTooltip(const Point& rPoint )
+ {
+ ::rtl::OUString aTooltipText;
+ RowPos current = getCurrentRow(rPoint);
+ com::sun::star::uno::Sequence< sal_Int32 > cols = m_rAntiImpl.getColumnsForTooltip();
+ com::sun::star::uno::Sequence< ::rtl::OUString > text = m_rAntiImpl.getTextForTooltip();
+ if(text.getLength()==0 && cols.getLength()==0)
+ {
+ ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][m_nCurColumn];
+ aTooltipText = convertToString(content);
+ }
+ else if(text.getLength() == 0)
+ {
+ for(int i=0; i<cols.getLength(); i++)
+ {
+ if(i==0)
+ {
+ ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]];
+ aTooltipText = convertToString(content);
+ }
+ else
+ {
+ aTooltipText+= ::rtl::OUString::createFromAscii("\n");
+ ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]];
+ aTooltipText += convertToString(content);
+ }
+ }
+ }
+ else if(cols.getLength() == 0)
+ {
+ for(int i=0; i<text.getLength(); i++)
+ {
+ if(i==0)
+ aTooltipText = text[i];
+ else
+ {
+ aTooltipText+= ::rtl::OUString::createFromAscii("\n");
+ aTooltipText+= text[i];
+ }
+ }
+ }
+ else
+ {
+ int nCols = cols.getLength();
+ int mText = text.getLength();
+ if(nCols < mText )
+ cols.realloc(mText);
+ else if(mText < nCols)
+ text.realloc(nCols);
+ for(int i=0; i<cols.getLength(); i++)
+ {
+ if(i==0)
+ {
+ ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]];
+ aTooltipText = text[i] + convertToString(content);
+ }
+ else
+ {
+ aTooltipText+= ::rtl::OUString::createFromAscii("\n");
+ aTooltipText+= text[i];
+ if(nCols > i)
+ {
+ ::com::sun::star::uno::Any content = m_pModel->getCellContent()[current][cols[i]];
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >xGraphic;
+ aTooltipText += convertToString(content);
+ }
+ }
+ }
+ }
+ return m_aTooltipText = aTooltipText;
+ }
+ //--------------------------------------------------------------------
+ void TableControl_Impl::resizeColumn(const Point& rPoint)
+ {
+ Pointer aNewPointer(POINTER_ARROW);
+ int headerRowWidth = 0;
+ if(m_pModel->hasRowHeaders())
+ headerRowWidth = m_rAntiImpl.LogicToPixel( Size(m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width();
+ int resizingColumn=m_nCurColumn-m_nLeftColumn;
+ PColumnModel pColumn = m_pModel->getColumnModel(m_nCurColumn);
+ impl_ni_getAccVisibleColWidths();
+ int newColWidth = m_aColumnWidthsPixel[m_nCurColumn];
+ //subtract 1 from m_aAccColumnWidthPixel because right border should be part of the current cell
+ if(m_aVisibleColumnWidthsPixel[resizingColumn]-1 == rPoint.X() && pColumn->isResizable())
+ aNewPointer = Pointer( POINTER_HSPLIT );
+ //MouseButton was pressed but not yet released, mouse is moving
+ if(m_bResizing)
+ {
+ if(rPoint.X() > m_pDataWindow->GetOutputSizePixel().Width() || rPoint.X() < m_aVisibleColumnWidthsPixel[resizingColumn]-newColWidth)
+ aNewPointer = Pointer( POINTER_NOTALLOWED);
+ else
+ aNewPointer = Pointer( POINTER_HSPLIT );
+ m_pDataWindow->HideTracking();
+ int lineHeight = 0;
+ if(m_pModel->hasColumnHeaders())
+ lineHeight+= m_nColHeaderHeightPixel;
+ lineHeight+=m_nRowHeightPixel*m_nRowCount;
+ int gridHeight = m_pDataWindow->GetOutputSizePixel().Height();
+ if(lineHeight >= gridHeight)
+ lineHeight = gridHeight;
+ m_pDataWindow->ShowTracking(Rectangle(Point(rPoint.X(),0), Size(1, lineHeight )),
+ SHOWTRACK_SPLIT | SHOWTRACK_WINDOW);
+ }
+ m_pDataWindow->SetPointer(aNewPointer);
+ }
+ //--------------------------------------------------------------------
+ bool TableControl_Impl::startResizeColumn(const Point& rPoint)
+ {
+ m_bResizingGrid = false;
+ m_nResizingColumn = m_nCurColumn;
+ PColumnModel pColumn = m_pModel->getColumnModel(m_nResizingColumn);
+ if(m_aVisibleColumnWidthsPixel[m_nResizingColumn-m_nLeftColumn]-1 == rPoint.X() && pColumn->isResizable())
+ {
+ m_pDataWindow->CaptureMouse();
+ m_bResizing = true;
+ }
+ return m_bResizing;
+ }
+ //--------------------------------------------------------------------
+ bool TableControl_Impl::endResizeColumn(const Point& rPoint)
+ {
+ if(m_bResizing)
+ {
+ m_pDataWindow->HideTracking();
+ PColumnModel pColumn = m_pModel->getColumnModel(m_nResizingColumn);
+ int maxWidth = m_rAntiImpl.LogicToPixel( Size( pColumn->getMaxWidth(), 0 ), MAP_APPFONT ).Width();
+ int minWidth = m_rAntiImpl.LogicToPixel( Size( pColumn->getMinWidth(), 0 ), MAP_APPFONT ).Width();
+ int resizeCol = m_nResizingColumn-m_nLeftColumn;
+ //new position of mouse
+ int actX = rPoint.X();
+ //old position of right border
+ int oldX = m_aVisibleColumnWidthsPixel[resizeCol];
+ //position of left border if cursor in the first cell
+ int leftX = 0;
+ if(m_nResizingColumn > m_nLeftColumn)
+ leftX = m_aVisibleColumnWidthsPixel[resizeCol-1];
+ else if(m_nResizingColumn == m_nLeftColumn && m_pModel->hasRowHeaders())
+ leftX = m_rAntiImpl.LogicToPixel( Size( m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width();
+ int actWidth = actX - leftX;
+ int newActWidth = 0;
+ //minimize the column width
+ if(oldX > actX && actX >= leftX)
+ {
+ if(minWidth < actWidth)
+ {
+ newActWidth = m_rAntiImpl.PixelToLogic( Size( actWidth, 0 ), MAP_APPFONT ).Width();
+ pColumn->setPreferredWidth(newActWidth);
+ }
+ else
+ pColumn->setPreferredWidth(pColumn->getMinWidth());
+ if(m_nLeftColumn != 0)
+ impl_updateLeftColumn();
+ }
+ else if(oldX < actX)
+ {
+ if(actWidth < maxWidth)
+ {
+ newActWidth = m_rAntiImpl.PixelToLogic( Size( actWidth, 0 ), MAP_APPFONT ).Width();
+ pColumn->setPreferredWidth(newActWidth);
+ }
+ else
+ pColumn->setPreferredWidth(pColumn->getMaxWidth());
+ }
+ m_nCurColumn = m_nResizingColumn;
+ impl_ni_updateColumnWidths();
+ impl_ni_updateScrollbars();
+ m_pDataWindow->Invalidate(INVALIDATE_UPDATE);
+ m_pDataWindow->SetPointer(Pointer());
+ m_bResizing = false;
+ m_bResizingGrid = true;
+ }
+ m_pDataWindow->ReleaseMouse();
+ return m_bResizing;
+ }
+ //-------------------------------------------------------------------------------
+ void TableControl_Impl::impl_ni_getAccVisibleColWidths()
+ {
+ TableSize nVisCols = impl_getVisibleColumns(true);
+ int widthsPixel = 0;
+ m_aVisibleColumnWidthsPixel.resize(0);
+ m_aVisibleColumnWidthsPixel.reserve(nVisCols);
+ int headerRowWidth = 0;
+ if(m_pModel->hasRowHeaders())
+ {
+ headerRowWidth = m_rAntiImpl.LogicToPixel( Size(m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width();
+ widthsPixel+=headerRowWidth;
+ }
+ int col = m_nLeftColumn;
+ while(nVisCols)
+ {
+ m_aVisibleColumnWidthsPixel.push_back(widthsPixel+=m_aColumnWidthsPixel[col]);
+ col++;
+ nVisCols--;
+ }
+ }
+ //-------------------------------------------------------------------------------
+ void TableControl_Impl::impl_updateLeftColumn()
+ {
+ int nVisCols = m_aVisibleColumnWidthsPixel.size();
+ int headerRowWidth = 0;
+ //sum of currently visible columns
+ int widthsPixel = 0;
+ //header pixel should be added, because header doesn't vanish when scrolling
+ if(m_pModel->hasRowHeaders())
+ {
+ headerRowWidth = m_rAntiImpl.LogicToPixel( Size(m_pModel->getRowHeaderWidth(), 0 ), MAP_APPFONT ).Width();
+ widthsPixel+=headerRowWidth;
+ }
+ int col = m_nLeftColumn;
+ //add column width of the neighbour of the left column
+ widthsPixel+=m_aColumnWidthsPixel[col-1];
+ //compute the sum of the new column widths
+ while(nVisCols)
+ {
+ PColumnModel pColumn = m_pModel->getColumnModel(col);
+ int colWidth = pColumn->getWidth();
+ int colPrefWidth = pColumn->getPreferredWidth();
+ if(colPrefWidth!=0)
+ colWidth = colPrefWidth;
+ widthsPixel += m_rAntiImpl.LogicToPixel( Size( colWidth, 0 ), MAP_APPFONT ).Width();
+ col++;
+ nVisCols--;
+ }
+ //when the sum of all visible columns and the next to the left column is smaller than
+ //window width, then update m_nLeftColumn
+ if(widthsPixel<m_pDataWindow->GetOutputSizePixel().Width())
+ m_nLeftColumn--;
+ }
+ //--------------------------------------------------------------------
+ rtl::OUString TableControl_Impl::convertToString(const ::com::sun::star::uno::Any& value)
+ {
+ sal_Int32 nInt = 0;
+ sal_Bool bBool = false;
+ double fDouble = 0;
+ ::rtl::OUString sNewString;
+ ::rtl::OUString sConvertString;
+ if(value >>= sConvertString)
+ sNewString = sConvertString;
+ else if(value >>= nInt)
+ sNewString = sConvertString.valueOf(nInt);
+ else if(value >>= bBool)
+ sNewString = sConvertString.valueOf(bBool);
+ else if(value >>= fDouble)
+ sNewString = sConvertString.valueOf(fDouble);
+ return sNewString;
+ }
+ Rectangle TableControl_Impl::calcHeaderRect(bool bColHeader)
+ {
+ Rectangle aRectTable, aRectTableWithHeaders;
+ impl_getAllVisibleDataCellArea(aRectTable);
+ impl_getAllVisibleCellsArea(aRectTableWithHeaders);
+ Size aSizeTable(aRectTable.GetSize());
+ Size aSizeTableWithHeaders(aRectTableWithHeaders.GetSize());
+ if(bColHeader)
+ return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width()-aSizeTable.Width(), aSizeTableWithHeaders.Height()));
+ else
+ return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width(), aSizeTableWithHeaders.Height()-aSizeTable.Height()));
+ }
+ Rectangle TableControl_Impl::calcTableRect()
+ {
+ Rectangle aRect;
+ impl_getAllVisibleDataCellArea(aRect);
+ return aRect;
+ }
+
+ //--------------------------------------------------------------------
+ IMPL_LINK( TableControl_Impl, OnScroll, ScrollBar*, _pScrollbar )
+ {
+ DBG_ASSERT( ( _pScrollbar == m_pVScroll ) || ( _pScrollbar == m_pHScroll ),
+ "TableControl_Impl::OnScroll: where did this come from?" );
+
+ if ( _pScrollbar == m_pVScroll )
+ impl_ni_ScrollRows( _pScrollbar->GetDelta() );
+ else
+ impl_ni_ScrollColumns( _pScrollbar->GetDelta() );
+
+ return 0L;
+ }
+ //---------------------------------------------------------------------------------------
+ TableFunctionSet::TableFunctionSet(TableControl_Impl* _pTableControl)
+ :m_pTableControl( _pTableControl)
+ ,m_nCurrentRow (-2)
+ {
+ }
+ //-------------------------------------------------------------------------------
+ TableFunctionSet::~TableFunctionSet()
+ {
+ }
+ //-------------------------------------------------------------------------------
+ void TableFunctionSet::BeginDrag()
+ {
+ }
+ //-------------------------------------------------------------------------------
+ void TableFunctionSet::CreateAnchor()
+ {
+ m_pTableControl->m_nAnchor = m_pTableControl->m_nCurRow;
+ }
+ //-------------------------------------------------------------------------------
+ void TableFunctionSet::DestroyAnchor()
+ {
+ m_pTableControl->m_nAnchor = -1;
+ }
+ //-------------------------------------------------------------------------------
+ BOOL TableFunctionSet::SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor)
+ {
+ BOOL bHandled = FALSE;
+ Rectangle rCells;
+ //curRow is the row where the mouse click happened, m_nCurRow is the last selected row, before the mouse click
+ RowPos curRow = m_pTableControl->getCurrentRow(rPoint);
+ if(curRow == -2)
+ return FALSE;
+ if( bDontSelectAtCursor )
+ {
+ if(m_pTableControl->m_nRowSelected.size()>1)
+ m_pTableControl->m_pSelEngine->AddAlways(TRUE);
+ bHandled = TRUE;
+ }
+ else if(m_pTableControl->m_nAnchor == m_pTableControl->m_nCurRow)
+ {
+ //selecting region,
+ int diff = m_pTableControl->m_nCurRow - curRow;
+ //selected region lies above the last selection
+ if( diff >= 0)
+ {
+ //put selected rows in vector
+ while(m_pTableControl->m_nAnchor>=curRow)
+ {
+ bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, m_pTableControl->m_nAnchor);
+ //if row isn't selected, put it in vector, otherwise don't put it there, because it will be twice there
+ if(!isAlreadySelected)
+ m_pTableControl->m_nRowSelected.push_back(m_pTableControl->m_nAnchor);
+ m_pTableControl->m_nAnchor--;
+ diff--;
+ }
+ m_pTableControl->m_nAnchor++;
+ }
+ //selected region lies beneath the last selected row
+ else
+ {
+ while(m_pTableControl->m_nAnchor<=curRow)
+ {
+ bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, m_pTableControl->m_nAnchor);
+ if(!isAlreadySelected)
+ m_pTableControl->m_nRowSelected.push_back(m_pTableControl->m_nAnchor);
+ m_pTableControl->m_nAnchor++;
+ diff++;
+ }
+ m_pTableControl->m_nAnchor--;
+ }
+ m_pTableControl->invalidateSelectedRegion(m_pTableControl->m_nCurRow, curRow, rCells);
+ bHandled = TRUE;
+ }
+ //no region selected
+ else
+ {
+ if(m_pTableControl->m_nRowSelected.empty())
+ m_pTableControl->m_nRowSelected.push_back(curRow);
+ else
+ {
+ if(m_pTableControl->m_pSelEngine->GetSelectionMode()==SINGLE_SELECTION)
+ {
+ DeselectAll();
+ m_pTableControl->m_nRowSelected.push_back(curRow);
+ }
+ else
+ {
+ bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, curRow);
+ if(!isAlreadySelected)
+ m_pTableControl->m_nRowSelected.push_back(curRow);
+ }
+ }
+ if(m_pTableControl->m_nRowSelected.size()>1 && m_pTableControl->m_pSelEngine->GetSelectionMode()!=SINGLE_SELECTION)
+ m_pTableControl->m_pSelEngine->AddAlways(TRUE);
+ m_pTableControl->invalidateSelectedRegion(curRow, curRow, rCells);
+ bHandled = TRUE;
+ }
+ m_pTableControl->m_nCurRow = curRow;
+ m_pTableControl->ensureVisible(m_pTableControl->m_nCurColumn,m_pTableControl->m_nCurRow,false);
+ return bHandled;
+ }
+ //-------------------------------------------------------------------------------
+ BOOL TableFunctionSet::IsSelectionAtPoint( const Point& rPoint )
+ {
+ m_pTableControl->m_pSelEngine->AddAlways(FALSE);
+ if(m_pTableControl->m_nRowSelected.empty())
+ return FALSE;
+ else
+ {
+ RowPos curRow = m_pTableControl->getCurrentRow(rPoint);
+ m_pTableControl->m_nAnchor = -1;
+ bool selected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, curRow);
+ m_nCurrentRow = curRow;
+ return selected;
+ }
+ }
+ //-------------------------------------------------------------------------------
+ void TableFunctionSet::DeselectAtPoint( const Point& rPoint )
+ {
+ (void)rPoint;
+ long pos = 0;
+ long i = 0;
+ Rectangle rCells;
+ for(std::vector<RowPos>::iterator it=m_pTableControl->m_nRowSelected.begin();
+ it!=m_pTableControl->m_nRowSelected.end();++it)
+ {
+ if(*it == m_nCurrentRow)
+ {
+ pos = i;
+ m_pTableControl->invalidateSelectedRegion(*it, *it, rCells);
+ }
+ ++i;
+ }
+ m_pTableControl->m_nRowSelected.erase(m_pTableControl->m_nRowSelected.begin()+pos);
+ }
+ //-------------------------------------------------------------------------------
+ void TableFunctionSet::DeselectAll()
+ {
+ if(!m_pTableControl->m_nRowSelected.empty())
+ {
+ Rectangle rCells;
+ for(std::vector<RowPos>::iterator it=m_pTableControl->m_nRowSelected.begin();
+ it!=m_pTableControl->m_nRowSelected.end();++it)
+ {
+ m_pTableControl->invalidateSelectedRegion(*it, *it, rCells);
+ }
+ m_pTableControl->m_nRowSelected.clear();
+ }
+ }
+
+//........................................................................
+} } // namespace svt::table
+//........................................................................
diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx
new file mode 100644
index 000000000000..053766d92841
--- /dev/null
+++ b/svtools/source/table/tablecontrol_impl.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 SVTOOLS_TABLECONTROL_IMPL_HXX
+#define SVTOOLS_TABLECONTROL_IMPL_HXX
+
+#ifndef SVTOOLS_INC_TABLE_TABLEMODEL_HXX
+#include <svtools/table/tablemodel.hxx>
+#endif
+
+#ifndef SVTOOLS_INC_TABLE_ABSTRACTTABLECONTROL_HXX
+#include <svtools/table/abstracttablecontrol.hxx>
+#endif
+
+#include <svtools/table/tablemodel.hxx>
+#include <vector>
+#include <vcl/seleng.hxx>
+
+
+class ScrollBar;
+class ScrollBarBox;
+
+//........................................................................
+namespace svt { namespace table
+{
+//........................................................................
+
+ typedef ::std::vector< long > ArrayOfLong;
+
+ class TableControl;
+ class TableDataWindow;
+ class TableFunctionSet;
+
+ //====================================================================
+ //= TableControl_Impl
+ //====================================================================
+ class TableControl_Impl : public IAbstractTableControl
+ {
+ friend class TableGeometry;
+ friend class TableRowGeometry;
+ friend class TableColumnGeometry;
+ friend class SuspendInvariants;
+ friend class TableFunctionSet;
+ private:
+ /// the control whose impl-instance we implemnt
+ TableControl& m_rAntiImpl;
+ /// the model of the table control
+ PTableModel m_pModel;
+ /// the input handler to use, usually the input handler as provided by ->m_pModel
+ PTableInputHandler m_pInputHandler;
+ /// the widths of the single columns, measured in pixel
+ ArrayOfLong m_aColumnWidthsPixel;
+ /** the accumulated widths of the single columns, i.e. their exclusive right borders,
+ <strong<not</strong> counting the space for a possible row header column
+ */
+ ArrayOfLong m_aAccColumnWidthsPixel;
+
+ ArrayOfLong m_aVisibleColumnWidthsPixel;
+ /// the height of a single row in the table, measured in pixels
+ long m_nRowHeightPixel;
+ /// the height of the column header row in the table, measured in pixels
+ long m_nColHeaderHeightPixel;
+ /// the width of the row header column in the table, measured in pixels
+ long m_nRowHeaderWidthPixel;
+
+ /// the number of columns in the table control. Cached model value.
+ TableSize m_nColumnCount;
+ /// the number of rows in the table control. Cached model value.
+ TableSize m_nRowCount;
+
+ ColPos m_nCurColumn;
+ RowPos m_nCurRow;
+ ColPos m_nLeftColumn;
+ RowPos m_nTopRow;
+
+ sal_Int32 m_nCursorHidden;
+
+ /** the window to contain all data content, including header bars
+
+ The window's upper left corner is at position (0,0), relative to the
+ table control, which is the direct parent of the data window.
+ */
+ TableDataWindow* m_pDataWindow;
+ /// the vertical scrollbar, if any
+ ScrollBar* m_pVScroll;
+ /// the horizontal scrollbar, if any
+ ScrollBar* m_pHScroll;
+ ScrollBarBox* m_pScrollCorner;
+ //selection engine - for determining selection range, e.g. single, multiple
+ SelectionEngine* m_pSelEngine;
+ //vector which contains the selected rows
+ std::vector<RowPos> m_nRowSelected;
+ //part of selection engine
+ TableFunctionSet* m_pTableFunctionSet;
+ //part of selection engine
+ RowPos m_nAnchor;
+ bool m_bResizing;
+ ColPos m_nResizingColumn;
+ bool m_bResizingGrid;
+ rtl::OUString m_aTooltipText;
+
+#if DBG_UTIL
+ #define INV_SCROLL_POSITION 1
+ /** represents a bitmask of invariants to check
+
+ Actually, impl_checkInvariants checks more invariants than denoted in this
+ bit mask, but only those present here can be disabled temporarily.
+ */
+ sal_Int32 m_nRequiredInvariants;
+#endif
+
+ public:
+
+
+ PTableModel getModel() const;
+ void setModel( PTableModel _pModel );
+
+ inline const PTableInputHandler& getInputHandler() const { return m_pInputHandler; }
+
+ inline ColPos getCurColumn() const { return m_nCurColumn; }
+ inline RowPos getCurRow() const { return m_nCurRow; }
+ inline void setCurRow(RowPos curRow){ m_nCurRow = curRow; }
+ inline RowPos getTopRow() const { return m_nTopRow; }
+ inline long getRowCount() const { return m_nRowCount; }
+ inline long getColumnCount() const { return m_nColumnCount; }
+
+ inline long getColHeaderHightPixel() const { return m_nColHeaderHeightPixel; }
+
+ inline const TableControl& getAntiImpl() const { return m_rAntiImpl; }
+ inline TableControl& getAntiImpl() { return m_rAntiImpl; }
+
+ public:
+ TableControl_Impl( TableControl& _rAntiImpl );
+ ~TableControl_Impl();
+
+#if DBG_UTIL
+ const sal_Char* impl_checkInvariants() const;
+#endif
+ /** to be called when the anti-impl instance has been resized
+ */
+ void onResize();
+
+ /** paints the table control content which intersects with the given rectangle
+ */
+ void doPaintContent( const Rectangle& _rUpdateRect );
+
+ /** moves the cursor to the cell with the given coordinates
+
+ To ease the caller's code, the coordinates must not necessarily denote a
+ valid position. If they don't, <FALSE/> will be returned.
+ */
+ bool goTo( ColPos _nColumn, RowPos _nRow );
+
+ /** ensures that the given coordinate is visible
+ @param _nColumn
+ the column position which should be visible. Must be non-negative, and smaller
+ than the column count.
+ @param _nRow
+ the row position which should be visibleMust be non-negative, and smaller
+ than the row count.
+ @param _bAcceptPartialVisibility
+ <TRUE/> if it's okay that the given cooordinate is only partially visible
+ */
+ void ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility );
+ /** returns the row, which contains the input point*/
+ virtual RowPos getCurrentRow (const Point& rPoint);
+
+ void setCursorAtCurrentCell(const Point& rPoint);
+ /** checks whether the vector with the selected rows contains the current row*/
+ BOOL isRowSelected(const ::std::vector<RowPos>& selectedRows, RowPos current);
+
+ bool isRowSelected(RowPos current);
+ /** returns the position of the current row in the selection vector */
+ int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current);
+ /** _rCellRect contains the region, which should be invalidate after some action e.g. selecting row*/
+ void invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect );
+ /** to be called when a new row is added to the control*/
+ void invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect );
+ /** returns the vector, which contains the selected rows*/
+ std::vector<RowPos>& getSelectedRows();
+ /** updates the vector, which contains the selected rows after removing the row nRowPos*/
+ void removeSelectedRow(RowPos _nRowPos);
+ void invalidateRows();
+ void clearSelection();
+ // IAbstractTableControl
+ virtual void hideCursor();
+ virtual void showCursor();
+ virtual bool dispatchAction( TableControlAction _eAction );
+ virtual SelectionEngine* getSelEngine();
+ virtual bool isTooltipActive();
+ virtual rtl::OUString& setTooltip(const Point& rPoint );
+ virtual void resizeColumn(const Point& rPoint);
+ virtual bool startResizeColumn(const Point& rPoint);
+ virtual bool endResizeColumn(const Point& rPoint);
+
+ TableDataWindow* getDataWindow();
+ ScrollBar* getHorzScrollbar();
+ ScrollBar* getVertScrollbar();
+
+ ::rtl::OUString convertToString(const ::com::sun::star::uno::Any& _value);
+ Rectangle calcHeaderRect(bool bColHeader);
+ Rectangle calcTableRect();
+ private:
+ /** toggles the cursor visibility
+
+ The method is not bound to the classes public invariants, as it's used in
+ situations where the they must not necessarily be fullfilled.
+ */
+ void impl_ni_doSwitchCursor( bool _bOn );
+
+ /** returns the number of visible rows.
+
+ @param _bAcceptPartialRow
+ specifies whether a possible only partially visible last row is
+ counted, too.
+ */
+ TableSize impl_getVisibleRows( bool _bAcceptPartialRow ) const;
+
+ /** returns the number of visible columns
+
+ The value may change with different horizontal scroll positions, as
+ different columns have different widths. For instance, if your control is
+ 100 pixels wide, and has three columns of width 50, 50, 100, respectively,
+ then this method will return either "2" or "1", depending on which column
+ is the first visible one.
+
+ @param _bAcceptPartialRow
+ specifies whether a possible only partially visible last row is
+ counted, too.
+ */
+ TableSize impl_getVisibleColumns( bool _bAcceptPartialRow ) const;
+
+ /** determines the rectangle occupied by the given cell
+ */
+ void impl_getCellRect( ColPos _nColumn, RowPos _nRow, Rectangle& _rCellRect ) const;
+
+ /** updates all cached model values
+
+ The method is not bound to the classes public invariants, as it's used in
+ situations where the they must not necessarily be fullfilled.
+ */
+ void impl_ni_updateCachedModelValues();
+
+ /** updates ->m_aColumnWidthsPixel with the current pixel widths of all model columns
+
+ The method takes into account the current zoom factor and map mode of the table
+ control, plus any possible COLWIDTH_FIT_TO_VIEW widths in the model columns.
+
+ The method is not bound to the classes public invariants, as it's used in
+ situations where the they must not necessarily be fullfilled.
+ */
+ void impl_ni_updateColumnWidths();
+
+ /** updates the scrollbars of the control
+
+ The method is not bound to the classes public invariants, as it's used in
+ situations where the they must not necessarily be fullfilled.
+
+ This includes both the existence of the scrollbars, and their
+ state.
+ */
+ void impl_ni_updateScrollbars();
+
+ /** scrolls the view by the given number of rows
+
+ The method is not bound to the classes public invariants, as it's used in
+ situations where the they must not necessarily be fullfilled.
+
+ @return
+ the number of rows by which the viewport was scrolled. This may differ
+ from the given numbers to scroll in case the begin or the end of the
+ row range were reached.
+ */
+ TableSize impl_ni_ScrollRows( TableSize _nRowDelta );
+
+ /** scrolls the view by the given number of columns
+
+ The method is not bound to the classes public invariants, as it's used in
+ situations where the they must not necessarily be fullfilled.
+
+ @return
+ the number of columns by which the viewport was scrolled. This may differ
+ from the given numbers to scroll in case the begin or the end of the
+ column range were reached.
+ */
+ TableSize impl_ni_ScrollColumns( TableSize _nRowDelta );
+ /** retrieves the area occupied by the totality of (at least partially) visible cells
+
+ The returned area includes row and column headers. Also, it takes into
+ account the the fact that there might be less columns than would normally
+ find room in the control.
+
+ As a result of respecting the partial visibility of rows and columns,
+ the returned area might be larger than the data window's output size.
+ */
+ void impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const;
+
+ /** retrieves the area occupied by all (at least partially) visible data cells.
+
+ Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea,
+ minus the row and column header areas.
+ */
+ void impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const;
+
+ void impl_ni_getAccVisibleColWidths();
+ void impl_updateLeftColumn();
+
+ DECL_LINK( OnScroll, ScrollBar* );
+ };
+ //see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine
+ class TableFunctionSet : public FunctionSet
+ {
+ friend class TableDataWindow;
+ private:
+ TableControl_Impl* m_pTableControl;
+ RowPos m_nCurrentRow;
+ public:
+ TableFunctionSet(TableControl_Impl* _pTableControl);
+ virtual ~TableFunctionSet();
+
+ virtual void BeginDrag();
+ virtual void CreateAnchor();
+ virtual void DestroyAnchor();
+ virtual BOOL SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor);
+ virtual BOOL IsSelectionAtPoint( const Point& rPoint );
+ virtual void DeselectAtPoint( const Point& rPoint );
+ virtual void DeselectAll();
+ };
+
+
+//........................................................................
+} } // namespace svt::table
+//........................................................................
+
+#endif // SVTOOLS_TABLECONTROL_IMPL_HXX
diff --git a/svtools/source/table/tabledatawindow.cxx b/svtools/source/table/tabledatawindow.cxx
new file mode 100644
index 000000000000..e2e1ce5353fe
--- /dev/null
+++ b/svtools/source/table/tabledatawindow.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.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "svtools/table/tablecontrol.hxx"
+#include "svtools/table/tabledatawindow.hxx"
+#include "tablecontrol_impl.hxx"
+#include <vcl/help.hxx>
+
+//........................................................................
+namespace svt { namespace table
+{
+ class TableControl_Impl;
+//........................................................................
+
+ //====================================================================
+ //= TableDataWindow
+ //====================================================================
+ //--------------------------------------------------------------------
+ TableDataWindow::TableDataWindow( TableControl_Impl& _rTableControl )
+ :Window( &_rTableControl.getAntiImpl() )
+ ,m_rTableControl ( _rTableControl )
+ ,m_nRowAlreadySelected( -1 )
+ {
+ // by default, use the background as determined by the style settings
+ const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() );
+ SetBackground( Wallpaper( aWindowColor ) );
+ SetFillColor( aWindowColor );
+ }
+
+ //--------------------------------------------------------------------
+ void TableDataWindow::Paint( const Rectangle& rUpdateRect )
+ {
+ m_rTableControl.doPaintContent( rUpdateRect );
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::SetBackground( const Wallpaper& rColor )
+ {
+ Window::SetBackground( rColor );
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::SetControlBackground( const Color& rColor )
+ {
+ Window::SetControlBackground( rColor );
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::SetBackground()
+ {
+ Window::SetBackground();
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::SetControlBackground()
+ {
+ Window::SetControlBackground();
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::MouseMove( const MouseEvent& rMEvt )
+ {
+ Point aPoint = rMEvt.GetPosPixel();
+ if ( !m_rTableControl.getInputHandler()->MouseMove( m_rTableControl, rMEvt ) )
+ {
+ if(m_rTableControl.getCurrentRow(aPoint)>=0 && m_rTableControl.isTooltipActive() )
+ {
+ SetPointer(POINTER_ARROW);
+ rtl::OUString& rHelpText = m_rTableControl.setTooltip(aPoint);
+ Help::EnableBalloonHelp();
+ Window::SetHelpText( rHelpText.getStr());
+ }
+ else if(m_rTableControl.getCurrentRow(aPoint) == -1)
+ {
+ if(Help::IsBalloonHelpEnabled())
+ Help::DisableBalloonHelp();
+ m_rTableControl.resizeColumn(aPoint);
+ }
+ else
+ {
+ if(Help::IsBalloonHelpEnabled())
+ Help::DisableBalloonHelp();
+ Window::MouseMove( rMEvt );
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::MouseButtonDown( const MouseEvent& rMEvt )
+ {
+ Point aPoint = rMEvt.GetPosPixel();
+ RowPos nCurRow = m_rTableControl.getCurrentRow(aPoint);
+ if ( !m_rTableControl.getInputHandler()->MouseButtonDown( m_rTableControl, rMEvt ) )
+ Window::MouseButtonDown( rMEvt );
+ else
+ {
+ if(nCurRow >= 0 && m_rTableControl.getSelEngine()->GetSelectionMode() != NO_SELECTION)
+ {
+ if( m_nRowAlreadySelected != nCurRow )
+ {
+ m_nRowAlreadySelected = nCurRow;
+ m_aSelectHdl.Call( NULL );
+ }
+ }
+ }
+ m_aMouseButtonDownHdl.Call((MouseEvent*) &rMEvt);
+ m_rTableControl.getAntiImpl().LoseFocus();
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::MouseButtonUp( const MouseEvent& rMEvt )
+ {
+ if ( !m_rTableControl.getInputHandler()->MouseButtonUp( m_rTableControl, rMEvt ) )
+ Window::MouseButtonUp( rMEvt );
+ m_aMouseButtonUpHdl.Call((MouseEvent*) &rMEvt);
+ m_rTableControl.getAntiImpl().GetFocus();
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::SetPointer( const Pointer& rPointer )
+ {
+ Window::SetPointer(rPointer);
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::CaptureMouse()
+ {
+ Window::CaptureMouse();
+ }
+ //--------------------------------------------------------------------
+ void TableDataWindow::ReleaseMouse( )
+ {
+ Window::ReleaseMouse();
+ }
+ // -----------------------------------------------------------------------
+ long TableDataWindow::Notify(NotifyEvent& rNEvt )
+ {
+ long nDone = 0;
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
+ if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
+ {
+ nDone = HandleScrollCommand( rCEvt, m_rTableControl.getHorzScrollbar(), m_rTableControl.getVertScrollbar() );
+ }
+ }
+ }
+ return nDone ? nDone : Window::Notify( rNEvt );
+ }
+//........................................................................
+} } // namespace svt::table
+//........................................................................
diff --git a/svtools/source/table/tablegeometry.cxx b/svtools/source/table/tablegeometry.cxx
new file mode 100644
index 000000000000..d60de9e6438f
--- /dev/null
+++ b/svtools/source/table/tablegeometry.cxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+
+#include "tablegeometry.hxx"
+#include "tablecontrol_impl.hxx"
+
+#include <tools/debug.hxx>
+
+//........................................................................
+namespace svt { namespace table
+{
+//........................................................................
+
+ //====================================================================
+ //= TableRowGeometry
+ //====================================================================
+ //--------------------------------------------------------------------
+ TableRowGeometry::TableRowGeometry( const TableControl_Impl& _rControl, const Rectangle& _rBoundaries,
+ RowPos _nRow )
+ :TableGeometry( _rControl, _rBoundaries )
+ ,m_nRowPos( _nRow )
+ {
+ if ( m_nRowPos == ROW_COL_HEADERS )
+ {
+ //DBG_ASSERT( m_rControl.m_pModel->hasColumnHeaders(),
+ // "TableRowGeometry::TableRowGeometry: why asking for the geoemtry of the non-existent column header row?" );
+ m_aRect.Top() = 0;
+ m_aRect.Bottom() = m_rControl.m_nColHeaderHeightPixel - 1;
+ }
+ else
+ {
+ if ( ( m_nRowPos >= m_rControl.m_nTopRow ) && ( m_nRowPos < m_rControl.m_pModel->getRowCount() ) )
+ {
+ m_aRect.Top() = m_rControl.m_nColHeaderHeightPixel + ( m_nRowPos - m_rControl.m_nTopRow ) * m_rControl.m_nRowHeightPixel;
+ m_aRect.Bottom() = m_aRect.Top() + m_rControl.m_nRowHeightPixel - 1;
+ }
+ else
+ m_aRect.SetEmpty();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool TableRowGeometry::moveDown()
+ {
+ if ( ++m_nRowPos < m_rControl.m_pModel->getRowCount() )
+ m_aRect.Move( 0, m_rControl.m_nRowHeightPixel );
+ else
+ m_aRect.SetEmpty();
+ return isValid();
+ }
+
+ //====================================================================
+ //= TableColumnGeometry
+ //====================================================================
+ //--------------------------------------------------------------------
+ TableColumnGeometry::TableColumnGeometry( const TableControl_Impl& _rControl, const Rectangle& _rBoundaries,
+ ColPos _nCol )
+ :TableGeometry( _rControl, _rBoundaries )
+ ,m_nColPos( _nCol )
+ {
+ if ( m_nColPos == COL_ROW_HEADERS )
+ {
+/* DBG_ASSERT( m_rControl.m_pModel->hasRowHeaders(),
+ "TableColumnGeometry::TableColumnGeometry: why asking for the geoemtry of the non-existent row header column?" )*/;
+ m_aRect.Left() = 0;
+ m_aRect.Right() = m_rControl.m_nRowHeaderWidthPixel - 1;
+ }
+ else
+ {
+ ColPos nLeftColumn = m_rControl.m_nLeftColumn;
+ if ( ( m_nColPos >= nLeftColumn ) && ( m_nColPos < (ColPos)m_rControl.m_aColumnWidthsPixel.size() ) )
+ {
+ m_aRect.Left() = m_rControl.m_nRowHeaderWidthPixel;
+ // TODO: take into account any possibly frozen columns
+
+ for ( ColPos col = nLeftColumn; col < m_nColPos; ++col )
+ m_aRect.Left() += m_rControl.m_aColumnWidthsPixel[ col ];
+ m_aRect.Right() = m_aRect.Left() + m_rControl.m_aColumnWidthsPixel[ m_nColPos ] - 1;
+ }
+ else
+ m_aRect.SetEmpty();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool TableColumnGeometry::moveRight()
+ {
+ DBG_ASSERT( m_nColPos != COL_ROW_HEADERS, "TableColumnGeometry::moveRight: cannot move the row header column!" );
+ // what would be COL_ROW_HEADERS + 1?
+
+ if ( ++m_nColPos < (ColPos)m_rControl.m_aColumnWidthsPixel.size() )
+ {
+ m_aRect.Left() = m_aRect.Right() + 1;
+ m_aRect.Right() += m_rControl.m_aColumnWidthsPixel[ m_nColPos ];
+ }
+ else
+ m_aRect.SetEmpty();
+
+ return isValid();
+ }
+
+//........................................................................
+} } // namespace svt::table
+//........................................................................
diff --git a/svtools/source/table/tablegeometry.hxx b/svtools/source/table/tablegeometry.hxx
new file mode 100644
index 000000000000..3ddde0c98c64
--- /dev/null
+++ b/svtools/source/table/tablegeometry.hxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#ifndef SVTOOLS_TABLEGEOMETRY_HXX
+#define SVTOOLS_TABLEGEOMETRY_HXX
+
+#ifndef SVTOOLS_INC_TABLE_TABLETYPES_HXX
+#include <svtools/table/tabletypes.hxx>
+#endif
+
+#ifndef _SV_GEN_HXX
+#include <tools/gen.hxx>
+#endif
+
+//........................................................................
+namespace svt { namespace table
+{
+//........................................................................
+
+ class TableControl_Impl;
+
+ //====================================================================
+ //= TableGeometry
+ //====================================================================
+ class TableGeometry
+ {
+ protected:
+ const TableControl_Impl& m_rControl;
+ const Rectangle& m_rBoundaries;
+ Rectangle m_aRect;
+
+ protected:
+ TableGeometry(
+ const TableControl_Impl& _rControl,
+ const Rectangle& _rBoundaries
+ )
+ :m_rControl( _rControl )
+ ,m_rBoundaries( _rBoundaries )
+ ,m_aRect( _rBoundaries )
+ {
+ }
+
+ public:
+ // attribute access
+ const TableControl_Impl& getControl() const { return m_rControl; }
+
+ // status
+ const Rectangle& getRect() const { return m_aRect; }
+ bool isValid() const { return !m_aRect.GetIntersection( m_rBoundaries ).IsEmpty(); }
+ };
+
+ //====================================================================
+ //= TableRowGeometry
+ //====================================================================
+ class TableRowGeometry : public TableGeometry
+ {
+ protected:
+ RowPos m_nRowPos;
+
+ public:
+ TableRowGeometry(
+ const TableControl_Impl& _rControl,
+ const Rectangle& _rBoundaries,
+ RowPos _nRow
+ );
+
+ // status
+ RowPos getRow() const { return m_nRowPos; }
+ // operations
+ bool moveDown();
+ };
+
+ //====================================================================
+ //= TableColumnGeometry
+ //====================================================================
+ class TableColumnGeometry : public TableGeometry
+ {
+ protected:
+ ColPos m_nColPos;
+
+ public:
+ TableColumnGeometry(
+ const TableControl_Impl& _rControl,
+ const Rectangle& _rBoundaries,
+ ColPos _nCol
+ );
+
+ // status
+ ColPos getCol() const { return m_nColPos; }
+ // operations
+ bool moveRight();
+ };
+
+ //====================================================================
+ //= TableCellGeometry
+ //====================================================================
+ /** a helper representing geometry information of a cell
+ */
+ class TableCellGeometry
+ {
+ private:
+ TableRowGeometry m_aRow;
+ TableColumnGeometry m_aCol;
+
+ public:
+ TableCellGeometry(
+ const TableControl_Impl& _rControl,
+ const Rectangle& _rBoundaries,
+ ColPos _nCol,
+ RowPos _nRow
+ )
+ :m_aRow( _rControl, _rBoundaries, _nRow )
+ ,m_aCol( _rControl, _rBoundaries, _nCol )
+ {
+ }
+
+ TableCellGeometry(
+ const TableRowGeometry& _rRow,
+ ColPos _nCol
+ )
+ :m_aRow( _rRow )
+ ,m_aCol( _rRow.getControl(), _rRow.getRect(), _nCol )
+ {
+ }
+
+ inline Rectangle getRect() const { return m_aRow.getRect().GetIntersection( m_aCol.getRect() ); }
+ inline RowPos getRow() const { return m_aRow.getRow(); }
+ inline ColPos getColumn() const { return m_aCol.getCol(); }
+ inline bool isValid() const { return !getRect().IsEmpty(); }
+
+ inline bool moveDown() {return m_aRow.moveDown(); }
+ inline bool moveRight() {return m_aCol.moveRight(); }
+ };
+
+//........................................................................
+} } // namespace svt::table
+//........................................................................
+
+#endif // SVTOOLS_TABLEGEOMETRY_HXX
diff --git a/svtools/source/toolpanel/drawerlayouter.cxx b/svtools/source/toolpanel/drawerlayouter.cxx
new file mode 100644
index 000000000000..040f33045fff
--- /dev/null
+++ b/svtools/source/toolpanel/drawerlayouter.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.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "svtools/toolpanel/drawerlayouter.hxx"
+#include "toolpaneldrawer.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+#include <comphelper/accimplaccess.hxx>
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::accessibility::XAccessible;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= DrawerDeckLayouter
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerDeckLayouter::DrawerDeckLayouter( ::Window& i_rParentWindow, IToolPanelDeck& i_rPanels )
+ :m_rParentWindow( i_rParentWindow )
+ ,m_rPanelDeck( i_rPanels )
+ ,m_aDrawers()
+ ,m_aLastKnownActivePanel()
+ {
+ m_rPanelDeck.AddListener( *this );
+
+ // simulate PanelInserted events for the panels which are already there
+ for ( size_t i=0; i<m_rPanelDeck.GetPanelCount(); ++i )
+ PanelInserted( m_rPanelDeck.GetPanel( i ), i );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerDeckLayouter::~DrawerDeckLayouter()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( DrawerDeckLayouter )
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle DrawerDeckLayouter::Layout( const Rectangle& i_rDeckPlayground )
+ {
+ const size_t nPanelCount( m_rPanelDeck.GetPanelCount() );
+ if ( nPanelCount == 0 )
+ return i_rDeckPlayground;
+
+ const int nWidth( i_rDeckPlayground.GetWidth() );
+ ::boost::optional< size_t > aActivePanel( m_rPanelDeck.GetActivePanel() );
+ if ( !aActivePanel )
+ aActivePanel = m_aLastKnownActivePanel;
+
+ // arrange the title bars which are *above* the active panel (or *all* if there is no active panel), plus
+ // the title bar of the active panel itself
+ Point aUpperDrawerPos( i_rDeckPlayground.TopLeft() );
+ const size_t nUpperBound = !!aActivePanel ? *aActivePanel : nPanelCount - 1;
+ for ( size_t i=0; i<=nUpperBound; ++i )
+ {
+ sal_uInt32 nDrawerHeight = m_aDrawers[i]->GetPreferredHeightPixel();
+ m_aDrawers[i]->SetPosSizePixel(
+ aUpperDrawerPos, Size( nWidth, nDrawerHeight ) );
+ aUpperDrawerPos.Move( 0, nDrawerHeight );
+ }
+
+ // arrange title bars which are below the active panel (or *none* if there is no active panel)
+ Point aLowerDrawerPos( i_rDeckPlayground.BottomLeft() );
+ for ( size_t j = nPanelCount - 1; j > nUpperBound; --j )
+ {
+ sal_uInt32 nDrawerHeight = m_aDrawers[j]->GetPreferredHeightPixel();
+ m_aDrawers[j]->SetPosSizePixel(
+ Point( aLowerDrawerPos.X(), aLowerDrawerPos.Y() - nDrawerHeight + 1 ),
+ Size( nWidth, nDrawerHeight )
+ );
+ aLowerDrawerPos.Move( 0, -nDrawerHeight );
+ }
+
+ // fincally calculate the rectangle for the active panel
+ return Rectangle(
+ aUpperDrawerPos,
+ Size( nWidth, aLowerDrawerPos.Y() - aUpperDrawerPos.Y() + 1 )
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::Destroy()
+ {
+ while ( !m_aDrawers.empty() )
+ impl_removeDrawer( 0 );
+ m_rPanelDeck.RemoveListener( *this );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::SetFocusToPanelSelector()
+ {
+ const size_t nPanelCount( m_rPanelDeck.GetPanelCount() );
+ if ( !nPanelCount )
+ // nothing to focus
+ return;
+ ::boost::optional< size_t > aActivePanel( m_rPanelDeck.GetActivePanel() );
+ if ( !aActivePanel )
+ aActivePanel = 0;
+ ENSURE_OR_RETURN_VOID( *aActivePanel < m_aDrawers.size(), "DrawerDeckLayouter::SetFocusToPanelSelector: invalid active panel, or inconsistent drawers!" );
+ m_aDrawers[ *aActivePanel ]->GrabFocus();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ size_t DrawerDeckLayouter::GetAccessibleChildCount() const
+ {
+ return m_aDrawers.size();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessible > DrawerDeckLayouter::GetAccessibleChild( const size_t i_nChildIndex, const Reference< XAccessible >& i_rParentAccessible )
+ {
+ ENSURE_OR_RETURN( i_nChildIndex < m_aDrawers.size(), "illegal index", NULL );
+
+ const PToolPanelDrawer pDrawer( m_aDrawers[ i_nChildIndex ] );
+
+ Reference< XAccessible > xItemAccessible = pDrawer->GetAccessible( FALSE );
+ if ( !xItemAccessible.is() )
+ {
+ xItemAccessible = pDrawer->GetAccessible( TRUE );
+ ENSURE_OR_RETURN( xItemAccessible.is(), "illegal accessible provided by the drawer implementation!", NULL );
+ OSL_VERIFY( ::comphelper::OAccessibleImplementationAccess::setAccessibleParent( xItemAccessible->getAccessibleContext(),
+ i_rParentAccessible ) );
+ }
+
+ return xItemAccessible;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ OSL_PRECOND( i_nPosition <= m_aDrawers.size(), "DrawerDeckLayouter::PanelInserted: inconsistency!" );
+
+ PToolPanelDrawer pDrawer( new ToolPanelDrawer( m_rParentWindow, i_pPanel->GetDisplayName() ) );
+ pDrawer->SetSmartHelpId( i_pPanel->GetHelpID() );
+ // proper Z-Order
+ if ( i_nPosition == 0 )
+ {
+ pDrawer->SetZOrder( NULL, WINDOW_ZORDER_FIRST );
+ }
+ else
+ {
+ const PToolPanelDrawer pFirstDrawer( m_aDrawers[ i_nPosition - 1 ] );
+ pDrawer->SetZOrder( pFirstDrawer.get(), WINDOW_ZORDER_BEHIND );
+ }
+
+ pDrawer->Show();
+ pDrawer->AddEventListener( LINK( this, DrawerDeckLayouter, OnWindowEvent ) );
+ m_aDrawers.insert( m_aDrawers.begin() + i_nPosition, pDrawer );
+ impl_triggerRearrange();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::PanelRemoved( const size_t i_nPosition )
+ {
+ impl_removeDrawer( i_nPosition );
+ impl_triggerRearrange();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::impl_triggerRearrange() const
+ {
+ // this is somewhat hacky, it assumes that the parent of our panels is a tool panel deck, which, in its
+ // Resize implementation, rearrances all elements.
+ m_rParentWindow.Resize();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
+ {
+ if ( !!i_rOldActive )
+ {
+ OSL_ENSURE( *i_rOldActive < m_aDrawers.size(), "DrawerDeckLayouter::ActivePanelChanged: illegal old index!" );
+ m_aDrawers[ *i_rOldActive ]->SetExpanded( false );
+ }
+
+ if ( !!i_rNewActive )
+ {
+ OSL_ENSURE( *i_rNewActive < m_aDrawers.size(), "DrawerDeckLayouter::ActivePanelChanged: illegal new index!" );
+ m_aDrawers[ *i_rNewActive ]->SetExpanded( true );
+ }
+
+ impl_triggerRearrange();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
+ {
+ // not interested in
+ (void)i_rNewLayouter;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ size_t DrawerDeckLayouter::impl_getPanelPositionFromWindow( const Window* i_pDrawerWindow ) const
+ {
+ for ( ::std::vector< PToolPanelDrawer >::const_iterator drawerPos = m_aDrawers.begin();
+ drawerPos != m_aDrawers.end();
+ ++drawerPos
+ )
+ {
+ if ( drawerPos->get() == i_pDrawerWindow )
+ return drawerPos - m_aDrawers.begin();
+ }
+ return m_aDrawers.size();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::impl_removeDrawer( const size_t i_nPosition )
+ {
+ OSL_PRECOND( i_nPosition < m_aDrawers.size(), "DrawerDeckLayouter::impl_removeDrawer: invalid panel position!" );
+ m_aDrawers[ i_nPosition ]->RemoveEventListener( LINK( this, DrawerDeckLayouter, OnWindowEvent ) );
+ OSL_ENSURE( m_aDrawers[ i_nPosition ].unique(), "DrawerDeckLayouter::impl_removeDrawer: somebody else is still holding a reference!" );
+ m_aDrawers.erase( m_aDrawers.begin() + i_nPosition );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IMPL_LINK( DrawerDeckLayouter, OnWindowEvent, VclSimpleEvent*, i_pEvent )
+ {
+ const VclWindowEvent* pWindowEvent = PTR_CAST( VclWindowEvent, i_pEvent );
+ ENSURE_OR_RETURN( pWindowEvent, "no WindowEvent", 0L );
+
+ bool bActivatePanel = false;
+ switch ( pWindowEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_MOUSEBUTTONUP:
+ {
+ const MouseEvent* pMouseEvent = static_cast< const MouseEvent* >( pWindowEvent->GetData() );
+ ENSURE_OR_RETURN( pMouseEvent, "no mouse event with MouseButtonUp", 0L );
+ if ( pMouseEvent->GetButtons() == MOUSE_LEFT )
+ {
+ bActivatePanel = true;
+ }
+ }
+ break;
+ case VCLEVENT_WINDOW_KEYINPUT:
+ {
+ const KeyEvent* pKeyEvent = static_cast< const KeyEvent* >( pWindowEvent->GetData() );
+ ENSURE_OR_RETURN( pKeyEvent, "no key event with KeyInput", 0L );
+ const KeyCode& rKeyCode( pKeyEvent->GetKeyCode() );
+ if ( ( rKeyCode.GetModifier() == 0 ) && ( rKeyCode.GetCode() == KEY_RETURN ) )
+ {
+ bActivatePanel = true;
+ }
+ }
+ break;
+ }
+ if ( bActivatePanel )
+ {
+ const size_t nPanelPos = impl_getPanelPositionFromWindow( pWindowEvent->GetWindow() );
+ if ( nPanelPos != m_rPanelDeck.GetActivePanel() )
+ {
+ m_rPanelDeck.ActivatePanel( nPanelPos );
+ }
+ else
+ {
+ PToolPanel pPanel( m_rPanelDeck.GetPanel( nPanelPos ) );
+ pPanel->GrabFocus();
+ }
+ return 1L;
+ }
+ return 0L;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::Dying()
+ {
+ Destroy();
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/dummypanel.cxx b/svtools/source/toolpanel/dummypanel.cxx
new file mode 100644
index 000000000000..20f140a6e610
--- /dev/null
+++ b/svtools/source/toolpanel/dummypanel.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "dummypanel.hxx"
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::accessibility::XAccessible;
+
+ //====================================================================
+ //= DummyPanel
+ //====================================================================
+ //--------------------------------------------------------------------
+ DummyPanel::DummyPanel()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DummyPanel::~DummyPanel()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( DummyPanel )
+
+ //--------------------------------------------------------------------
+ void DummyPanel::Activate( Window& )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void DummyPanel::Deactivate()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void DummyPanel::SetSizePixel( const Size& )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString DummyPanel::GetDisplayName() const
+ {
+ return ::rtl::OUString();
+ }
+
+ //--------------------------------------------------------------------
+ Image DummyPanel::GetImage() const
+ {
+ return Image();
+ }
+
+ //--------------------------------------------------------------------
+ SmartId DummyPanel::GetHelpID() const
+ {
+ return SmartId();
+ }
+
+ //--------------------------------------------------------------------
+ void DummyPanel::GrabFocus()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void DummyPanel::Dispose()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XAccessible > DummyPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible )
+ {
+ (void)i_rParentAccessible;
+ return NULL;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/dummypanel.hxx b/svtools/source/toolpanel/dummypanel.hxx
new file mode 100644
index 000000000000..adb98e52077e
--- /dev/null
+++ b/svtools/source/toolpanel/dummypanel.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 DUMMYPANEL_HXX
+#define DUMMYPANEL_HXX
+
+#include "svtools/toolpanel/toolpanel.hxx"
+#include "svtools/toolpanel/refbase.hxx"
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= DummyPanel
+ //====================================================================
+ /// is a dummy implementation of the IToolPanel interface
+ class DummyPanel :public RefBase
+ ,public IToolPanel
+ {
+ public:
+ DummyPanel();
+ ~DummyPanel();
+
+ // IToolPanel
+ virtual ::rtl::OUString GetDisplayName() const;
+ virtual Image GetImage() const;
+ virtual SmartId GetHelpID() const;
+ virtual void Activate( Window& i_rParentWindow );
+ virtual void Deactivate();
+ virtual void SetSizePixel( const Size& i_rPanelWindowSize );
+ virtual void GrabFocus();
+ virtual void Dispose();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ CreatePanelAccessible(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rParentAccessible
+ );
+
+ DECLARE_IREFERENCE()
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // DUMMYPANEL_HXX
diff --git a/svtools/source/toolpanel/makefile.mk b/svtools/source/toolpanel/makefile.mk
new file mode 100755
index 000000000000..58282056f529
--- /dev/null
+++ b/svtools/source/toolpanel/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# 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: makefile.mk,v $
+#
+# $Revision: 1.16 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General 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=svtools
+TARGET=toolpanel
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES=\
+ toolpanel.src
+
+SLOFILES=\
+ $(SLO)$/drawerlayouter.obj \
+ $(SLO)$/dummypanel.obj \
+ $(SLO)$/paneldecklisteners.obj \
+ $(SLO)$/paneltabbar.obj \
+ $(SLO)$/paneltabbarpeer.obj \
+ $(SLO)$/refbase.obj \
+ $(SLO)$/tabbargeometry.obj \
+ $(SLO)$/tablayouter.obj \
+ $(SLO)$/toolpanel.obj \
+ $(SLO)$/toolpanelcollection.obj \
+ $(SLO)$/toolpaneldrawer.obj \
+ $(SLO)$/toolpaneldrawerpeer.obj \
+ $(SLO)$/toolpaneldeck.obj \
+ $(SLO)$/toolpaneldeckpeer.obj \
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/toolpanel/paneldecklisteners.cxx b/svtools/source/toolpanel/paneldecklisteners.cxx
new file mode 100755
index 000000000000..32ba9b5c6a24
--- /dev/null
+++ b/svtools/source/toolpanel/paneldecklisteners.cxx
@@ -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.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "paneldecklisteners.hxx"
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= PanelDeckListeners
+ //====================================================================
+ //--------------------------------------------------------------------
+ PanelDeckListeners::PanelDeckListeners()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ PanelDeckListeners::~PanelDeckListeners()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners );
+ for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin();
+ loop != aListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->PanelInserted( i_pPanel, i_nPosition );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::PanelRemoved( const size_t i_nPosition )
+ {
+ ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners );
+ for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin();
+ loop != aListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->PanelRemoved( i_nPosition );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
+ {
+ ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners );
+ for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin();
+ loop != aListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->ActivePanelChanged( i_rOldActive, i_rNewActive );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
+ {
+ ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners );
+ for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin();
+ loop != aListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->LayouterChanged( i_rNewLayouter );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::Dying()
+ {
+ while ( !m_aListeners.empty() )
+ {
+ IToolPanelDeckListener* pListener( *m_aListeners.begin() );
+ m_aListeners.erase( m_aListeners.begin() );
+ pListener->Dying();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::AddListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_aListeners.push_back( &i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void PanelDeckListeners::RemoveListener( IToolPanelDeckListener& i_rListener )
+ {
+ for ( ::std::vector< IToolPanelDeckListener* >::iterator lookup = m_aListeners.begin();
+ lookup != m_aListeners.end();
+ ++lookup
+ )
+ {
+ if ( *lookup == &i_rListener )
+ {
+ m_aListeners.erase( lookup );
+ return;
+ }
+ }
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/paneldecklisteners.hxx b/svtools/source/toolpanel/paneldecklisteners.hxx
new file mode 100755
index 000000000000..bc7e2ae7db88
--- /dev/null
+++ b/svtools/source/toolpanel/paneldecklisteners.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 PANELDECKLISTENERS_HXX
+#define PANELDECKLISTENERS_HXX
+
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+
+#include <boost/optional.hpp>
+#include <vector>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ class IToolPanelDeckListener;
+
+ //====================================================================
+ //= PanelDeckListeners
+ //====================================================================
+ /** implements a container for IToolPanelDeckListeners
+ */
+ class PanelDeckListeners
+ {
+ public:
+ PanelDeckListeners();
+ ~PanelDeckListeners();
+
+ // IToolPanelDeckListener equivalents, forward the events to all registered listeners
+ void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition );
+ void PanelRemoved( const size_t i_nPosition );
+ void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
+ void LayouterChanged( const PDeckLayouter& i_rNewLayouter );
+ void Dying();
+
+ // listener maintainance
+ void AddListener( IToolPanelDeckListener& i_rListener );
+ void RemoveListener( IToolPanelDeckListener& i_rListener );
+
+ private:
+ ::std::vector< IToolPanelDeckListener* > m_aListeners;
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // PANELDECKLISTENERS_HXX
diff --git a/svtools/source/toolpanel/paneltabbar.cxx b/svtools/source/toolpanel/paneltabbar.cxx
new file mode 100755
index 000000000000..23067d3ee5d0
--- /dev/null
+++ b/svtools/source/toolpanel/paneltabbar.cxx
@@ -0,0 +1,1354 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_svtools.hxx"
+
+#include "svtools/toolpanel/paneltabbar.hxx"
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+#include "svtools/svtdata.hxx"
+#include "svtools/svtools.hrc"
+
+#include "tabitemdescriptor.hxx"
+#include "paneltabbarpeer.hxx"
+#include "tabbargeometry.hxx"
+
+#include <vcl/button.hxx>
+#include <vcl/help.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <boost/optional.hpp>
+#include <vector>
+
+// space around an item
+#define ITEM_OUTER_SPACE 2 * 3
+// spacing before and after an item's text
+#define ITEM_TEXT_FLOW_SPACE 5
+// space between item icon and icon text
+#define ITEM_ICON_TEXT_DISTANCE 4
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::awt::XWindowPeer;
+
+ typedef sal_uInt16 ItemFlags;
+
+ #define ITEM_STATE_NORMAL 0x00
+ #define ITEM_STATE_ACTIVE 0x01
+ #define ITEM_STATE_HOVERED 0x02
+ #define ITEM_STATE_FOCUSED 0x04
+ #define ITEM_POSITION_FIRST 0x08
+ #define ITEM_POSITION_LAST 0x10
+
+ //==================================================================================================================
+ //= helper
+ //==================================================================================================================
+ namespace
+ {
+ ControlState lcl_ItemToControlState( const ItemFlags i_nItemFlags )
+ {
+ ControlState nState = CTRL_STATE_ENABLED;
+ if ( i_nItemFlags & ITEM_STATE_FOCUSED ) nState |= CTRL_STATE_FOCUSED | CTRL_STATE_PRESSED;
+ if ( i_nItemFlags & ITEM_STATE_HOVERED ) nState |= CTRL_STATE_ROLLOVER;
+ if ( i_nItemFlags & ITEM_STATE_ACTIVE ) nState |= CTRL_STATE_SELECTED;
+ return nState;
+ }
+ }
+
+ //==================================================================================================================
+ //= ITabBarRenderer
+ //==================================================================================================================
+ class SAL_NO_VTABLE ITabBarRenderer
+ {
+ public:
+ /** fills the background of our target device
+ */
+ virtual void renderBackground() const = 0;
+ virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const = 0;
+ virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const = 0;
+ virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const = 0;
+
+ // TODO: postRenderItem takes the "real" window, i.e. effectively the tab bar. This is because
+ // DrawSelectionBackground needs to be applied after everything else is painted, and is available at the Window
+ // class, but not at the OutputDevice. This makes the API somewhat weird, as we're now mixing operations on the
+ // target device, done in a normalized geometry, with operations on the window, done in a transformed geometry.
+ // So, we should get rid of postRenderItem completely.
+ };
+ typedef ::boost::shared_ptr< ITabBarRenderer > PTabBarRenderer;
+
+ //==================================================================================================================
+ //= VCLItemRenderer - declaration
+ //==================================================================================================================
+ class VCLItemRenderer : public ITabBarRenderer
+ {
+ public:
+ VCLItemRenderer( OutputDevice& i_rTargetDevice )
+ :m_rTargetDevice( i_rTargetDevice )
+ {
+ }
+
+ // ITabBarRenderer
+ virtual void renderBackground() const;
+ virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const;
+ virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const;
+ virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const;
+
+ protected:
+ OutputDevice& getTargetDevice() const { return m_rTargetDevice; }
+
+ private:
+ OutputDevice& m_rTargetDevice;
+ };
+
+ //==================================================================================================================
+ //= VCLItemRenderer - implementation
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ void VCLItemRenderer::renderBackground() const
+ {
+ getTargetDevice().DrawRect( Rectangle( Point(), getTargetDevice().GetOutputSizePixel() ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle VCLItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const
+ {
+ (void)i_nItemFlags;
+ // no decorations at all
+ return i_rContentArea;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void VCLItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const
+ {
+ (void)i_rContentRect;
+ (void)i_nItemFlags;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void VCLItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const
+ {
+ const bool bActive = ( ( i_nItemFlags & ITEM_STATE_ACTIVE ) != 0 );
+ const bool bHovered = ( ( i_nItemFlags & ITEM_STATE_HOVERED ) != 0 );
+ const bool bFocused = ( ( i_nItemFlags & ITEM_STATE_FOCUSED ) != 0 );
+ if ( bActive || bHovered || bFocused )
+ {
+ Rectangle aSelectionRect( i_rItemRect );
+ aSelectionRect.Left() += ITEM_OUTER_SPACE / 2;
+ aSelectionRect.Top() += ITEM_OUTER_SPACE / 2;
+ aSelectionRect.Right() -= ITEM_OUTER_SPACE / 2;
+ aSelectionRect.Bottom() -= ITEM_OUTER_SPACE / 2;
+ i_rActualWindow.DrawSelectionBackground(
+ aSelectionRect,
+ ( bHovered || bFocused ) ? ( bActive ? 1 : 2 ) : 0 /* hilight */,
+ bActive /* check */,
+ TRUE /* border */,
+ FALSE /* ext border only */,
+ 0 /* corner radius */,
+ NULL,
+ NULL
+ );
+ }
+ }
+
+ //==================================================================================================================
+ //= NWFToolboxItemRenderer - declaration
+ //==================================================================================================================
+ class NWFToolboxItemRenderer : public ITabBarRenderer
+ {
+ public:
+ NWFToolboxItemRenderer( OutputDevice& i_rTargetDevice )
+ :m_rTargetDevice( i_rTargetDevice )
+ {
+ }
+
+ // ITabBarRenderer
+ virtual void renderBackground() const;
+ virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const;
+ virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const;
+ virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const;
+
+ protected:
+ OutputDevice& getTargetDevice() const { return m_rTargetDevice; }
+
+ private:
+ OutputDevice& m_rTargetDevice;
+ };
+
+ //==================================================================================================================
+ //= NWFToolboxItemRenderer - implementation
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ void NWFToolboxItemRenderer::renderBackground() const
+ {
+ getTargetDevice().DrawRect( Rectangle( Point(), getTargetDevice().GetOutputSizePixel() ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle NWFToolboxItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const
+ {
+ // don't ask GetNativeControlRegion, this will not deliver proper results in all cases.
+ // Instead, simply assume that both the content and the bounding region are the same.
+// const ControlState nState( lcl_ItemToControlState( i_nItemFlags );
+// const ImplControlValue aControlValue;
+// bool bNativeOK = m_rTargetWindow.GetNativeControlRegion(
+// CTRL_TOOLBAR, PART_BUTTON,
+// i_rContentArea, nState,
+// aControlValue, ::rtl::OUString(),
+// aBoundingRegion, aContentRegion
+// );
+ (void)i_nItemFlags;
+ return Rectangle(
+ Point( i_rContentArea.Left() - 1, i_rContentArea.Top() - 1 ),
+ Size( i_rContentArea.GetWidth() + 2, i_rContentArea.GetHeight() + 2 )
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void NWFToolboxItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const
+ {
+ const ControlState nState = lcl_ItemToControlState( i_nItemFlags );
+
+ ImplControlValue aControlValue;
+ aControlValue.setTristateVal( ( i_nItemFlags & ITEM_STATE_ACTIVE ) ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
+
+ bool bNativeOK = getTargetDevice().DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON, i_rContentRect, nState, aControlValue, rtl::OUString() );
+ (void)bNativeOK;
+ OSL_ENSURE( bNativeOK, "NWFToolboxItemRenderer::preRenderItem: inconsistent NWF implementation!" );
+ // IsNativeControlSupported returned true, previously, otherwise we would not be here ...
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void NWFToolboxItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const
+ {
+ (void)i_rActualWindow;
+ (void)i_rItemRect;
+ (void)i_nItemFlags;
+ }
+
+ //==================================================================================================================
+ //= NWFTabItemRenderer - declaration
+ //==================================================================================================================
+ class NWFTabItemRenderer : public ITabBarRenderer
+ {
+ public:
+ NWFTabItemRenderer( OutputDevice& i_rTargetDevice )
+ :m_rTargetDevice( i_rTargetDevice )
+ {
+ }
+
+ // ITabBarRenderer
+ virtual void renderBackground() const;
+ virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const;
+ virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const;
+ virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const;
+
+ protected:
+ OutputDevice& getTargetDevice() const { return m_rTargetDevice; }
+
+ private:
+ OutputDevice& m_rTargetDevice;
+ };
+
+ //==================================================================================================================
+ //= NWFTabItemRenderer - implementation
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ void NWFTabItemRenderer::renderBackground() const
+ {
+ Rectangle aBackground( Point(), getTargetDevice().GetOutputSizePixel() );
+ getTargetDevice().DrawRect( aBackground );
+
+ aBackground.Top() = aBackground.Bottom();
+ getTargetDevice().DrawNativeControl( CTRL_TAB_PANE, PART_ENTIRE_CONTROL, aBackground,
+ CTRL_STATE_ENABLED, ImplControlValue(), ::rtl::OUString() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle NWFTabItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const
+ {
+ const ControlState nState( lcl_ItemToControlState( i_nItemFlags ) );
+
+ TabitemValue tiValue;
+
+ Rectangle aBoundingRegion, aContentRegion;
+ bool bNativeOK = getTargetDevice().GetNativeControlRegion(
+ CTRL_TAB_ITEM, PART_ENTIRE_CONTROL,
+ i_rContentArea, nState,
+ tiValue, ::rtl::OUString(),
+ aBoundingRegion, aContentRegion
+ );
+ (void)bNativeOK;
+ OSL_ENSURE( bNativeOK, "NWFTabItemRenderer::calculateDecorations: GetNativeControlRegion not implemented for CTRL_TAB_ITEM?!" );
+
+ return aBoundingRegion;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void NWFTabItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const
+ {
+ const ControlState nState = lcl_ItemToControlState( i_nItemFlags );
+
+ TabitemValue tiValue;
+ if ( i_nItemFlags & ITEM_POSITION_FIRST )
+ tiValue.mnAlignment |= TABITEM_FIRST_IN_GROUP;
+ if ( i_nItemFlags & ITEM_POSITION_LAST )
+ tiValue.mnAlignment |= TABITEM_LAST_IN_GROUP;
+
+
+ bool bNativeOK = getTargetDevice().DrawNativeControl( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, i_rContentRect, nState, tiValue, rtl::OUString() );
+ (void)bNativeOK;
+ OSL_ENSURE( bNativeOK, "NWFTabItemRenderer::preRenderItem: inconsistent NWF implementation!" );
+ // IsNativeControlSupported returned true, previously, otherwise we would not be here ...
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void NWFTabItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const
+ {
+ (void)i_rActualWindow;
+ (void)i_rItemRect;
+ (void)i_nItemFlags;
+ }
+
+ //==================================================================================================================
+ //= PanelTabBar_Impl
+ //==================================================================================================================
+ class PanelTabBar_Impl : public IToolPanelDeckListener
+ {
+ public:
+ PanelTabBar_Impl( PanelTabBar& i_rTabBar, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent );
+
+ ~PanelTabBar_Impl()
+ {
+ m_rPanelDeck.RemoveListener( *this );
+ }
+
+ // IToolPanelDeckListener
+ virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ (void)i_pPanel;
+ (void)i_nPosition;
+ m_bItemsDirty = true;
+ m_rTabBar.Invalidate();
+
+ Relayout();
+ }
+
+ virtual void PanelRemoved( const size_t i_nPosition )
+ {
+ m_bItemsDirty = true;
+ m_rTabBar.Invalidate();
+
+ if ( i_nPosition < m_nScrollPosition )
+ --m_nScrollPosition;
+
+ Relayout();
+ }
+
+ virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
+ virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter );
+ virtual void Dying();
+
+ void UpdateScrollButtons()
+ {
+ m_aScrollBack.Enable( m_nScrollPosition > 0 );
+ m_aScrollForward.Enable( m_nScrollPosition < m_aItems.size() - 1 );
+ }
+
+ void Relayout();
+ void EnsureItemsCache();
+ ::boost::optional< size_t > FindItemForPoint( const Point& i_rPoint ) const;
+ void DrawItem( const size_t i_nItemIndex, const Rectangle& i_rBoundaries ) const;
+ void InvalidateItem( const size_t i_nItemIndex, const ItemFlags i_nAdditionalItemFlags = 0 ) const;
+ void CopyFromRenderDevice( const Rectangle& i_rLogicalRect ) const;
+ Rectangle GetActualLogicalItemRect( const Rectangle& i_rLogicalItemRect ) const;
+ Rectangle GetItemScreenRect( const size_t i_nItemPos ) const;
+
+ void FocusItem( const ::boost::optional< size_t >& i_rItemPos );
+
+ inline bool IsVertical() const
+ {
+ return ( ( m_eTabAlignment == TABS_LEFT )
+ || ( m_eTabAlignment == TABS_RIGHT )
+ );
+ }
+
+ protected:
+ DECL_LINK( OnScroll, const PushButton* );
+
+ void impl_calcItemRects();
+ Size impl_calculateItemContentSize( const PToolPanel& i_pPanel, const TabItemContent i_eItemContent ) const;
+ void impl_renderItemContent( const PToolPanel& i_pPanel, const Rectangle& i_rContentArea, const TabItemContent i_eItemContent ) const;
+ ItemFlags impl_getItemFlags( const size_t i_nItemIndex ) const;
+
+ public:
+ PanelTabBar& m_rTabBar;
+ TabBarGeometry m_aGeometry;
+ NormalizedArea m_aNormalizer;
+ TabAlignment m_eTabAlignment;
+ IToolPanelDeck& m_rPanelDeck;
+
+ VirtualDevice m_aRenderDevice;
+ PTabBarRenderer m_pRenderer;
+
+ ::boost::optional< size_t > m_aHoveredItem;
+ ::boost::optional< size_t > m_aFocusedItem;
+ bool m_bMouseButtonDown;
+
+ ItemDescriptors m_aItems;
+ bool m_bItemsDirty;
+
+ PushButton m_aScrollBack;
+ PushButton m_aScrollForward;
+
+ size_t m_nScrollPosition;
+ };
+
+ //==================================================================================================================
+ //= helper
+ //==================================================================================================================
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ #if OSL_DEBUG_LEVEL > 0
+ static void lcl_checkConsistency( const PanelTabBar_Impl& i_rImpl )
+ {
+ if ( !i_rImpl.m_bItemsDirty )
+ {
+ if ( i_rImpl.m_rPanelDeck.GetPanelCount() != i_rImpl.m_aItems.size() )
+ {
+ OSL_ENSURE( false, "lcl_checkConsistency: inconsistent array sizes!" );
+ return;
+ }
+ for ( size_t i = 0; i < i_rImpl.m_rPanelDeck.GetPanelCount(); ++i )
+ {
+ if ( i_rImpl.m_rPanelDeck.GetPanel( i ).get() != i_rImpl.m_aItems[i].pPanel.get() )
+ {
+ OSL_ENSURE( false, "lcl_checkConsistency: array elements are inconsistent!" );
+ return;
+ }
+ }
+ }
+ }
+
+ #define DBG_CHECK( data ) \
+ lcl_checkConsistency( data );
+ #else
+ #define DBG_CHECK( data ) \
+ (void)data;
+ #endif
+
+ //--------------------------------------------------------------------------------------------------------------
+ class ClipItemRegion
+ {
+ public:
+ ClipItemRegion( const PanelTabBar_Impl& i_rImpl )
+ :m_rDevice( i_rImpl.m_rTabBar )
+ {
+ m_rDevice.Push( PUSH_CLIPREGION );
+ m_rDevice.SetClipRegion( i_rImpl.m_aNormalizer.getTransformed( i_rImpl.m_aGeometry.getItemsRect(), i_rImpl.m_eTabAlignment ) );
+ }
+
+ ~ClipItemRegion()
+ {
+ m_rDevice.Pop();
+ }
+
+ private:
+ OutputDevice& m_rDevice;
+ };
+ }
+
+ //==================================================================================================================
+ //= PanelTabBar_Impl - implementation
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBar_Impl::PanelTabBar_Impl( PanelTabBar& i_rTabBar, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
+ :m_rTabBar( i_rTabBar )
+ ,m_aGeometry( i_eItemContent )
+ ,m_aNormalizer()
+ ,m_eTabAlignment( i_eAlignment )
+ ,m_rPanelDeck( i_rPanelDeck )
+ ,m_aRenderDevice( i_rTabBar )
+ ,m_pRenderer()
+ ,m_aHoveredItem()
+ ,m_aFocusedItem()
+ ,m_bMouseButtonDown( false )
+ ,m_aItems()
+ ,m_bItemsDirty( true )
+ ,m_aScrollBack( &i_rTabBar, WB_BEVELBUTTON )
+ ,m_aScrollForward( &i_rTabBar, WB_BEVELBUTTON )
+ ,m_nScrollPosition( 0 )
+ {
+#ifdef WNT
+ if ( m_aRenderDevice.IsNativeControlSupported( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL ) )
+ // this mode requires the NWF framework to be able to render those items onto a virtual
+ // device. For some frameworks (some GTK themes, in particular), this is known to fail.
+ // So, be on the safe side for the moment.
+ m_pRenderer.reset( new NWFTabItemRenderer( m_aRenderDevice ) );
+ else
+#endif
+ if ( m_aRenderDevice.IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
+ m_pRenderer.reset( new NWFToolboxItemRenderer( m_aRenderDevice ) );
+ else
+ m_pRenderer.reset( new VCLItemRenderer( m_aRenderDevice ) );
+
+ m_aRenderDevice.SetLineColor();
+
+ m_rPanelDeck.AddListener( *this );
+
+ m_aScrollBack.SetSymbol( IsVertical() ? SYMBOL_ARROW_UP : SYMBOL_ARROW_LEFT );
+ m_aScrollBack.Show();
+ m_aScrollBack.SetClickHdl( LINK( this, PanelTabBar_Impl, OnScroll ) );
+ m_aScrollBack.SetAccessibleDescription( String( SvtResId( STR_SVT_TOOL_PANEL_BUTTON_FWD ) ) );
+ m_aScrollBack.SetAccessibleName( m_aScrollBack.GetAccessibleDescription() );
+
+ m_aScrollForward.SetSymbol( IsVertical() ? SYMBOL_ARROW_DOWN : SYMBOL_ARROW_RIGHT );
+ m_aScrollForward.Show();
+ m_aScrollForward.SetClickHdl( LINK( this, PanelTabBar_Impl, OnScroll ) );
+ m_aScrollForward.SetAccessibleDescription( String( SvtResId( STR_SVT_TOOL_PANEL_BUTTON_BACK ) ) );
+ m_aScrollForward.SetAccessibleName( m_aScrollForward.GetAccessibleDescription() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::impl_calcItemRects()
+ {
+ m_aItems.resize(0);
+
+ Point aCompletePos( m_aGeometry.getFirstItemPosition() );
+ Point aIconOnlyPos( aCompletePos );
+ Point aTextOnlyPos( aCompletePos );
+
+ for ( size_t i = 0;
+ i < m_rPanelDeck.GetPanelCount();
+ ++i
+ )
+ {
+ PToolPanel pPanel( m_rPanelDeck.GetPanel( i ) );
+
+ ItemDescriptor aItem;
+ aItem.pPanel = pPanel;
+
+ Rectangle aContentArea;
+
+ const Size aCompleteSize( impl_calculateItemContentSize( pPanel, TABITEM_IMAGE_AND_TEXT ) );
+ const Size aIconOnlySize( impl_calculateItemContentSize( pPanel, TABITEM_IMAGE_ONLY ) );
+ const Size aTextOnlySize( impl_calculateItemContentSize( pPanel, TABITEM_TEXT_ONLY ) );
+
+ // TODO: have one method calculating all sizes?
+
+ // remember the three areas
+ aItem.aCompleteArea = Rectangle( aCompletePos, aCompleteSize );
+ aItem.aIconOnlyArea = Rectangle( aIconOnlyPos, aIconOnlySize );
+ aItem.aTextOnlyArea = Rectangle( aTextOnlyPos, aTextOnlySize );
+
+ m_aItems.push_back( aItem );
+
+ aCompletePos = aItem.aCompleteArea.TopRight();
+ aIconOnlyPos = aItem.aIconOnlyArea.TopRight();
+ aTextOnlyPos = aItem.aTextOnlyArea.TopRight();
+ }
+
+ m_bItemsDirty = false;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Size PanelTabBar_Impl::impl_calculateItemContentSize( const PToolPanel& i_pPanel, const TabItemContent i_eItemContent ) const
+ {
+ // calculate the size needed for the content
+ OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "PanelTabBar_Impl::impl_calculateItemContentSize: illegal TabItemContent value!" );
+
+ const Image aImage( i_pPanel->GetImage() );
+ const bool bUseImage = !!aImage && ( i_eItemContent != TABITEM_TEXT_ONLY );
+
+ const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() );
+ const bool bUseText = ( sItemText.getLength() != 0 ) && ( i_eItemContent != TABITEM_IMAGE_ONLY );
+
+ Size aItemContentSize;
+ if ( bUseImage )
+ {
+ aItemContentSize = aImage.GetSizePixel();
+ }
+
+ if ( bUseText )
+ {
+ if ( bUseImage )
+ aItemContentSize.Width() += ITEM_ICON_TEXT_DISTANCE;
+
+ // add space for text
+ const Size aTextSize( m_rTabBar.GetCtrlTextWidth( sItemText ), m_rTabBar.GetTextHeight() );
+ aItemContentSize.Width() += aTextSize.Width();
+ aItemContentSize.Height() = ::std::max( aItemContentSize.Height(), aTextSize.Height() );
+
+ aItemContentSize.Width() += 2 * ITEM_TEXT_FLOW_SPACE;
+ }
+
+ if ( !bUseImage && !bUseText )
+ {
+ // have a minimal size - this is pure heuristics, but if it doesn't suit your needs, then give your panels
+ // a name and or image! :)
+ aItemContentSize = Size( 16, 16 );
+ }
+
+ aItemContentSize.Width() += 2 * ITEM_OUTER_SPACE;
+ aItemContentSize.Height() += 2 * ITEM_OUTER_SPACE;
+
+ return aItemContentSize;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::impl_renderItemContent( const PToolPanel& i_pPanel, const Rectangle& i_rContentArea, const TabItemContent i_eItemContent ) const
+ {
+ OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "PanelTabBar_Impl::impl_renderItemContent: illegal TabItemContent value!" );
+
+ Rectangle aRenderArea( i_rContentArea );
+ if ( IsVertical() )
+ {
+ aRenderArea.Top() += ITEM_OUTER_SPACE;
+ }
+ else
+ {
+ aRenderArea.Left() += ITEM_OUTER_SPACE;
+ }
+
+ // draw the image
+ const Image aItemImage( i_pPanel->GetImage() );
+ const Size aImageSize( aItemImage.GetSizePixel() );
+ const bool bUseImage = !!aItemImage && ( i_eItemContent != TABITEM_TEXT_ONLY );
+
+ if ( bUseImage )
+ {
+ Point aImagePos;
+ if ( IsVertical() )
+ {
+ aImagePos.X() = aRenderArea.Left() + ( aRenderArea.GetWidth() - aImageSize.Width() ) / 2;
+ aImagePos.Y() = aRenderArea.Top();
+ }
+ else
+ {
+ aImagePos.X() = aRenderArea.Left();
+ aImagePos.Y() = aRenderArea.Top() + ( aRenderArea.GetHeight() - aImageSize.Height() ) / 2;
+ }
+ m_rTabBar.DrawImage( aImagePos, aItemImage );
+ }
+
+ const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() );
+ const bool bUseText = ( sItemText.getLength() != 0 ) && ( i_eItemContent != TABITEM_IMAGE_ONLY );
+
+ if ( bUseText )
+ {
+ if ( IsVertical() )
+ {
+ if ( bUseImage )
+ aRenderArea.Top() += aImageSize.Height() + ITEM_ICON_TEXT_DISTANCE;
+ aRenderArea.Top() += ITEM_TEXT_FLOW_SPACE;
+ }
+ else
+ {
+ if ( bUseImage )
+ aRenderArea.Left() += aImageSize.Width() + ITEM_ICON_TEXT_DISTANCE;
+ aRenderArea.Left() += ITEM_TEXT_FLOW_SPACE;
+ }
+
+ // draw the text
+ const Size aTextSize( m_rTabBar.GetCtrlTextWidth( sItemText ), m_rTabBar.GetTextHeight() );
+ Point aTextPos( aRenderArea.TopLeft() );
+ if ( IsVertical() )
+ {
+ m_rTabBar.Push( PUSH_FONT );
+
+ Font aFont( m_rTabBar.GetFont() );
+ aFont.SetOrientation( 2700 );
+ aFont.SetVertical( TRUE );
+ m_rTabBar.SetFont( aFont );
+
+ aTextPos.X() += aTextSize.Height();
+ aTextPos.X() += ( aRenderArea.GetWidth() - aTextSize.Height() ) / 2;
+ }
+ else
+ {
+ aTextPos.Y() += ( aRenderArea.GetHeight() - aTextSize.Height() ) / 2;
+ }
+
+ m_rTabBar.DrawText( aTextPos, sItemText );
+
+ if ( IsVertical() )
+ {
+ m_rTabBar.Pop();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::CopyFromRenderDevice( const Rectangle& i_rLogicalRect ) const
+ {
+ BitmapEx aBitmap( m_aRenderDevice.GetBitmapEx(
+ i_rLogicalRect.TopLeft(),
+ Size(
+ i_rLogicalRect.GetSize().Width(),
+ i_rLogicalRect.GetSize().Height()
+ )
+ ) );
+ if ( IsVertical() )
+ {
+ aBitmap.Rotate( 2700, COL_BLACK );
+ if ( m_eTabAlignment == TABS_LEFT )
+ aBitmap.Mirror( BMP_MIRROR_HORZ );
+ }
+ else if ( m_eTabAlignment == TABS_BOTTOM )
+ {
+ aBitmap.Mirror( BMP_MIRROR_VERT );
+ }
+
+ const Rectangle aActualRect( m_aNormalizer.getTransformed( i_rLogicalRect, m_eTabAlignment ) );
+ m_rTabBar.DrawBitmapEx( aActualRect.TopLeft(), aBitmap );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::InvalidateItem( const size_t i_nItemIndex, const ItemFlags i_nAdditionalItemFlags ) const
+ {
+ const ItemDescriptor& rItem( m_aItems[ i_nItemIndex ] );
+ const ItemFlags nItemFlags( impl_getItemFlags( i_nItemIndex ) | i_nAdditionalItemFlags );
+
+ const Rectangle aNormalizedContent( GetActualLogicalItemRect( rItem.GetCurrentRect() ) );
+ const Rectangle aNormalizedBounds( m_pRenderer->calculateDecorations( aNormalizedContent, nItemFlags ) );
+
+ const Rectangle aActualBounds = m_aNormalizer.getTransformed( aNormalizedBounds, m_eTabAlignment );
+ m_rTabBar.Invalidate( aActualBounds );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ItemFlags PanelTabBar_Impl::impl_getItemFlags( const size_t i_nItemIndex ) const
+ {
+ ItemFlags nItemFlags( ITEM_STATE_NORMAL );
+ if ( m_aHoveredItem == i_nItemIndex )
+ {
+ nItemFlags |= ITEM_STATE_HOVERED;
+ if ( m_bMouseButtonDown )
+ nItemFlags |= ITEM_STATE_ACTIVE;
+ }
+
+ if ( m_rPanelDeck.GetActivePanel() == i_nItemIndex )
+ nItemFlags |= ITEM_STATE_ACTIVE;
+
+ if ( m_aFocusedItem == i_nItemIndex )
+ nItemFlags |= ITEM_STATE_FOCUSED;
+
+ if ( 0 == i_nItemIndex )
+ nItemFlags |= ITEM_POSITION_FIRST;
+
+ if ( m_rPanelDeck.GetPanelCount() - 1 == i_nItemIndex )
+ nItemFlags |= ITEM_POSITION_LAST;
+
+ return nItemFlags;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::DrawItem( const size_t i_nItemIndex, const Rectangle& i_rBoundaries ) const
+ {
+ const ItemDescriptor& rItem( m_aItems[ i_nItemIndex ] );
+ const ItemFlags nItemFlags( impl_getItemFlags( i_nItemIndex ) );
+
+ // the normalized bounding and content rect
+ const Rectangle aNormalizedContent( GetActualLogicalItemRect( rItem.GetCurrentRect() ) );
+ const Rectangle aNormalizedBounds( m_pRenderer->calculateDecorations( aNormalizedContent, nItemFlags ) );
+
+ // check whether the item actually overlaps with the painting area
+ if ( !i_rBoundaries.IsEmpty() )
+ {
+ const Rectangle aItemRect( GetActualLogicalItemRect( rItem.GetCurrentRect() ) );
+ if ( !aItemRect.IsOver( i_rBoundaries ) )
+ return;
+ }
+
+ m_rTabBar.SetUpdateMode( FALSE );
+
+ // the aligned bounding and content rect
+ const Rectangle aActualBounds = m_aNormalizer.getTransformed( aNormalizedBounds, m_eTabAlignment );
+ const Rectangle aActualContent = m_aNormalizer.getTransformed( aNormalizedContent, m_eTabAlignment );
+
+ // render item "background" layer
+ m_pRenderer->preRenderItem( aNormalizedContent, nItemFlags );
+
+ // copy from the virtual device to ourself
+ CopyFromRenderDevice( aNormalizedBounds );
+
+ // render the actual item content
+ impl_renderItemContent( rItem.pPanel, aActualContent, rItem.eContent );
+
+ // render item "foreground" layer
+ m_pRenderer->postRenderItem( m_rTabBar, aActualBounds, nItemFlags );
+
+ m_rTabBar.SetUpdateMode( TRUE );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::EnsureItemsCache()
+ {
+ if ( m_bItemsDirty == false )
+ {
+ DBG_CHECK( *this );
+ return;
+ }
+ impl_calcItemRects();
+ OSL_POSTCOND( m_bItemsDirty == false, "PanelTabBar_Impl::EnsureItemsCache: cache still dirty!" );
+ DBG_CHECK( *this );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::Relayout()
+ {
+ EnsureItemsCache();
+
+ const Size aOutputSize( m_rTabBar.GetOutputSizePixel() );
+ m_aNormalizer = NormalizedArea( Rectangle( Point(), aOutputSize ), IsVertical() );
+ const Size aLogicalOutputSize( m_aNormalizer.getReferenceSize() );
+
+ // forward actual output size to our render device
+ m_aRenderDevice.SetOutputSizePixel( aLogicalOutputSize );
+
+ // re-calculate the size of the scroll buttons and of the items
+ m_aGeometry.relayout( aLogicalOutputSize, m_aItems );
+
+ if ( m_aGeometry.getButtonBackRect().IsEmpty() )
+ {
+ m_aScrollBack.Hide();
+ }
+ else
+ {
+ const Rectangle aButtonBack( m_aNormalizer.getTransformed( m_aGeometry.getButtonBackRect(), m_eTabAlignment ) );
+ m_aScrollBack.SetPosSizePixel( aButtonBack.TopLeft(), aButtonBack.GetSize() );
+ m_aScrollBack.Show();
+ }
+
+ if ( m_aGeometry.getButtonForwardRect().IsEmpty() )
+ {
+ m_aScrollForward.Hide();
+ }
+ else
+ {
+ const Rectangle aButtonForward( m_aNormalizer.getTransformed( m_aGeometry.getButtonForwardRect(), m_eTabAlignment ) );
+ m_aScrollForward.SetPosSizePixel( aButtonForward.TopLeft(), aButtonForward.GetSize() );
+ m_aScrollForward.Show();
+ }
+
+ UpdateScrollButtons();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::boost::optional< size_t > PanelTabBar_Impl::FindItemForPoint( const Point& i_rPoint ) const
+ {
+ Point aPoint( IsVertical() ? i_rPoint.Y() : i_rPoint.X(), IsVertical() ? i_rPoint.X() : i_rPoint.Y() );
+
+ if ( !m_aGeometry.getItemsRect().IsInside( aPoint ) )
+ return ::boost::optional< size_t >();
+
+ size_t i=0;
+ for ( ItemDescriptors::const_iterator item = m_aItems.begin();
+ item != m_aItems.end();
+ ++item, ++i
+ )
+ {
+ Rectangle aItemRect( GetActualLogicalItemRect( item->GetCurrentRect() ) );
+ if ( aItemRect.IsInside( aPoint ) )
+ {
+ return ::boost::optional< size_t >( i );
+ }
+ }
+ return ::boost::optional< size_t >();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle PanelTabBar_Impl::GetItemScreenRect( const size_t i_nItemPos ) const
+ {
+ ENSURE_OR_RETURN( i_nItemPos < m_aItems.size(), "PanelTabBar_Impl::GetItemScreenRect: invalid item pos!", Rectangle() );
+ const ItemDescriptor& rItem( m_aItems[ i_nItemPos ] );
+ const Rectangle aItemRect( m_aNormalizer.getTransformed(
+ GetActualLogicalItemRect( rItem.GetCurrentRect() ),
+ m_eTabAlignment ) );
+
+ const Rectangle aTabBarRect( m_rTabBar.GetWindowExtentsRelative( NULL ) );
+ return Rectangle(
+ Point( aTabBarRect.Left() + aItemRect.Left(), aTabBarRect.Top() + aItemRect.Top() ),
+ aItemRect.GetSize()
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::FocusItem( const ::boost::optional< size_t >& i_rItemPos )
+ {
+ // reset old focus item
+ if ( !!m_aFocusedItem )
+ InvalidateItem( *m_aFocusedItem );
+ m_aFocusedItem.reset();
+
+ // mark the active icon as focused
+ if ( !!i_rItemPos )
+ {
+ m_aFocusedItem = i_rItemPos;
+ InvalidateItem( *m_aFocusedItem );
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IMPL_LINK( PanelTabBar_Impl, OnScroll, const PushButton*, i_pButton )
+ {
+ if ( i_pButton == &m_aScrollBack )
+ {
+ OSL_ENSURE( m_nScrollPosition > 0, "PanelTabBar_Impl::OnScroll: inconsistency!" );
+ --m_nScrollPosition;
+ m_rTabBar.Invalidate();
+ }
+ else if ( i_pButton == &m_aScrollForward )
+ {
+ OSL_ENSURE( m_nScrollPosition < m_aItems.size() - 1, "PanelTabBar_Impl::OnScroll: inconsistency!" );
+ ++m_nScrollPosition;
+ m_rTabBar.Invalidate();
+ }
+
+ UpdateScrollButtons();
+
+ return 0L;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle PanelTabBar_Impl::GetActualLogicalItemRect( const Rectangle& i_rLogicalItemRect ) const
+ {
+ // care for the offset imposed by our geometry, i.e. whether or not we have scroll buttons
+ Rectangle aItemRect( i_rLogicalItemRect );
+ aItemRect.Move( m_aGeometry.getItemsRect().Left() - m_aGeometry.getButtonBackRect().Left(), 0 );
+
+ // care for the current scroll position
+ OSL_ENSURE( m_nScrollPosition < m_aItems.size(), "GetActualLogicalItemRect: invalid scroll position!" );
+ if ( ( m_nScrollPosition > 0 ) && ( m_nScrollPosition < m_aItems.size() ) )
+ {
+ long nOffsetX = m_aItems[ m_nScrollPosition ].GetCurrentRect().Left() - m_aItems[ 0 ].GetCurrentRect().Left();
+ long nOffsetY = m_aItems[ m_nScrollPosition ].GetCurrentRect().Top() - m_aItems[ 0 ].GetCurrentRect().Top();
+ aItemRect.Move( -nOffsetX, -nOffsetY );
+ }
+
+ return aItemRect;
+ }
+
+ //==================================================================================================================
+ //= PanelTabBar_Impl
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
+ {
+ EnsureItemsCache();
+
+ if ( !!i_rOldActive )
+ InvalidateItem( *i_rOldActive, ITEM_STATE_ACTIVE );
+ if ( !!i_rNewActive )
+ InvalidateItem( *i_rNewActive );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
+ {
+ // not interested in
+ (void)i_rNewLayouter;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar_Impl::Dying()
+ {
+ // not interested in - the notifier is a member of this instance here, so we're dying ourself at the moment
+ }
+
+ //==================================================================================================================
+ //= PanelTabBar
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBar::PanelTabBar( Window& i_rParentWindow, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
+ :Control( &i_rParentWindow, 0 )
+ ,m_pImpl( new PanelTabBar_Impl( *this, i_rPanelDeck, i_eAlignment, i_eItemContent ) )
+ {
+ DBG_CHECK( *m_pImpl );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBar::~PanelTabBar()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ TabItemContent PanelTabBar::GetTabItemContent() const
+ {
+ return m_pImpl->m_aGeometry.getItemContent();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::SetTabItemContent( const TabItemContent& i_eItemContent )
+ {
+ m_pImpl->m_aGeometry.setItemContent( i_eItemContent );
+ m_pImpl->Relayout();
+ Invalidate();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IToolPanelDeck& PanelTabBar::GetPanelDeck() const
+ {
+ DBG_CHECK( *m_pImpl );
+ return m_pImpl->m_rPanelDeck;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Size PanelTabBar::GetOptimalSize( WindowSizeType i_eType ) const
+ {
+ m_pImpl->EnsureItemsCache();
+ Size aOptimalSize( m_pImpl->m_aGeometry.getOptimalSize( m_pImpl->m_aItems, i_eType == WINDOWSIZE_MINIMUM ) );
+ if ( m_pImpl->IsVertical() )
+ ::std::swap( aOptimalSize.Width(), aOptimalSize.Height() );
+ return aOptimalSize;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::Resize()
+ {
+ Control::Resize();
+ m_pImpl->Relayout();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::Paint( const Rectangle& i_rRect )
+ {
+ m_pImpl->EnsureItemsCache();
+
+ // background
+ const Rectangle aNormalizedPaintArea( m_pImpl->m_aNormalizer.getNormalized( i_rRect, m_pImpl->m_eTabAlignment ) );
+ m_pImpl->m_aRenderDevice.Push( PUSH_CLIPREGION );
+ m_pImpl->m_aRenderDevice.SetClipRegion( aNormalizedPaintArea );
+ m_pImpl->m_pRenderer->renderBackground();
+ m_pImpl->m_aRenderDevice.Pop();
+ m_pImpl->CopyFromRenderDevice( aNormalizedPaintArea );
+
+ // ensure the items really paint into their own playground only
+ ClipItemRegion aClipItems( *m_pImpl );
+
+ const Rectangle aLogicalPaintRect( m_pImpl->m_aNormalizer.getNormalized( i_rRect, m_pImpl->m_eTabAlignment ) );
+
+ const ::boost::optional< size_t > aActivePanel( m_pImpl->m_rPanelDeck.GetActivePanel() );
+ const ::boost::optional< size_t > aHoveredPanel( m_pImpl->m_aHoveredItem );
+
+ // items:
+ // 1. paint all non-active, non-hovered items
+ size_t i=0;
+ for ( ItemDescriptors::const_iterator item = m_pImpl->m_aItems.begin();
+ item != m_pImpl->m_aItems.end();
+ ++item, ++i
+ )
+ {
+ if ( i == aActivePanel )
+ continue;
+
+ if ( aHoveredPanel == i )
+ continue;
+
+ m_pImpl->DrawItem( i, aLogicalPaintRect );
+ }
+
+ // 2. paint the item which is hovered, /without/ the mouse button pressed down
+ if ( !!aHoveredPanel && !m_pImpl->m_bMouseButtonDown )
+ m_pImpl->DrawItem( *aHoveredPanel, aLogicalPaintRect );
+
+ // 3. paint the active item
+ if ( !!aActivePanel )
+ m_pImpl->DrawItem( *aActivePanel, aLogicalPaintRect );
+
+ // 4. paint the item which is hovered, /with/ the mouse button pressed down
+ if ( !!aHoveredPanel && m_pImpl->m_bMouseButtonDown )
+ m_pImpl->DrawItem( *aHoveredPanel, aLogicalPaintRect );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::MouseMove( const MouseEvent& i_rMouseEvent )
+ {
+ m_pImpl->EnsureItemsCache();
+
+ ::boost::optional< size_t > aOldItem( m_pImpl->m_aHoveredItem );
+ ::boost::optional< size_t > aNewItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) );
+
+ if ( i_rMouseEvent.IsLeaveWindow() )
+ aNewItem.reset();
+
+ if ( aOldItem != aNewItem )
+ {
+ if ( !!aOldItem )
+ m_pImpl->InvalidateItem( *aOldItem );
+
+ m_pImpl->m_aHoveredItem = aNewItem;
+
+ if ( !!aNewItem )
+ m_pImpl->InvalidateItem( *aNewItem );
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::MouseButtonDown( const MouseEvent& i_rMouseEvent )
+ {
+ Control::MouseButtonDown( i_rMouseEvent );
+
+ if ( !i_rMouseEvent.IsLeft() )
+ return;
+
+ m_pImpl->EnsureItemsCache();
+
+ ::boost::optional< size_t > aHitItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) );
+ if ( !aHitItem )
+ return;
+
+ CaptureMouse();
+ m_pImpl->m_bMouseButtonDown = true;
+
+ m_pImpl->InvalidateItem( *aHitItem );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::MouseButtonUp( const MouseEvent& i_rMouseEvent )
+ {
+ Control::MouseButtonUp( i_rMouseEvent );
+
+ if ( m_pImpl->m_bMouseButtonDown )
+ {
+ ::boost::optional< size_t > aHitItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) );
+ if ( !!aHitItem )
+ {
+ // re-draw that item now that we're not in mouse-down mode anymore
+ m_pImpl->InvalidateItem( *aHitItem );
+ // activate the respective panel
+ m_pImpl->m_rPanelDeck.ActivatePanel( *aHitItem );
+ }
+
+ OSL_ENSURE( IsMouseCaptured(), "PanelTabBar::MouseButtonUp: inconsistency!" );
+ if ( IsMouseCaptured() )
+ ReleaseMouse();
+ m_pImpl->m_bMouseButtonDown = false;
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::RequestHelp( const HelpEvent& i_rHelpEvent )
+ {
+ m_pImpl->EnsureItemsCache();
+
+ ::boost::optional< size_t > aHelpItem( m_pImpl->FindItemForPoint( ScreenToOutputPixel( i_rHelpEvent.GetMousePosPixel() ) ) );
+ if ( !aHelpItem )
+ return;
+
+ const ItemDescriptor& rItem( m_pImpl->m_aItems[ *aHelpItem ] );
+ if ( rItem.eContent != TABITEM_IMAGE_ONLY )
+ // if the text is displayed for the item, we do not need to show it as tooltip
+ return;
+
+ const ::rtl::OUString sItemText( rItem.pPanel->GetDisplayName() );
+ if ( i_rHelpEvent.GetMode() == HELPMODE_BALLOON )
+ Help::ShowBalloon( this, OutputToScreenPixel( rItem.GetCurrentRect().Center() ), rItem.GetCurrentRect(), sItemText );
+ else
+ Help::ShowQuickHelp( this, rItem.GetCurrentRect(), sItemText );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::GetFocus()
+ {
+ Control::GetFocus();
+ if ( !m_pImpl->m_aFocusedItem )
+ m_pImpl->FocusItem( m_pImpl->m_rPanelDeck.GetActivePanel() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::LoseFocus()
+ {
+ Control::LoseFocus();
+
+ if ( !!m_pImpl->m_aFocusedItem )
+ {
+ m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
+ }
+
+ m_pImpl->m_aFocusedItem.reset();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ class KeyInputHandler
+ {
+ public:
+ KeyInputHandler( Control& i_rControl, const KeyEvent& i_rKeyEvent )
+ :m_rControl( i_rControl )
+ ,m_rKeyEvent( i_rKeyEvent )
+ ,m_bHandled( false )
+ {
+ }
+
+ ~KeyInputHandler()
+ {
+ if ( !m_bHandled )
+ m_rControl.Control::KeyInput( m_rKeyEvent );
+ }
+
+ void setHandled()
+ {
+ m_bHandled = true;
+ }
+
+ private:
+ Control& m_rControl;
+ const KeyEvent& m_rKeyEvent;
+ bool m_bHandled;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::KeyInput( const KeyEvent& i_rKeyEvent )
+ {
+ KeyInputHandler aKeyInputHandler( *this, i_rKeyEvent );
+
+ const KeyCode& rKeyCode( i_rKeyEvent.GetKeyCode() );
+ if ( rKeyCode.GetModifier() != 0 )
+ // only interested in mere key presses
+ return;
+
+ // if there are less than 2 panels, we cannot travel them ...
+ const size_t nPanelCount( m_pImpl->m_rPanelDeck.GetPanelCount() );
+ if ( nPanelCount < 2 )
+ return;
+
+ OSL_PRECOND( !!m_pImpl->m_aFocusedItem, "PanelTabBar::KeyInput: we should have a focused item here!" );
+ // if we get KeyInput events, we should have the focus. In this case, m_aFocusedItem should not be empty,
+ // except if there are no panels, but then we bail out of this method here earlier ...
+
+ bool bFocusNext = false;
+ bool bFocusPrev = false;
+
+ switch ( rKeyCode.GetCode() )
+ {
+ case KEY_UP: bFocusPrev = true; break;
+ case KEY_DOWN: bFocusNext = true; break;
+ case KEY_LEFT:
+ if ( IsRTLEnabled() )
+ bFocusNext = true;
+ else
+ bFocusPrev = true;
+ break;
+ case KEY_RIGHT:
+ if ( IsRTLEnabled() )
+ bFocusPrev = true;
+ else
+ bFocusNext = true;
+ break;
+ case KEY_RETURN:
+ m_pImpl->m_rPanelDeck.ActivatePanel( *m_pImpl->m_aFocusedItem );
+ break;
+ }
+
+ if ( !bFocusNext && !bFocusPrev )
+ return;
+
+ m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
+ if ( bFocusNext )
+ {
+ m_pImpl->m_aFocusedItem.reset( ( *m_pImpl->m_aFocusedItem + 1 ) % nPanelCount );
+ }
+ else
+ {
+ m_pImpl->m_aFocusedItem.reset( ( *m_pImpl->m_aFocusedItem + nPanelCount - 1 ) % nPanelCount );
+ }
+ m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
+
+ // don't delegate to base class
+ aKeyInputHandler.setHandled();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::DataChanged( const DataChangedEvent& i_rDataChanedEvent )
+ {
+ Control::DataChanged( i_rDataChanedEvent );
+
+ if ( ( i_rDataChanedEvent.GetType() == DATACHANGED_SETTINGS )
+ && ( ( i_rDataChanedEvent.GetFlags() & SETTINGS_STYLE ) != 0 )
+ )
+ {
+ Invalidate();
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ bool PanelTabBar::IsVertical() const
+ {
+ return m_pImpl->IsVertical();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ PushButton& PanelTabBar::GetScrollButton( const bool i_bForward )
+ {
+ return i_bForward ? m_pImpl->m_aScrollForward : m_pImpl->m_aScrollBack;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::boost::optional< size_t > PanelTabBar::GetFocusedPanelItem() const
+ {
+ return m_pImpl->m_aFocusedItem;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::FocusPanelItem( const size_t i_nItemPos )
+ {
+ ENSURE_OR_RETURN_VOID( i_nItemPos < m_pImpl->m_rPanelDeck.GetPanelCount(), "PanelTabBar::FocusPanelItem: illegal item pos!" );
+
+ if ( !HasChildPathFocus() )
+ GrabFocus();
+
+ m_pImpl->FocusItem( i_nItemPos );
+ OSL_POSTCOND( !!m_pImpl->m_aFocusedItem, "PanelTabBar::FocusPanelItem: have the focus, but no focused item?" );
+ if ( !!m_pImpl->m_aFocusedItem )
+ m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
+ m_pImpl->m_aFocusedItem.reset( i_nItemPos );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle PanelTabBar::GetItemScreenRect( const size_t i_nItemPos ) const
+ {
+ return m_pImpl->GetItemScreenRect( i_nItemPos );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWindowPeer > PanelTabBar::GetComponentInterface( BOOL i_bCreate )
+ {
+ Reference< XWindowPeer > xWindowPeer( Control::GetComponentInterface( FALSE ) );
+ if ( !xWindowPeer.is() && i_bCreate )
+ {
+ xWindowPeer.set( new PanelTabBarPeer( *this ) );
+ SetComponentInterface( xWindowPeer );
+ }
+ return xWindowPeer;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/paneltabbarpeer.cxx b/svtools/source/toolpanel/paneltabbarpeer.cxx
new file mode 100644
index 000000000000..d8329109ffb4
--- /dev/null
+++ b/svtools/source/toolpanel/paneltabbarpeer.cxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "paneltabbarpeer.hxx"
+#include "svtools/toolpanel/paneltabbar.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/DisposedException.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ 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::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::accessibility::XAccessibleContext;
+ using ::com::sun::star::lang::DisposedException;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= PanelTabBarPeer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBarPeer::PanelTabBarPeer( PanelTabBar& i_rTabBar )
+ :VCLXWindow()
+ ,m_pTabBar( &i_rTabBar )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBarPeer::~PanelTabBarPeer()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessibleContext > PanelTabBarPeer::CreateAccessibleContext()
+ {
+ ::vos::OGuard aSolarGuard( GetMutex() );
+ if ( m_pTabBar == NULL )
+ throw DisposedException( ::rtl::OUString(), *this );
+
+
+
+ Window* pAccessibleParent( m_pTabBar->GetAccessibleParentWindow() );
+ ENSURE_OR_RETURN( pAccessibleParent != NULL, "no accessible parent => no accessible context", NULL );
+ Reference< XAccessible > xAccessibleParent( pAccessibleParent->GetAccessible(), UNO_SET_THROW );
+ return m_aAccessibleFactory.getFactory().createAccessibleToolPanelTabBar( xAccessibleParent, m_pTabBar->GetPanelDeck(), *m_pTabBar );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL PanelTabBarPeer::dispose() throw(RuntimeException)
+ {
+ {
+ ::vos::OGuard aSolarGuard( GetMutex() );
+ m_pTabBar = NULL;
+ }
+ VCLXWindow::dispose();
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/paneltabbarpeer.hxx b/svtools/source/toolpanel/paneltabbarpeer.hxx
new file mode 100644
index 000000000000..7c2e5188d994
--- /dev/null
+++ b/svtools/source/toolpanel/paneltabbarpeer.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 SVT_PANELTABBARPEER_HXX
+#define SVT_PANELTABBARPEER_HXX
+
+#include "svtaccessiblefactory.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <toolkit/awt/vclxwindow.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ class PanelTabBar;
+ //====================================================================
+ //= PanelTabBarPeer
+ //====================================================================
+ class PanelTabBarPeer : public VCLXWindow
+ {
+ public:
+ PanelTabBarPeer( PanelTabBar& i_rTabBar );
+
+ protected:
+ ~PanelTabBarPeer();
+
+ // VCLXWindow overridables
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > CreateAccessibleContext();
+
+ // XComponent
+ void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+
+ private:
+ AccessibleFactoryAccess m_aAccessibleFactory;
+ PanelTabBar* m_pTabBar;
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // SVT_PANELTABBARPEER_HXX
diff --git a/svtools/source/toolpanel/refbase.cxx b/svtools/source/toolpanel/refbase.cxx
new file mode 100644
index 000000000000..f41aa2d9bb9c
--- /dev/null
+++ b/svtools/source/toolpanel/refbase.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.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "svtools/toolpanel/refbase.hxx"
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= RefBase
+ //====================================================================
+ //--------------------------------------------------------------------
+ oslInterlockedCount SAL_CALL RefBase::acquire()
+ {
+ return osl_incrementInterlockedCount( &m_refCount );
+ }
+
+ //--------------------------------------------------------------------
+ oslInterlockedCount SAL_CALL RefBase::release()
+ {
+ oslInterlockedCount newCount = osl_decrementInterlockedCount( &m_refCount );
+ if ( 0 == newCount )
+ delete this;
+ return newCount;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/tabbargeometry.cxx b/svtools/source/toolpanel/tabbargeometry.cxx
new file mode 100644
index 000000000000..45c40cee6ef2
--- /dev/null
+++ b/svtools/source/toolpanel/tabbargeometry.cxx
@@ -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 "precompiled_svtools.hxx"
+
+#include "tabbargeometry.hxx"
+
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/numeric/ftools.hxx>
+
+#include <vcl/window.hxx>
+
+#include <algorithm>
+
+// the width (or height, depending on alignment) of the scroll buttons
+#define BUTTON_FLOW_WIDTH 20
+// the space between the scroll buttons and the items
+#define BUTTON_FLOW_SPACE 2
+// outer space to apply between the tab bar borders and any content. Note that those refer to a "normalized" geometry,
+// i.e. if the tab bar were aligned at the top
+#define OUTER_SPACE_LEFT 2
+#define OUTER_SPACE_TOP 4
+#define OUTER_SPACE_RIGHT 4
+#define OUTER_SPACE_BOTTOM 2
+
+// outer space to apply between the area for the items, and the actual items. They refer to a normalized geometry.
+#define ITEMS_INSET_LEFT 4
+#define ITEMS_INSET_TOP 3
+#define ITEMS_INSET_RIGHT 4
+#define ITEMS_INSET_BOTTOM 0
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= helper
+ //==================================================================================================================
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ static void lcl_transform( Rectangle& io_rRect, const ::basegfx::B2DHomMatrix& i_rTransformation )
+ {
+ ::basegfx::B2DRange aRect( io_rRect.Left(), io_rRect.Top(), io_rRect.Right(), io_rRect.Bottom() );
+ aRect.transform( i_rTransformation );
+ io_rRect.Left() = long( aRect.getMinX() );
+ io_rRect.Top() = long( aRect.getMinY() );
+ io_rRect.Right() = long( aRect.getMaxX() );
+ io_rRect.Bottom() = long( aRect.getMaxY() );
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ /** transforms the given, possible rotated playground,
+ */
+ void lcl_rotate( const Rectangle& i_rReference, Rectangle& io_rArea, const bool i_bRight )
+ {
+ // step 1: move the to-be-upper-left corner (left/bottom) of the rectangle to (0,0)
+ ::basegfx::B2DHomMatrix aTransformation;
+ aTransformation.translate(
+ i_bRight ? -i_rReference.Left() : -i_rReference.Right(),
+ i_bRight ? -i_rReference.Bottom() : -i_rReference.Top()
+ );
+
+ // step 2: rotate by -90 degrees
+ aTransformation.rotate( i_bRight ? +F_PI2 : -F_PI2 );
+ // note:
+ // on the screen, the ordinate goes top-down, while basegfx calculates in a system where the
+ // ordinate goes bottom-up; thus the "wrong" sign before F_PI2 here
+
+ // step 3: move back to original coordinates
+ aTransformation.translate( i_rReference.Left(), i_rReference.Top() );
+
+ // apply transformation
+ lcl_transform( io_rArea, aTransformation );
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void lcl_mirrorHorizontally( const Rectangle& i_rReferenceArea, Rectangle& io_rArea )
+ {
+ io_rArea.Left() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Left();
+ io_rArea.Right() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Right();
+ ::std::swap( io_rArea.Left(), io_rArea.Right() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void lcl_mirrorVertically( const Rectangle& i_rReferenceArea, Rectangle& io_rArea )
+ {
+ io_rArea.Top() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Top();
+ io_rArea.Bottom() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Bottom();
+ ::std::swap( io_rArea.Top(), io_rArea.Bottom() );
+ }
+
+ //==================================================================================================================
+ //= NormalizedArea
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ NormalizedArea::NormalizedArea()
+ :m_aReference()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ NormalizedArea::NormalizedArea( const Rectangle& i_rReference, const bool i_bIsVertical )
+ :m_aReference( i_bIsVertical ? Rectangle( i_rReference.TopLeft(), Size( i_rReference.GetHeight(), i_rReference.GetWidth() ) ) : i_rReference )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle NormalizedArea::getTransformed( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const
+ {
+ Rectangle aResult( i_rArea );
+
+ if ( ( i_eTargetAlignment == TABS_RIGHT )
+ || ( i_eTargetAlignment == TABS_LEFT )
+ )
+ {
+ lcl_rotate( m_aReference, aResult, true );
+
+ if ( i_eTargetAlignment == TABS_LEFT )
+ {
+ Rectangle aReference( m_aReference );
+ aReference.Transpose();
+ lcl_mirrorHorizontally( aReference, aResult );
+ }
+ }
+ else
+ if ( i_eTargetAlignment == TABS_BOTTOM )
+ {
+ lcl_mirrorVertically( m_aReference, aResult );
+ }
+
+ return aResult;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle NormalizedArea::getNormalized( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const
+ {
+ Rectangle aResult( i_rArea );
+
+ if ( ( i_eTargetAlignment == TABS_RIGHT )
+ || ( i_eTargetAlignment == TABS_LEFT )
+ )
+ {
+ Rectangle aReference( m_aReference );
+ lcl_rotate( m_aReference, aReference, true );
+
+ if ( i_eTargetAlignment == TABS_LEFT )
+ {
+ lcl_mirrorHorizontally( aReference, aResult );
+ }
+
+ lcl_rotate( aReference, aResult, false );
+ }
+ else
+ if ( i_eTargetAlignment == TABS_BOTTOM )
+ {
+ lcl_mirrorVertically( m_aReference, aResult );
+ }
+ return aResult;
+ }
+
+ //==================================================================================================================
+ //= TabBarGeometry
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ TabBarGeometry::TabBarGeometry( const TabItemContent i_eItemContent )
+ :m_eTabItemContent( i_eItemContent )
+ ,m_aItemsInset()
+ ,m_aButtonBackRect()
+ ,m_aItemsRect()
+ ,m_aButtonForwardRect()
+ {
+ m_aItemsInset.Left() = ITEMS_INSET_LEFT;
+ m_aItemsInset.Top() = ITEMS_INSET_TOP;
+ m_aItemsInset.Right() = ITEMS_INSET_RIGHT;
+ m_aItemsInset.Bottom() = ITEMS_INSET_BOTTOM;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ TabBarGeometry::~TabBarGeometry()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ bool TabBarGeometry::impl_fitItems( ItemDescriptors& io_rItems ) const
+ {
+ if ( io_rItems.empty() )
+ // nothing to do, "no items" perfectly fit into any space we have ...
+ return true;
+
+ // the available size
+ Size aOutputSize( getItemsRect().GetSize() );
+ // shrunk by the outer space
+ aOutputSize.Width() -= m_aItemsInset.Right();
+ aOutputSize.Height() -= m_aItemsInset.Bottom();
+ const Rectangle aFitInto( Point( 0, 0 ), aOutputSize );
+
+ TabItemContent eItemContent( getItemContent() );
+ if ( eItemContent == TABITEM_AUTO )
+ {
+ // the "content modes" to try
+ TabItemContent eTryThis[] =
+ {
+ TABITEM_IMAGE_ONLY, // assumed to have the smallest rects
+ TABITEM_TEXT_ONLY,
+ TABITEM_IMAGE_AND_TEXT // assumed to have the largest rects
+ };
+
+
+ // determine which of the different version fits
+ eItemContent = eTryThis[0];
+ size_t nTryIndex = 2;
+ while ( nTryIndex > 0 )
+ {
+ const Point aBottomRight( io_rItems.rbegin()->GetRect( eTryThis[ nTryIndex ] ).BottomRight() );
+ if ( aFitInto.IsInside( aBottomRight ) )
+ {
+ eItemContent = eTryThis[ nTryIndex ];
+ break;
+ }
+ --nTryIndex;
+ }
+ }
+
+ // propagate to the items
+ for ( ItemDescriptors::iterator item = io_rItems.begin();
+ item != io_rItems.end();
+ ++item
+ )
+ {
+ item->eContent = eItemContent;
+ }
+
+ const ItemDescriptor& rLastItem( *io_rItems.rbegin() );
+ const Point aLastItemBottomRight( rLastItem.GetCurrentRect().BottomRight() );
+ return aFitInto.Left() <= aLastItemBottomRight.X()
+ && aFitInto.Right() >= aLastItemBottomRight.X();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Size TabBarGeometry::getOptimalSize( ItemDescriptors& io_rItems, const bool i_bMinimalSize ) const
+ {
+ if ( io_rItems.empty() )
+ return Size(
+ m_aItemsInset.Left() + m_aItemsInset.Right(),
+ m_aItemsInset.Top() + m_aItemsInset.Bottom()
+ );
+
+ // the rect of the last item
+ const Rectangle& rLastItemRect( i_bMinimalSize ? io_rItems.rbegin()->aIconOnlyArea : io_rItems.rbegin()->aCompleteArea );
+ return Size(
+ rLastItemRect.Left() + 1 + m_aItemsInset.Right(),
+ rLastItemRect.Top() + 1 + rLastItemRect.Bottom() + m_aItemsInset.Bottom()
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void TabBarGeometry::relayout( const Size& i_rActualOutputSize, ItemDescriptors& io_rItems )
+ {
+ // assume all items fit
+ Point aButtonBackPos( OUTER_SPACE_LEFT, OUTER_SPACE_TOP );
+ m_aButtonBackRect = Rectangle( aButtonBackPos, Size( 1, 1 ) );
+ m_aButtonBackRect.SetEmpty();
+
+ Point aButtonForwardPos( i_rActualOutputSize.Width(), OUTER_SPACE_TOP );
+ m_aButtonForwardRect = Rectangle( aButtonForwardPos, Size( 1, 1 ) );
+ m_aButtonForwardRect.SetEmpty();
+
+ Point aItemsPos( OUTER_SPACE_LEFT, 0 );
+ Size aItemsSize( i_rActualOutputSize.Width() - OUTER_SPACE_LEFT - OUTER_SPACE_RIGHT, i_rActualOutputSize.Height() );
+ m_aItemsRect = Rectangle( aItemsPos, aItemsSize );
+
+ if ( !impl_fitItems( io_rItems ) )
+ {
+ // assumption was wrong, the items do not fit => calculate rects for the scroll buttons
+ const Size aButtonSize( BUTTON_FLOW_WIDTH, i_rActualOutputSize.Height() - OUTER_SPACE_TOP - OUTER_SPACE_BOTTOM );
+
+ aButtonBackPos = Point( OUTER_SPACE_LEFT, OUTER_SPACE_TOP );
+ m_aButtonBackRect = Rectangle( aButtonBackPos, aButtonSize );
+
+ aButtonForwardPos = Point( i_rActualOutputSize.Width() - BUTTON_FLOW_WIDTH - OUTER_SPACE_RIGHT, OUTER_SPACE_TOP );
+ m_aButtonForwardRect = Rectangle( aButtonForwardPos, aButtonSize );
+
+ aItemsPos.X() = aButtonBackPos.X() + aButtonSize.Width() + BUTTON_FLOW_SPACE;
+ aItemsSize.Width() = aButtonForwardPos.X() - BUTTON_FLOW_SPACE - aItemsPos.X();
+ m_aItemsRect = Rectangle( aItemsPos, aItemsSize );
+
+ // fit items, again. In the TABITEM_AUTO case, the smaller playground for the items might lead to another
+ // item content.
+ impl_fitItems( io_rItems );
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Point TabBarGeometry::getFirstItemPosition() const
+ {
+ return Point( m_aItemsInset.Left(), m_aItemsInset.Top() );
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/tabbargeometry.hxx b/svtools/source/toolpanel/tabbargeometry.hxx
new file mode 100644
index 000000000000..059d69a3e233
--- /dev/null
+++ b/svtools/source/toolpanel/tabbargeometry.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 TABBARGEOMETRY_HXX
+#define TABBARGEOMETRY_HXX
+
+#include "svtools/toolpanel/tabalignment.hxx"
+
+#include "tabitemdescriptor.hxx"
+
+#include <tools/gen.hxx>
+#include <tools/svborder.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= NormalizedArea
+ //==================================================================================================================
+ /** a rectangle which automatically translates between unrotated and rotated geometry.
+
+ It can be operated as if it were an unrotated area, but is able to provide corrdinates of rotated objects,
+ relative to its playground.
+ */
+ class NormalizedArea
+ {
+ public:
+ NormalizedArea();
+ NormalizedArea( const Rectangle& i_rReference, const bool i_bIsVertical );
+
+ /** transforms a rectangle, relative to our playground, into a coordinate system defined by the given alignment
+ @param i_rArea
+ the area which is to be transformed.
+ */
+ Rectangle getTransformed(
+ const Rectangle& i_rArea,
+ const TabAlignment i_eTargetAlignment
+ ) const;
+
+ /** normalizes an already transformed rectangle
+ @param i_rArea
+ the area which is to be normalized.
+ */
+ Rectangle getNormalized(
+ const Rectangle& i_rArea,
+ const TabAlignment i_eTargetAlignment
+ ) const;
+
+
+ Size getReferenceSize() const { return m_aReference.GetSize(); }
+ const Rectangle&
+ getReference() const { return m_aReference; }
+
+ private:
+ // the normalized reference area
+ Rectangle m_aReference;
+ };
+
+ //==================================================================================================================
+ //= TabBarGeometry
+ //==================================================================================================================
+ class TabBarGeometry_Impl;
+ class TabBarGeometry
+ {
+ public:
+ TabBarGeometry( const TabItemContent i_eItemContent );
+ ~TabBarGeometry();
+
+ // retrieves the rectangle to be occupied by the button for scrolling backward through the items
+ const Rectangle& getButtonBackRect() const { return m_aButtonBackRect; }
+ // retrieves the rectangle to be occupied by the items
+ const Rectangle& getItemsRect() const { return m_aItemsRect; }
+ // retrieves the rectangle to be occupied by the button for scrolling forward through the items
+ const Rectangle& getButtonForwardRect() const { return m_aButtonForwardRect; }
+
+ inline TabItemContent
+ getItemContent() const { return m_eTabItemContent; }
+ inline void setItemContent( const TabItemContent i_eItemContent ) { m_eTabItemContent = i_eItemContent; }
+
+ /** adjusts the sizes of the buttons and the item's playground, plus the sizes of the items
+ */
+ void relayout( const Size& i_rActualOutputSize, ItemDescriptors& io_rItems );
+
+ /** calculates the optimal size of the tab bar, depending on the item's sizes
+ */
+ Size getOptimalSize( ItemDescriptors& io_rItems, const bool i_bMinimalSize ) const;
+
+ /** retrieves the position where the first item should start, relative to the item rect
+ */
+ Point getFirstItemPosition() const;
+
+ private:
+ bool impl_fitItems( ItemDescriptors& io_rItems ) const;
+
+ private:
+ /// specifies the content to be displayed in the tab items
+ TabItemContent m_eTabItemContent;
+ /// specifies the inset to be used in the items area, depends on the actual alignment
+ SvBorder m_aItemsInset;
+ // the (logical) rectangle to be used for the "back" button, empty if the button is not needed
+ Rectangle m_aButtonBackRect;
+ // the (logical) rectangle to be used for the items
+ Rectangle m_aItemsRect;
+ // the (logical) rectangle to be used for the "forward" button, empty if the button is not needed
+ Rectangle m_aButtonForwardRect;
+ };
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
+
+#endif // TABBARGEOMETRY_HXX
diff --git a/svtools/source/toolpanel/tabitemdescriptor.hxx b/svtools/source/toolpanel/tabitemdescriptor.hxx
new file mode 100644
index 000000000000..8005816b0fe2
--- /dev/null
+++ b/svtools/source/toolpanel/tabitemdescriptor.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 TABITEMDESCRIPTOR_HXX
+#define TABITEMDESCRIPTOR_HXX
+
+#include "svtools/toolpanel/toolpanel.hxx"
+#include "svtools/toolpanel/tabitemcontent.hxx"
+
+#include <tools/gen.hxx>
+#include <osl/diagnose.h>
+
+#include <vector>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //==================================================================================================================
+ //= ItemDescriptor
+ //==================================================================================================================
+ struct ItemDescriptor
+ {
+ PToolPanel pPanel;
+ Rectangle aCompleteArea; // bounding area if the both text and icon are to be rendererd
+ Rectangle aIconOnlyArea; // bounding area if the icon is to be rendererd
+ Rectangle aTextOnlyArea; // bounding area if the text is to be rendererd
+ TabItemContent eContent;
+ // content to be used for this particular item. Might differ from item content which has been set
+ // up for the complete control, in case not the complete content fits into the available space.
+
+ ItemDescriptor()
+ :pPanel()
+ ,aCompleteArea()
+ ,aIconOnlyArea()
+ ,aTextOnlyArea()
+ ,eContent( TABITEM_IMAGE_AND_TEXT )
+ {
+ }
+
+ const Rectangle& GetRect( const TabItemContent i_eItemContent ) const
+ {
+ OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "ItemDescriptor::GetRect: illegal value!" );
+
+ return ( i_eItemContent == TABITEM_IMAGE_AND_TEXT )
+ ? aCompleteArea
+ : ( ( i_eItemContent == TABITEM_TEXT_ONLY )
+ ? aTextOnlyArea
+ : aIconOnlyArea
+ );
+ }
+
+ const Rectangle& GetCurrentRect() const
+ {
+ return GetRect( eContent );
+ }
+ };
+
+ typedef ::std::vector< ItemDescriptor > ItemDescriptors;
+
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // TABITEMDESCRIPTOR_HXX
diff --git a/svtools/source/toolpanel/tablayouter.cxx b/svtools/source/toolpanel/tablayouter.cxx
new file mode 100755
index 000000000000..f68bbc1bbd0f
--- /dev/null
+++ b/svtools/source/toolpanel/tablayouter.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_svtools.hxx"
+
+#include "svtools/toolpanel/tablayouter.hxx"
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+#include "svtools/toolpanel/paneltabbar.hxx"
+#include "svtaccessiblefactory.hxx"
+
+#include <tools/gen.hxx>
+#include <tools/diagnose_ex.h>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::accessibility::XAccessible;
+
+ //====================================================================
+ //= TabDeckLayouter_Data
+ //====================================================================
+ struct TabDeckLayouter_Data
+ {
+ TabAlignment eAlignment;
+ IToolPanelDeck& rPanels;
+ ::std::auto_ptr< PanelTabBar > pTabBar;
+ AccessibleFactoryAccess aAccessibleFactory;
+
+ TabDeckLayouter_Data( Window& i_rParent, IToolPanelDeck& i_rPanels,
+ const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
+ :eAlignment( i_eAlignment )
+ ,rPanels( i_rPanels )
+ ,pTabBar( new PanelTabBar( i_rParent, i_rPanels, i_eAlignment, i_eItemContent ) )
+ {
+ pTabBar->Show();
+ }
+ };
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ namespace
+ {
+ static bool lcl_isVerticalTabBar( const TabAlignment i_eAlignment )
+ {
+ return ( i_eAlignment == TABS_RIGHT )
+ || ( i_eAlignment == TABS_LEFT );
+ }
+
+ static bool lcl_checkDisposed( const TabDeckLayouter_Data& i_rData )
+ {
+ if ( !i_rData.pTabBar.get() )
+ {
+ OSL_ENSURE( false, "lcl_checkDisposed: already disposed!" );
+ return true;
+ }
+ return false;
+ }
+ }
+
+ //====================================================================
+ //= TabDeckLayouter
+ //====================================================================
+ //--------------------------------------------------------------------
+ TabDeckLayouter::TabDeckLayouter( Window& i_rParent, IToolPanelDeck& i_rPanels,
+ const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
+ :m_pData( new TabDeckLayouter_Data( i_rParent, i_rPanels, i_eAlignment, i_eItemContent ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ TabDeckLayouter::~TabDeckLayouter()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( TabDeckLayouter )
+
+ //--------------------------------------------------------------------
+ TabItemContent TabDeckLayouter::GetTabItemContent() const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return TABITEM_IMAGE_AND_TEXT;
+ return m_pData->pTabBar->GetTabItemContent();
+ }
+
+ //--------------------------------------------------------------------
+ void TabDeckLayouter::SetTabItemContent( const TabItemContent& i_eItemContent )
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return;
+ m_pData->pTabBar->SetTabItemContent( i_eItemContent );
+ }
+
+ //--------------------------------------------------------------------
+ TabAlignment TabDeckLayouter::GetTabAlignment() const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return TABS_RIGHT;
+ return m_pData->eAlignment;
+ }
+
+ //--------------------------------------------------------------------
+ ::boost::optional< size_t > TabDeckLayouter::GetFocusedPanelItem() const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return ::boost::optional< size_t >();
+ return m_pData->pTabBar->GetFocusedPanelItem();
+ }
+
+ //--------------------------------------------------------------------
+ void TabDeckLayouter::FocusPanelItem( const size_t i_nItemPos )
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return;
+ m_pData->pTabBar->FocusPanelItem( i_nItemPos );
+ }
+
+ //--------------------------------------------------------------------
+ bool TabDeckLayouter::IsPanelSelectorEnabled() const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return false;
+ return m_pData->pTabBar->IsEnabled();
+ }
+
+ //--------------------------------------------------------------------
+ bool TabDeckLayouter::IsPanelSelectorVisible() const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return false;
+ return m_pData->pTabBar->IsVisible();
+ }
+
+ //--------------------------------------------------------------------
+ Rectangle TabDeckLayouter::GetItemScreenRect( const size_t i_nItemPos ) const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return Rectangle();
+ return m_pData->pTabBar->GetItemScreenRect( i_nItemPos );
+ }
+
+ //--------------------------------------------------------------------
+ Rectangle TabDeckLayouter::Layout( const Rectangle& i_rDeckPlayground )
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return i_rDeckPlayground;
+
+ const Size aPreferredSize( m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_PREFERRED ) );
+ if ( lcl_isVerticalTabBar( m_pData->eAlignment ) )
+ {
+ Size aTabBarSize = ( aPreferredSize.Width() < i_rDeckPlayground.GetWidth() )
+ ? aPreferredSize
+ : m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM );
+ aTabBarSize.Height() = i_rDeckPlayground.GetHeight();
+
+ Rectangle aPanelRect( i_rDeckPlayground );
+ if ( m_pData->eAlignment == TABS_RIGHT )
+ {
+ aPanelRect.Right() -= aTabBarSize.Width();
+ Point aTabBarTopLeft( aPanelRect.TopRight() );
+ aTabBarTopLeft.X() += 1;
+ m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize );
+ }
+ else
+ {
+ m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize );
+ aPanelRect.Left() += aTabBarSize.Width();
+ }
+ if ( aPanelRect.Left() >= aPanelRect.Right() )
+ aPanelRect = Rectangle();
+
+ return aPanelRect;
+ }
+
+ Size aTabBarSize = ( aPreferredSize.Height() < i_rDeckPlayground.GetHeight() )
+ ? aPreferredSize
+ : m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM );
+ aTabBarSize.Width() = i_rDeckPlayground.GetWidth();
+
+ Rectangle aPanelRect( i_rDeckPlayground );
+ if ( m_pData->eAlignment == TABS_TOP )
+ {
+ m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize );
+ aPanelRect.Top() += aTabBarSize.Height();
+ }
+ else
+ {
+ aPanelRect.Bottom() -= aTabBarSize.Height();
+ Point aTabBarTopLeft( aPanelRect.BottomLeft() );
+ aTabBarTopLeft.Y() -= 1;
+ m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize );
+ }
+ if ( aPanelRect.Top() >= aPanelRect.Bottom() )
+ aPanelRect = Rectangle();
+
+ return aPanelRect;
+ }
+
+ //--------------------------------------------------------------------
+ void TabDeckLayouter::Destroy()
+ {
+ m_pData->pTabBar.reset();
+ }
+
+ //--------------------------------------------------------------------
+ void TabDeckLayouter::SetFocusToPanelSelector()
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return;
+ m_pData->pTabBar->GrabFocus();
+ }
+
+ //--------------------------------------------------------------------
+ size_t TabDeckLayouter::GetAccessibleChildCount() const
+ {
+ if ( lcl_checkDisposed( *m_pData ) )
+ return 0;
+
+ return 1;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XAccessible > TabDeckLayouter::GetAccessibleChild( const size_t i_nChildIndex, const Reference< XAccessible >& i_rParentAccessible )
+ {
+ (void)i_nChildIndex;
+ (void)i_rParentAccessible;
+ if ( lcl_checkDisposed( *m_pData ) )
+ return NULL;
+
+ return m_pData->pTabBar->GetAccessible( TRUE );
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/toolpanel.cxx b/svtools/source/toolpanel/toolpanel.cxx
new file mode 100644
index 000000000000..f7b999494563
--- /dev/null
+++ b/svtools/source/toolpanel/toolpanel.cxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "svtools/toolpanel/toolpanel.hxx"
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= ToolPanelBase
+ //====================================================================
+ //--------------------------------------------------------------------
+ ToolPanelBase::ToolPanelBase()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ToolPanelBase::~ToolPanelBase()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( ToolPanelBase )
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/toolpanel.src b/svtools/source/toolpanel/toolpanel.src
new file mode 100644
index 000000000000..5908a8fbcf98
--- /dev/null
+++ b/svtools/source/toolpanel/toolpanel.src
@@ -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 "svtools/svtools.hrc"
+
+String STR_SVT_TOOL_PANEL_BUTTON_FWD
+{
+ Text [ en-US ] = "Tab Panel Scroll Button, backward";
+};
+
+String STR_SVT_TOOL_PANEL_BUTTON_BACK
+{
+ Text [ en-US ] = "Tab Panel Scroll Button, forward";
+};
+
+Image IMG_TRIANGLE_RIGHT
+{
+ ImageBitmap = Bitmap { File = "triangle_right.png"; };
+};
+
+Image IMG_TRIANGLE_RIGHT_HC
+{
+ ImageBitmap = Bitmap { File = "triangle_right_hc.png"; };
+};
+
+Image IMG_TRIANGLE_DOWN
+{
+ ImageBitmap = Bitmap { File = "triangle_down.png"; };
+};
+
+Image IMG_TRIANGLE_DOWN_HC
+{
+ ImageBitmap = Bitmap { File = "plus.png"; } ;
+};
diff --git a/svtools/source/toolpanel/toolpanelcollection.cxx b/svtools/source/toolpanel/toolpanelcollection.cxx
new file mode 100644
index 000000000000..baefbd92400f
--- /dev/null
+++ b/svtools/source/toolpanel/toolpanelcollection.cxx
@@ -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.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "toolpanelcollection.hxx"
+#include "paneldecklisteners.hxx"
+
+#include <tools/diagnose_ex.h>
+
+#include <vector>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= ToolPanelCollection_Data
+ //====================================================================
+ struct ToolPanelCollection_Data
+ {
+ ::std::vector< PToolPanel > aPanels;
+ ::boost::optional< size_t > aActivePanel;
+ PanelDeckListeners aListeners;
+ };
+
+ //====================================================================
+ //= ToolPanelCollection
+ //====================================================================
+ //--------------------------------------------------------------------
+ ToolPanelCollection::ToolPanelCollection()
+ :m_pData( new ToolPanelCollection_Data )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ToolPanelCollection::~ToolPanelCollection()
+ {
+ m_pData->aListeners.Dying();
+ }
+
+ //--------------------------------------------------------------------
+ size_t ToolPanelCollection::GetPanelCount() const
+ {
+ return m_pData->aPanels.size();
+ }
+
+ //--------------------------------------------------------------------
+ ::boost::optional< size_t > ToolPanelCollection::GetActivePanel() const
+ {
+ return m_pData->aActivePanel;
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelCollection::ActivatePanel( const ::boost::optional< size_t >& i_rPanel )
+ {
+ if ( !!i_rPanel )
+ {
+ OSL_ENSURE( *i_rPanel < GetPanelCount(), "ToolPanelCollection::ActivatePanel: illegal panel no.!" );
+ if ( *i_rPanel >= GetPanelCount() )
+ return;
+ }
+
+ if ( m_pData->aActivePanel == i_rPanel )
+ return;
+
+ const ::boost::optional< size_t > aOldPanel( m_pData->aActivePanel );
+ m_pData->aActivePanel = i_rPanel;
+
+ // notify listeners
+ m_pData->aListeners.ActivePanelChanged( aOldPanel, m_pData->aActivePanel );
+ }
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelCollection::GetPanel( const size_t i_nPos ) const
+ {
+ OSL_ENSURE( i_nPos < m_pData->aPanels.size(), "ToolPanelCollection::GetPanel: illegal position!" );
+ if ( i_nPos >= m_pData->aPanels.size() )
+ return PToolPanel();
+ return m_pData->aPanels[ i_nPos ];
+ }
+
+ //--------------------------------------------------------------------
+ size_t ToolPanelCollection::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ OSL_ENSURE( i_pPanel.get(), "ToolPanelCollection::InsertPanel: illegal panel!" );
+ if ( !i_pPanel.get() )
+ return 0;
+
+ // insert
+ const size_t position = i_nPosition < m_pData->aPanels.size() ? i_nPosition : m_pData->aPanels.size();
+ m_pData->aPanels.insert( m_pData->aPanels.begin() + position, i_pPanel );
+
+ // update active panel
+ if ( !!m_pData->aActivePanel )
+ {
+ if ( i_nPosition <= *m_pData->aActivePanel )
+ ++*m_pData->aActivePanel;
+ }
+
+ // notifications
+ m_pData->aListeners.PanelInserted( i_pPanel, i_nPosition );
+
+ return position;
+ }
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelCollection::RemovePanel( const size_t i_nPosition )
+ {
+ OSL_ENSURE( i_nPosition < m_pData->aPanels.size(), "ToolPanelCollection::RemovePanel: illegal position!" );
+ if ( i_nPosition >= m_pData->aPanels.size() )
+ return NULL;
+
+ // if the active panel is going to be removed, activate another one (before the actual removal)
+ if ( m_pData->aActivePanel == i_nPosition )
+ {
+ const ::boost::optional< size_t > aOldActive( m_pData->aActivePanel );
+
+ if ( i_nPosition + 1 < GetPanelCount() )
+ {
+ ++*m_pData->aActivePanel;
+ }
+ else if ( i_nPosition > 0 )
+ {
+ --*m_pData->aActivePanel;
+ }
+ else
+ {
+ m_pData->aActivePanel.reset();
+ }
+
+ m_pData->aListeners.ActivePanelChanged( aOldActive, m_pData->aActivePanel );
+ }
+
+ // remember the removed panel for the aller
+ PToolPanel pRemovedPanel( m_pData->aPanels[ i_nPosition ] );
+
+ // actually remove
+ m_pData->aPanels.erase( m_pData->aPanels.begin() + i_nPosition );
+
+ if ( !!m_pData->aActivePanel )
+ {
+ if ( i_nPosition < *m_pData->aActivePanel )
+ {
+ --*m_pData->aActivePanel;
+ }
+ }
+
+ // notify removed panel
+ m_pData->aListeners.PanelRemoved( i_nPosition );
+
+ return pRemovedPanel;
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelCollection::AddListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_pData->aListeners.AddListener( i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelCollection::RemoveListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_pData->aListeners.RemoveListener( i_rListener );
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/toolpanelcollection.hxx b/svtools/source/toolpanel/toolpanelcollection.hxx
new file mode 100644
index 000000000000..2bdba38546c9
--- /dev/null
+++ b/svtools/source/toolpanel/toolpanelcollection.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 TOOLPANELCOLLECTION_HXX
+#define TOOLPANELCOLLECTION_HXX
+
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+
+#include <memory>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ struct ToolPanelCollection_Data;
+
+ //====================================================================
+ //= ToolPanelCollection
+ //====================================================================
+ class ToolPanelCollection : public IToolPanelDeck
+ {
+ public:
+ ToolPanelCollection();
+ ~ToolPanelCollection();
+
+ // IToolPanelDeck
+ virtual size_t GetPanelCount() const;
+ virtual PToolPanel GetPanel( const size_t i_nPos ) const;
+ virtual ::boost::optional< size_t >
+ GetActivePanel() const;
+ virtual void ActivatePanel( const ::boost::optional< size_t >& i_rPanel );
+ virtual size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition );
+ virtual PToolPanel RemovePanel( const size_t i_nPosition );
+ virtual void AddListener( IToolPanelDeckListener& i_rListener );
+ virtual void RemoveListener( IToolPanelDeckListener& i_rListener );
+
+ private:
+ ::std::auto_ptr< ToolPanelCollection_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // TOOLPANELCOLLECTION_HXX
diff --git a/svtools/source/toolpanel/toolpaneldeck.cxx b/svtools/source/toolpanel/toolpaneldeck.cxx
new file mode 100755
index 000000000000..e157090bbf0e
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldeck.cxx
@@ -0,0 +1,560 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_svtools.hxx"
+
+#include "dummypanel.hxx"
+#include "toolpanelcollection.hxx"
+#include "paneldecklisteners.hxx"
+#include "toolpaneldeckpeer.hxx"
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+#include "svtools/toolpanel/tablayouter.hxx"
+#include "svtools/toolpanel/drawerlayouter.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+#include <boost/optional.hpp>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::accessibility::XAccessible;
+ using ::com::sun::star::awt::XWindowPeer;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ /** === end UNO using === **/
+ namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole;
+
+ enum DeckAction
+ {
+ /// activates the first panel
+ ACTION_ACTIVATE_FIRST,
+ // activates the panel after the currently active panel
+ ACTION_ACTIVATE_NEXT,
+ // activates the panel before the currently active panel
+ ACTION_ACTIVATE_PREV,
+ // activates the last panel
+ ACTION_ACTIVATE_LAST,
+
+ // toggles the focus between the active panel and the panel selector
+ ACTION_TOGGLE_FOCUS,
+ };
+
+ //====================================================================
+ //= ToolPanelDeck_Impl
+ //====================================================================
+ class ToolPanelDeck_Impl : public IToolPanelDeckListener
+ {
+ public:
+ ToolPanelDeck_Impl( ToolPanelDeck& i_rDeck )
+ :m_rDeck( i_rDeck )
+ ,m_aPanelAnchor( &i_rDeck, WB_DIALOGCONTROL | WB_CHILDDLGCTRL )
+ ,m_aPanels()
+ ,m_pDummyPanel( new DummyPanel )
+ ,m_pLayouter()
+ ,m_bInDtor( false )
+ ,m_pAccessibleParent( NULL )
+ {
+ m_aPanels.AddListener( *this );
+ m_aPanelAnchor.Show();
+ m_aPanelAnchor.SetAccessibleRole( AccessibleRole::PANEL );
+ }
+
+ ~ToolPanelDeck_Impl()
+ {
+ m_bInDtor = true;
+ }
+
+ PDeckLayouter GetLayouter() const { return m_pLayouter; }
+ void SetLayouter( const PDeckLayouter& i_pNewLayouter );
+
+ Window& GetPanelWindowAnchor() { return m_aPanelAnchor; }
+ const Window& GetPanelWindowAnchor() const { return m_aPanelAnchor; }
+
+ bool IsDead() const { return m_bInDtor; }
+
+ /// notifies our listeners that we're going to die. Only to be called from with our anti-impl's destructor
+ void NotifyDying()
+ {
+ m_aPanels.RemoveListener( *this );
+ m_aListeners.Dying();
+ }
+
+ // IToolPanelDeck equivalents
+ size_t GetPanelCount() const;
+ PToolPanel GetPanel( const size_t i_nPos ) const;
+ ::boost::optional< size_t >
+ GetActivePanel() const;
+ void ActivatePanel( const ::boost::optional< size_t >& i_rPanel );
+ size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition );
+ PToolPanel RemovePanel( const size_t i_nPosition );
+ void AddListener( IToolPanelDeckListener& i_rListener );
+ void RemoveListener( IToolPanelDeckListener& i_rListener );
+
+ /// re-layouts everything
+ void LayoutAll() { ImplDoLayout(); }
+
+ void DoAction( const DeckAction i_eAction );
+
+ bool FocusActivePanel();
+
+ void SetAccessibleParentWindow( Window* i_pAccessibleParent );
+ Window* GetAccessibleParentWindow() const { return m_pAccessibleParent; }
+
+ protected:
+ // IToolPanelDeckListener
+ virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition );
+ virtual void PanelRemoved( const size_t i_nPosition );
+ virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
+ virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter );
+ virtual void Dying();
+
+ private:
+ void ImplDoLayout();
+ PToolPanel GetActiveOrDummyPanel_Impl();
+
+ private:
+ ToolPanelDeck& m_rDeck;
+ Window m_aPanelAnchor;
+ ToolPanelCollection m_aPanels;
+ PToolPanel m_pDummyPanel;
+ PanelDeckListeners m_aListeners;
+ PDeckLayouter m_pLayouter;
+ bool m_bInDtor;
+ Window* m_pAccessibleParent;
+ };
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelDeck_Impl::GetActiveOrDummyPanel_Impl()
+ {
+ ::boost::optional< size_t > aActivePanel( m_aPanels.GetActivePanel() );
+ if ( !aActivePanel )
+ return m_pDummyPanel;
+ return m_aPanels.GetPanel( *aActivePanel );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::SetLayouter( const PDeckLayouter& i_pNewLayouter )
+ {
+ ENSURE_OR_RETURN_VOID( i_pNewLayouter.get(), "invalid layouter" );
+
+ if ( m_pLayouter.get() )
+ m_pLayouter->Destroy();
+
+ m_pLayouter = i_pNewLayouter;
+
+ ImplDoLayout();
+
+ m_aListeners.LayouterChanged( m_pLayouter );
+ }
+
+ //--------------------------------------------------------------------
+ size_t ToolPanelDeck_Impl::GetPanelCount() const
+ {
+ return m_aPanels.GetPanelCount();
+ }
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelDeck_Impl::GetPanel( const size_t i_nPos ) const
+ {
+ return m_aPanels.GetPanel( i_nPos );
+ }
+
+ //--------------------------------------------------------------------
+ ::boost::optional< size_t > ToolPanelDeck_Impl::GetActivePanel() const
+ {
+ return m_aPanels.GetActivePanel();
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::ActivatePanel( const ::boost::optional< size_t >& i_rPanel )
+ {
+ m_aPanels.ActivatePanel( i_rPanel );
+ }
+
+ //--------------------------------------------------------------------
+ size_t ToolPanelDeck_Impl::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ return m_aPanels.InsertPanel( i_pPanel, i_nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelDeck_Impl::RemovePanel( const size_t i_nPosition )
+ {
+ return m_aPanels.RemovePanel( i_nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::ImplDoLayout()
+ {
+ const Rectangle aDeckPlayground( Point(), m_rDeck.GetOutputSizePixel() );
+
+ // ask the layouter what is left for our panel, and position the panel container window appropriately
+ Rectangle aPlaygroundArea( aDeckPlayground );
+ OSL_ENSURE( m_pLayouter.get(), "ToolPanelDeck_Impl::ImplDoLayout: no layouter!" );
+ if ( m_pLayouter.get() )
+ {
+ aPlaygroundArea = m_pLayouter->Layout( aDeckPlayground );
+ }
+ m_aPanelAnchor.SetPosSizePixel( aPlaygroundArea.TopLeft(), aPlaygroundArea.GetSize() );
+
+ // position the active panel
+ const PToolPanel pActive( GetActiveOrDummyPanel_Impl() );
+ pActive->SetSizePixel( m_aPanelAnchor.GetOutputSizePixel() );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::AddListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_aListeners.AddListener( i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::RemoveListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_aListeners.RemoveListener( i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::DoAction( const DeckAction i_eAction )
+ {
+ const size_t nPanelCount( m_aPanels.GetPanelCount() );
+ ::boost::optional< size_t > aActivatePanel;
+ ::boost::optional< size_t > aCurrentPanel( GetActivePanel() );
+
+ switch ( i_eAction )
+ {
+ case ACTION_ACTIVATE_FIRST:
+ if ( nPanelCount > 0 )
+ aActivatePanel = 0;
+ break;
+ case ACTION_ACTIVATE_PREV:
+ if ( !aCurrentPanel && ( nPanelCount > 0 ) )
+ aActivatePanel = nPanelCount - 1;
+ else
+ if ( !!aCurrentPanel && ( *aCurrentPanel > 0 ) )
+ aActivatePanel = *aCurrentPanel - 1;
+ break;
+ case ACTION_ACTIVATE_NEXT:
+ if ( !aCurrentPanel && ( nPanelCount > 0 ) )
+ aActivatePanel = 0;
+ else
+ if ( !!aCurrentPanel && ( *aCurrentPanel < nPanelCount - 1 ) )
+ aActivatePanel = *aCurrentPanel + 1;
+ break;
+ case ACTION_ACTIVATE_LAST:
+ if ( nPanelCount > 0 )
+ aActivatePanel = nPanelCount - 1;
+ break;
+ case ACTION_TOGGLE_FOCUS:
+ {
+ PToolPanel pActivePanel( GetActiveOrDummyPanel_Impl() );
+ if ( !m_aPanelAnchor.HasChildPathFocus() )
+ pActivePanel->GrabFocus();
+ else
+ GetLayouter()->SetFocusToPanelSelector();
+ }
+ break;
+ }
+
+ if ( !!aActivatePanel )
+ {
+ ActivatePanel( aActivatePanel );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool ToolPanelDeck_Impl::FocusActivePanel()
+ {
+ ::boost::optional< size_t > aActivePanel( m_aPanels.GetActivePanel() );
+ if ( !aActivePanel )
+ return false;
+
+ PToolPanel pActivePanel( m_aPanels.GetPanel( *aActivePanel ) );
+ pActivePanel->GrabFocus();
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ // multiplex to our own listeners
+ m_aListeners.PanelInserted( i_pPanel, i_nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::PanelRemoved( const size_t i_nPosition )
+ {
+ // multiplex to our own listeners
+ m_aListeners.PanelRemoved( i_nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
+ {
+ // hide the old panel
+ if ( !!i_rOldActive )
+ {
+ const PToolPanel pOldActive( m_aPanels.GetPanel( *i_rOldActive ) );
+ pOldActive->Deactivate();
+ }
+
+ // position and show the new panel
+ const PToolPanel pNewActive( !i_rNewActive ? m_pDummyPanel : m_aPanels.GetPanel( *i_rNewActive ) );
+ pNewActive->Activate( m_aPanelAnchor );
+ pNewActive->GrabFocus();
+
+ // resize the panel (cannot guarantee it has ever been resized before
+ pNewActive->SetSizePixel( m_aPanelAnchor.GetOutputSizePixel() );
+
+ // multiplex to our own listeners
+ m_aListeners.ActivePanelChanged( i_rOldActive, i_rNewActive );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
+ {
+ // not interested in
+ (void)i_rNewLayouter;
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::Dying()
+ {
+ // not interested in. Since the ToolPanelCollection is our member, this just means we ourself
+ // are dying, and we already sent this notification in our dtor.
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::SetAccessibleParentWindow( Window* i_pAccessibleParent )
+ {
+ m_pAccessibleParent = i_pAccessibleParent;
+ }
+
+ //====================================================================
+ //= ToolPanelDeck
+ //====================================================================
+ //--------------------------------------------------------------------
+ ToolPanelDeck::ToolPanelDeck( Window& i_rParent, const WinBits i_nStyle )
+ :Control( &i_rParent, i_nStyle )
+ ,m_pImpl( new ToolPanelDeck_Impl( *this ) )
+ {
+ // use a default layouter
+// SetLayouter( PDeckLayouter( new TabDeckLayouter( *this, *this, TABS_RIGHT, TABITEM_IMAGE_AND_TEXT ) ) );
+ SetLayouter( PDeckLayouter( new DrawerDeckLayouter( *this, *this ) ) );
+ }
+
+ //--------------------------------------------------------------------
+ ToolPanelDeck::~ToolPanelDeck()
+ {
+ m_pImpl->NotifyDying();
+ GetLayouter()->Destroy();
+
+ Hide();
+ for ( size_t i=0; i<GetPanelCount(); ++i )
+ {
+ PToolPanel pPanel( GetPanel( i ) );
+ pPanel->Dispose();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ size_t ToolPanelDeck::GetPanelCount() const
+ {
+ return m_pImpl->GetPanelCount();
+ }
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelDeck::GetPanel( const size_t i_nPos ) const
+ {
+ return m_pImpl->GetPanel( i_nPos );
+ }
+
+ //--------------------------------------------------------------------
+ ::boost::optional< size_t > ToolPanelDeck::GetActivePanel() const
+ {
+ return m_pImpl->GetActivePanel();
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::ActivatePanel( const ::boost::optional< size_t >& i_rPanel )
+ {
+ m_pImpl->ActivatePanel( i_rPanel );
+ }
+
+ //--------------------------------------------------------------------
+ size_t ToolPanelDeck::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ return m_pImpl->InsertPanel( i_pPanel, i_nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ PToolPanel ToolPanelDeck::RemovePanel( const size_t i_nPosition )
+ {
+ return m_pImpl->RemovePanel( i_nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ PDeckLayouter ToolPanelDeck::GetLayouter() const
+ {
+ return m_pImpl->GetLayouter();
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::SetLayouter( const PDeckLayouter& i_pNewLayouter )
+ {
+ return m_pImpl->SetLayouter( i_pNewLayouter );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::AddListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_pImpl->AddListener( i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::RemoveListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_pImpl->RemoveListener( i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ Window& ToolPanelDeck::GetPanelWindowAnchor()
+ {
+ return m_pImpl->GetPanelWindowAnchor();
+ }
+
+ //--------------------------------------------------------------------
+ const Window& ToolPanelDeck::GetPanelWindowAnchor() const
+ {
+ return m_pImpl->GetPanelWindowAnchor();
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::Resize()
+ {
+ Control::Resize();
+ m_pImpl->LayoutAll();
+ }
+
+ //--------------------------------------------------------------------
+ long ToolPanelDeck::Notify( NotifyEvent& i_rNotifyEvent )
+ {
+ bool bHandled = false;
+ if ( i_rNotifyEvent.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pEvent = i_rNotifyEvent.GetKeyEvent();
+ const KeyCode& rKeyCode = pEvent->GetKeyCode();
+ if ( rKeyCode.GetModifier() == KEY_MOD1 )
+ {
+ bHandled = true;
+ switch ( rKeyCode.GetCode() )
+ {
+ case KEY_HOME:
+ m_pImpl->DoAction( ACTION_ACTIVATE_FIRST );
+ break;
+ case KEY_PAGEUP:
+ m_pImpl->DoAction( ACTION_ACTIVATE_PREV );
+ break;
+ case KEY_PAGEDOWN:
+ m_pImpl->DoAction( ACTION_ACTIVATE_NEXT );
+ break;
+ case KEY_END:
+ m_pImpl->DoAction( ACTION_ACTIVATE_LAST );
+ break;
+ default:
+ bHandled = false;
+ break;
+ }
+ }
+ else if ( rKeyCode.GetModifier() == ( KEY_MOD1 | KEY_SHIFT ) )
+ {
+ if ( rKeyCode.GetCode() == KEY_E )
+ {
+ m_pImpl->DoAction( ACTION_TOGGLE_FOCUS );
+ bHandled = true;
+ }
+ }
+ }
+
+ if ( bHandled )
+ return 1;
+
+ return Control::Notify( i_rNotifyEvent );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::GetFocus()
+ {
+ Control::GetFocus();
+ if ( m_pImpl->IsDead() )
+ return;
+ if ( !m_pImpl->FocusActivePanel() )
+ {
+ PDeckLayouter pLayouter( GetLayouter() );
+ ENSURE_OR_RETURN_VOID( pLayouter.get(), "ToolPanelDeck::GetFocus: no layouter?!" );
+ pLayouter->SetFocusToPanelSelector();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::SetAccessibleParentWindow( Window* i_pAccessibleParent )
+ {
+ m_pImpl->SetAccessibleParentWindow( i_pAccessibleParent );
+ }
+
+ //--------------------------------------------------------------------
+ Window* ToolPanelDeck::GetAccessibleParentWindow() const
+ {
+ Window* pAccessibleParent( m_pImpl->GetAccessibleParentWindow() );
+ if ( !pAccessibleParent )
+ pAccessibleParent = Window::GetAccessibleParentWindow();
+ return pAccessibleParent;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XWindowPeer > ToolPanelDeck::GetComponentInterface( BOOL i_bCreate )
+ {
+ Reference< XWindowPeer > xWindowPeer( Control::GetComponentInterface( FALSE ) );
+ if ( !xWindowPeer.is() && i_bCreate )
+ {
+ xWindowPeer.set( new ToolPanelDeckPeer( *this ) );
+ SetComponentInterface( xWindowPeer );
+ }
+ return xWindowPeer;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/toolpaneldeckpeer.cxx b/svtools/source/toolpanel/toolpaneldeckpeer.cxx
new file mode 100755
index 000000000000..0a84a90b4fb3
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldeckpeer.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "toolpaneldeckpeer.hxx"
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/DisposedException.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ 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::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::accessibility::XAccessibleContext;
+ using ::com::sun::star::lang::DisposedException;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= ToolPanelDeckPeer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDeckPeer::ToolPanelDeckPeer( ToolPanelDeck& i_rDeck )
+ :VCLXWindow()
+ ,m_pDeck( &i_rDeck )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDeckPeer::~ToolPanelDeckPeer()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessibleContext > ToolPanelDeckPeer::CreateAccessibleContext()
+ {
+ ::vos::OGuard aSolarGuard( GetMutex() );
+ if ( m_pDeck == NULL )
+ throw DisposedException( ::rtl::OUString(), *this );
+
+ Window* pAccessibleParent( m_pDeck->GetAccessibleParentWindow() );
+ ENSURE_OR_RETURN( pAccessibleParent != NULL, "no accessible parent => no accessible context", NULL );
+ Reference< XAccessible > xAccessibleParent( pAccessibleParent->GetAccessible(), UNO_SET_THROW );
+ return m_aAccessibleFactory.getFactory().createAccessibleToolPanelDeck( xAccessibleParent, *m_pDeck );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL ToolPanelDeckPeer::dispose() throw(RuntimeException)
+ {
+ {
+ ::vos::OGuard aSolarGuard( GetMutex() );
+ m_pDeck = NULL;
+ }
+ VCLXWindow::dispose();
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldeckpeer.hxx b/svtools/source/toolpanel/toolpaneldeckpeer.hxx
new file mode 100755
index 000000000000..4b6607ecbd05
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldeckpeer.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 SVT_TOOLPANELDECKPEER_HXX
+#define SVT_TOOLPANELDECKPEER_HXX
+
+#include "svtaccessiblefactory.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <toolkit/awt/vclxwindow.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ class ToolPanelDeck;
+ //==================================================================================================================
+ //= ToolPanelDeckPeer
+ //==================================================================================================================
+ class ToolPanelDeckPeer : public VCLXWindow
+ {
+ public:
+ ToolPanelDeckPeer( ToolPanelDeck& i_rDeck );
+
+ protected:
+ ~ToolPanelDeckPeer();
+
+ // VCLXWindow overridables
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > CreateAccessibleContext();
+
+ // XComponent
+ void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+
+ private:
+ AccessibleFactoryAccess m_aAccessibleFactory;
+ ToolPanelDeck* m_pDeck;
+ };
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
+
+#endif // SVT_TOOLPANELDECKPEER_HXX
diff --git a/svtools/source/toolpanel/toolpaneldrawer.cxx b/svtools/source/toolpanel/toolpaneldrawer.cxx
new file mode 100644
index 000000000000..851556bc7874
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawer.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.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "toolpaneldrawer.hxx"
+#include "toolpaneldrawerpeer.hxx"
+#include "svtools/svtdata.hxx"
+#include "svtools/svtools.hrc"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+#include <vcl/lineinfo.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/vclevent.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::awt::XWindowPeer;
+ namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole;
+
+ static const int s_nIndentationWidth = 16;
+
+ //==================================================================================================================
+ //= DrawerVisualization
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerVisualization::DrawerVisualization( ToolPanelDrawer& i_rParent )
+ :Window( &i_rParent )
+ ,m_rDrawer( i_rParent )
+ {
+ SetMouseTransparent( TRUE );
+ Show();
+ SetAccessibleRole( AccessibleRole::LABEL );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerVisualization::~DrawerVisualization()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerVisualization::Paint( const Rectangle& i_rBoundingBox )
+ {
+ Window::Paint( i_rBoundingBox );
+ m_rDrawer.Paint();
+ }
+
+ //==================================================================================================================
+ //= ToolPanelDrawer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawer::ToolPanelDrawer( Window& i_rParent, const ::rtl::OUString& i_rTitle )
+ :Window( &i_rParent, WB_TABSTOP )
+ ,m_pPaintDevice( new VirtualDevice( *this ) )
+ ,m_aVisualization( *this )
+ ,m_bFocused( false )
+ ,m_bExpanded( false )
+ {
+ EnableMapMode( FALSE );
+ SetBackground( Wallpaper() );
+ SetPointer( POINTER_REFHAND );
+
+ SetAccessibleRole( AccessibleRole::LIST_ITEM );
+
+ SetText( i_rTitle );
+ SetAccessibleName( i_rTitle );
+ SetAccessibleDescription( i_rTitle );
+
+ m_aVisualization.SetAccessibleName( i_rTitle );
+ m_aVisualization.SetAccessibleDescription( i_rTitle );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawer::~ToolPanelDrawer()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ long ToolPanelDrawer::GetPreferredHeightPixel() const
+ {
+ Rectangle aTitleBarBox( impl_calcTitleBarBox( impl_calcTextBoundingBox() ) );
+ return aTitleBarBox.GetHeight();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::Paint()
+ {
+ m_pPaintDevice->SetMapMode( GetMapMode() );
+ m_pPaintDevice->SetOutputSize( GetOutputSizePixel() );
+ m_pPaintDevice->SetSettings( GetSettings() );
+ m_pPaintDevice->SetDrawMode( GetDrawMode() );
+
+ const Rectangle aTextBox( impl_calcTextBoundingBox() );
+ impl_paintBackground( impl_calcTitleBarBox( aTextBox ) );
+
+ Rectangle aFocusBox( impl_paintExpansionIndicator( aTextBox ) );
+
+ m_pPaintDevice->DrawText( aTextBox, GetText(), impl_getTextStyle() );
+
+ aFocusBox.Union( aTextBox );
+ aFocusBox.Left() += 2;
+ impl_paintFocusIndicator( aFocusBox );
+
+ m_aVisualization.DrawOutDev(
+ Point(), GetOutputSizePixel(),
+ Point(), GetOutputSizePixel(),
+ *m_pPaintDevice
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle ToolPanelDrawer::impl_paintExpansionIndicator( const Rectangle& i_rTextBox )
+ {
+ Rectangle aExpansionIndicatorArea;
+
+ Image aImage( impl_getExpansionIndicator() );
+ const int nHeight( aImage.GetSizePixel().Height() );
+ if ( nHeight > 0 )
+ {
+ Point aPosition(
+ 0,
+ i_rTextBox.Top() + ( GetTextHeight() - nHeight ) / 2
+ );
+ m_pPaintDevice->DrawImage( aPosition, aImage );
+
+ aExpansionIndicatorArea = Rectangle( aPosition, aImage.GetSizePixel() );
+ }
+
+ return aExpansionIndicatorArea;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Image ToolPanelDrawer::impl_getExpansionIndicator() const
+ {
+ const bool bHighContrastMode( GetSettings().GetStyleSettings().GetHighContrastMode() != 0 );
+ USHORT nResourceId = 0;
+ if ( m_bExpanded )
+ if ( bHighContrastMode )
+ nResourceId = IMG_TRIANGLE_DOWN_HC;
+ else
+ nResourceId = IMG_TRIANGLE_DOWN;
+ else
+ if ( bHighContrastMode )
+ nResourceId = IMG_TRIANGLE_RIGHT_HC;
+ else
+ nResourceId = IMG_TRIANGLE_RIGHT;
+ return Image( SvtResId( nResourceId ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ USHORT ToolPanelDrawer::impl_getTextStyle() const
+ {
+ const USHORT nBasicStyle = TEXT_DRAW_LEFT
+ | TEXT_DRAW_TOP
+ | TEXT_DRAW_WORDBREAK;
+
+ if ( IsEnabled() )
+ return nBasicStyle;
+
+ return nBasicStyle | TEXT_DRAW_DISABLE;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::impl_paintBackground( const Rectangle& i_rTitleBarBox )
+ {
+ m_pPaintDevice->SetFillColor( GetSettings().GetStyleSettings().GetDialogColor() );
+ m_pPaintDevice->DrawRect( i_rTitleBarBox );
+
+ m_pPaintDevice->SetFillColor();
+ m_pPaintDevice->SetLineColor( GetSettings().GetStyleSettings().GetLightColor() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.TopLeft(), i_rTitleBarBox.TopRight() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.TopLeft(), i_rTitleBarBox.BottomLeft() );
+
+ m_pPaintDevice->SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.BottomLeft(), i_rTitleBarBox.BottomRight() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.TopRight(), i_rTitleBarBox.BottomRight() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::impl_paintFocusIndicator( const Rectangle& i_rTextBox )
+ {
+ if ( m_bFocused )
+ {
+ const Rectangle aTextPixelBox( m_pPaintDevice->LogicToPixel( i_rTextBox ) );
+
+ m_pPaintDevice->EnableMapMode( FALSE );
+ m_pPaintDevice->SetFillColor();
+
+ Rectangle aBox( i_rTextBox );
+ aBox.Top() -= 1;
+ aBox.Bottom() += 1;
+
+ m_pPaintDevice->DrawRect( aTextPixelBox );
+
+ LineInfo aDottedStyle( LINE_DASH );
+ aDottedStyle.SetDashCount( 0 );
+ aDottedStyle.SetDotCount( 1 );
+ aDottedStyle.SetDotLen( 1 );
+ aDottedStyle.SetDistance( 1 );
+
+ m_pPaintDevice->SetLineColor( COL_BLACK );
+ m_pPaintDevice->DrawPolyLine( Polygon( aTextPixelBox ), aDottedStyle );
+ m_pPaintDevice->EnableMapMode( FALSE );
+ }
+ else
+ HideFocus();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::GetFocus()
+ {
+ m_bFocused = true;
+ Invalidate();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::LoseFocus()
+ {
+ m_bFocused = false;
+ Invalidate();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::Resize()
+ {
+ Window::Resize();
+ m_aVisualization.SetPosSizePixel( Point(), GetOutputSizePixel() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::MouseButtonDown( const MouseEvent& i_rMouseEvent )
+ {
+ // consume this event, and do not forward to the base class - it would sent a NotifyEvent, which in turn, when
+ // we live in a DockingWindow, would start undocking
+ (void)i_rMouseEvent;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::DataChanged( const DataChangedEvent& i_rEvent )
+ {
+ Window::DataChanged( i_rEvent );
+
+ switch ( i_rEvent.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ if ( ( i_rEvent.GetFlags() & SETTINGS_STYLE ) == 0 )
+ break;
+ SetSettings( Application::GetSettings() );
+ m_pPaintDevice.reset( new VirtualDevice( *this ) );
+
+ // fall through.
+
+ case DATACHANGED_FONTS:
+ case DATACHANGED_FONTSUBSTITUTION:
+ {
+ const StyleSettings& rStyleSettings( GetSettings().GetStyleSettings() );
+
+ // Font.
+ Font aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+
+ // Color.
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+
+ Invalidate();
+ }
+ break;
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWindowPeer > ToolPanelDrawer::GetComponentInterface( BOOL i_bCreate )
+ {
+ Reference< XWindowPeer > xWindowPeer( Window::GetComponentInterface( FALSE ) );
+ if ( !xWindowPeer.is() && i_bCreate )
+ {
+ xWindowPeer.set( new ToolPanelDrawerPeer() );
+ SetComponentInterface( xWindowPeer );
+ }
+ return xWindowPeer;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle ToolPanelDrawer::impl_calcTextBoundingBox() const
+ {
+ Font aFont( GetFont() );
+ if ( m_bExpanded )
+ aFont.SetWeight( m_bExpanded ? WEIGHT_BOLD : WEIGHT_NORMAL );
+ m_pPaintDevice->SetFont( aFont );
+
+ int nAvailableWidth = m_pPaintDevice->GetTextWidth( GetText() );
+
+ Rectangle aTextBox(
+ Point(),
+ Size(
+ nAvailableWidth,
+ GetSettings().GetStyleSettings().GetTitleHeight()
+ )
+ );
+ aTextBox.Top() += ( aTextBox.GetHeight() - GetTextHeight() ) / 2;
+ aTextBox.Left() += s_nIndentationWidth;
+ aTextBox.Right() -= 1;
+
+ aTextBox = m_pPaintDevice->GetTextRect( aTextBox, GetText(), impl_getTextStyle() );
+ return aTextBox;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle ToolPanelDrawer::impl_calcTitleBarBox( const Rectangle& i_rTextBox ) const
+ {
+ Rectangle aTitleBarBox( i_rTextBox );
+ aTitleBarBox.Bottom() += aTitleBarBox.Top();
+ aTitleBarBox.Top() = 0;
+ aTitleBarBox.Left() = 0;
+
+ const long nWidth = GetOutputSizePixel().Width();
+ if ( aTitleBarBox.GetWidth() < nWidth )
+ aTitleBarBox.Right() = nWidth - 1;
+
+ return aTitleBarBox;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::SetExpanded( const bool i_bExpanded )
+ {
+ if ( m_bExpanded != i_bExpanded )
+ {
+ m_bExpanded = i_bExpanded;
+ CallEventListeners( m_bExpanded ? VCLEVENT_ITEM_EXPANDED : VCLEVENT_ITEM_COLLAPSED );
+ Invalidate();
+ }
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldrawer.hxx b/svtools/source/toolpanel/toolpaneldrawer.hxx
new file mode 100644
index 000000000000..a465a0a6c9e1
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawer.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.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include <vcl/window.hxx>
+#include <vcl/virdev.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ class ToolPanelDrawer;
+ //==================================================================================================================
+ //= DrawerVisualization
+ //==================================================================================================================
+ /** serves a single purpose - let ZoomText read the drawers ...
+
+ Strange enough, ZoomText does not read the drawers when they get the focus (in none of the combinations
+ of AccessibleRoles I tried), except when it does have an AccessibleChild with the role LABEL. To "inject"
+ such a child into the A11Y hierarchy, we use this window here.
+
+ (We could also inject the A11Y component on the A11Y level only, but this would mean additional code. With
+ this approach here, VCL/toolkit will take care of creating and maintaining the A11Y component for us.)
+ */
+ class DrawerVisualization : public Window
+ {
+ public:
+ DrawerVisualization( ToolPanelDrawer& i_rParent );
+ ~DrawerVisualization();
+
+ protected:
+ // Window overridables
+ virtual void Paint( const Rectangle& i_rBoundingBox );
+
+ private:
+ ToolPanelDrawer& m_rDrawer;
+ };
+
+ //==================================================================================================================
+ //= ToolPanelDrawer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ class ToolPanelDrawer : public Window
+ {
+ public:
+ ToolPanelDrawer( Window& i_rParent, const ::rtl::OUString& i_rTitle );
+ ~ToolPanelDrawer();
+
+ long GetPreferredHeightPixel() const;
+ void SetExpanded( const bool i_bExpanded );
+ bool IsExpanded() const { return m_bExpanded; }
+
+ void Paint();
+
+ protected:
+ // Window overridables
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual void Resize();
+ virtual void DataChanged( const DataChangedEvent& i_rEvent );
+ virtual void MouseButtonDown( const MouseEvent& i_rMouseEvent );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
+ GetComponentInterface( BOOL i_bCreate );
+
+ private:
+ Rectangle impl_calcTextBoundingBox() const;
+ Rectangle impl_calcTitleBarBox( const Rectangle& i_rTextBox ) const;
+ void impl_paintBackground( const Rectangle& i_rTitleBarBox );
+ USHORT impl_getTextStyle() const;
+ void impl_paintFocusIndicator( const Rectangle& i_rTextBox );
+ Rectangle impl_paintExpansionIndicator( const Rectangle& i_rTextBox );
+ Image impl_getExpansionIndicator() const;
+
+ // don't expose SetText. Our text is used as AccessibleName/Desc, and those are not expected to change.
+ using Window::SetText;
+ using Window::Paint;
+
+ private:
+ ::std::auto_ptr< VirtualDevice > m_pPaintDevice;
+ DrawerVisualization m_aVisualization;
+ bool m_bFocused;
+ bool m_bExpanded;
+ };
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldrawerpeer.cxx b/svtools/source/toolpanel/toolpaneldrawerpeer.cxx
new file mode 100644
index 000000000000..959527330897
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawerpeer.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.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "toolpaneldrawerpeer.hxx"
+#include "toolpaneldrawer.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+#include <toolkit/awt/vclxaccessiblecomponent.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <vcl/vclevent.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ 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::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::accessibility::XAccessibleContext;
+ /** === end UNO using === **/
+ namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType;
+ namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
+
+ //==================================================================================================================
+ //= ToolPanelDrawerContext
+ //==================================================================================================================
+ class ToolPanelDrawerContext : public VCLXAccessibleComponent
+ {
+ public:
+ ToolPanelDrawerContext( VCLXWindow& i_rWindow )
+ :VCLXAccessibleComponent( &i_rWindow )
+ {
+ }
+
+ virtual void ProcessWindowEvent( const VclWindowEvent& i_rVclWindowEvent );
+ virtual void FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet );
+
+ protected:
+ ~ToolPanelDrawerContext()
+ {
+ }
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawerContext::ProcessWindowEvent( const VclWindowEvent& i_rVclWindowEvent )
+ {
+ VCLXAccessibleComponent::ProcessWindowEvent( i_rVclWindowEvent );
+
+ switch ( i_rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_ITEM_EXPANDED:
+ NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), makeAny( AccessibleStateType::EXPANDED ) );
+ break;
+ case VCLEVENT_ITEM_COLLAPSED:
+ NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, makeAny( AccessibleStateType::EXPANDED ), Any() );
+ break;
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawerContext::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet )
+ {
+ VCLXAccessibleComponent::FillAccessibleStateSet( i_rStateSet );
+ if ( !GetWindow() )
+ return;
+
+ i_rStateSet.AddState( AccessibleStateType::EXPANDABLE );
+ i_rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+
+ const ToolPanelDrawer* pDrawer( dynamic_cast< const ToolPanelDrawer* > ( GetWindow() ) );
+ ENSURE_OR_RETURN_VOID( pDrawer, "ToolPanelDrawerContext::FillAccessibleStateSet: illegal window!" );
+ if ( pDrawer->IsExpanded() )
+ i_rStateSet.AddState( AccessibleStateType::EXPANDED );
+
+ if ( pDrawer->HasChildPathFocus() )
+ i_rStateSet.AddState( AccessibleStateType::FOCUSED );
+ }
+
+ //==================================================================================================================
+ //= ToolPanelDrawerPeer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawerPeer::ToolPanelDrawerPeer()
+ :VCLXWindow()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawerPeer::~ToolPanelDrawerPeer()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessibleContext > ToolPanelDrawerPeer::CreateAccessibleContext()
+ {
+ ::vos::OGuard aSolarGuard( GetMutex() );
+ return new ToolPanelDrawerContext( *this );
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldrawerpeer.hxx b/svtools/source/toolpanel/toolpaneldrawerpeer.hxx
new file mode 100644
index 000000000000..5fcf0ac0ae7c
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawerpeer.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 SVT_TOOLPANELDRAWERPEER_HXX
+#define SVT_TOOLPANELDRAWERPEER_HXX
+
+#include <toolkit/awt/vclxwindow.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= ToolPanelDrawerPeer
+ //==================================================================================================================
+ class ToolPanelDrawerPeer : public VCLXWindow
+ {
+ public:
+ ToolPanelDrawerPeer();
+
+ protected:
+ ~ToolPanelDrawerPeer();
+
+ // VCLXWindow overridables
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > CreateAccessibleContext();
+ };
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
+
+#endif // SVT_TOOLPANELDRAWERPEER_HXX
diff --git a/svtools/source/uno/addrtempuno.cxx b/svtools/source/uno/addrtempuno.cxx
new file mode 100644
index 000000000000..2f25a8f2f9b2
--- /dev/null
+++ b/svtools/source/uno/addrtempuno.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include "svtools/genericunodialog.hxx"
+#ifndef _SVT_DOC_ADDRESSTEMPLATE_HXX_
+#include "addresstemplate.hxx"
+#endif
+#ifndef _CPPUHELPER_EXTRACT_HXX_
+#include <cppuhelper/extract.hxx>
+#endif
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/property.hxx>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+
+class SfxItemSet;
+class SfxItemPool;
+class SfxPoolItem;
+
+// .......................................................................
+namespace svt
+{
+// .......................................................................
+
+#define UNODIALOG_PROPERTY_ID_ALIASES 100
+#define UNODIALOG_PROPERTY_ALIASES "FieldMapping"
+
+ using namespace com::sun::star::uno;
+ using namespace com::sun::star::lang;
+ using namespace com::sun::star::util;
+ using namespace com::sun::star::beans;
+ using namespace com::sun::star::sdbc;
+
+ //=========================================================================
+ //= OAddressBookSourceDialogUno
+ //=========================================================================
+ typedef OGenericUnoDialog OAddressBookSourceDialogUnoBase;
+ class OAddressBookSourceDialogUno
+ :public OAddressBookSourceDialogUnoBase
+ ,public ::comphelper::OPropertyArrayUsageHelper< OAddressBookSourceDialogUno >
+ {
+ protected:
+ Sequence< AliasProgrammaticPair > m_aAliases;
+ Reference< XDataSource > m_xDataSource;
+ ::rtl::OUString m_sDataSourceName;
+ ::rtl::OUString m_sTable;
+
+ protected:
+ OAddressBookSourceDialogUno(const Reference< XMultiServiceFactory >& _rxORB);
+
+ public:
+ // XTypeProvider
+ virtual Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw(RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ virtual ::comphelper::StringSequence SAL_CALL getSupportedServiceNames() throw(RuntimeException);
+
+ // XServiceInfo - static methods
+ static Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( RuntimeException );
+ static ::rtl::OUString getImplementationName_Static(void) throw( RuntimeException );
+ static Reference< XInterface >
+ SAL_CALL Create(const Reference< com::sun::star::lang::XMultiServiceFactory >&);
+
+ // XPropertySet
+ virtual Reference< XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(RuntimeException);
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ protected:
+ // OGenericUnoDialog overridables
+ virtual Dialog* createDialog(Window* _pParent);
+
+ virtual void implInitialize(const com::sun::star::uno::Any& _rValue);
+
+ virtual void executedDialog(sal_Int16 _nExecutionResult);
+ };
+
+
+ //=========================================================================
+ //= OAddressBookSourceDialogUno
+ //=========================================================================
+ Reference< XInterface > SAL_CALL OAddressBookSourceDialogUno_CreateInstance( const Reference< XMultiServiceFactory >& _rxFactory)
+ {
+ return OAddressBookSourceDialogUno::Create(_rxFactory);
+ }
+
+ //-------------------------------------------------------------------------
+ OAddressBookSourceDialogUno::OAddressBookSourceDialogUno(const Reference< XMultiServiceFactory >& _rxORB)
+ :OGenericUnoDialog(_rxORB)
+ {
+ registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_ALIASES), UNODIALOG_PROPERTY_ID_ALIASES, PropertyAttribute::READONLY,
+ &m_aAliases, getCppuType(&m_aAliases));
+ }
+
+ //-------------------------------------------------------------------------
+ Sequence<sal_Int8> SAL_CALL OAddressBookSourceDialogUno::getImplementationId( ) throw(RuntimeException)
+ {
+ static ::cppu::OImplementationId aId;
+ return aId.getImplementationId();
+ }
+
+ //-------------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL OAddressBookSourceDialogUno::Create(const Reference< XMultiServiceFactory >& _rxFactory)
+ {
+ return *(new OAddressBookSourceDialogUno(_rxFactory));
+ }
+
+ //-------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OAddressBookSourceDialogUno::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+
+ //-------------------------------------------------------------------------
+ ::rtl::OUString OAddressBookSourceDialogUno::getImplementationName_Static() throw(RuntimeException)
+ {
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.svtools.OAddressBookSourceDialogUno");
+ }
+
+ //-------------------------------------------------------------------------
+ ::comphelper::StringSequence SAL_CALL OAddressBookSourceDialogUno::getSupportedServiceNames() throw(RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+
+ //-------------------------------------------------------------------------
+ ::comphelper::StringSequence OAddressBookSourceDialogUno::getSupportedServiceNames_Static() throw(RuntimeException)
+ {
+ ::comphelper::StringSequence aSupported(1);
+ aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.ui.AddressBookSourceDialog");
+ return aSupported;
+ }
+
+ //-------------------------------------------------------------------------
+ Reference<XPropertySetInfo> SAL_CALL OAddressBookSourceDialogUno::getPropertySetInfo() throw(RuntimeException)
+ {
+ Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+ }
+
+ //-------------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper& OAddressBookSourceDialogUno::getInfoHelper()
+ {
+ return *const_cast<OAddressBookSourceDialogUno*>(this)->getArrayHelper();
+ }
+
+ //------------------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper* OAddressBookSourceDialogUno::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+ }
+
+ //------------------------------------------------------------------------------
+ void OAddressBookSourceDialogUno::executedDialog(sal_Int16 _nExecutionResult)
+ {
+ OAddressBookSourceDialogUnoBase::executedDialog(_nExecutionResult);
+
+ if ( _nExecutionResult )
+ if ( m_pDialog )
+ static_cast< AddressBookSourceDialog* >( m_pDialog )->getFieldMapping( m_aAliases );
+ }
+
+ //------------------------------------------------------------------------------
+ void OAddressBookSourceDialogUno::implInitialize(const com::sun::star::uno::Any& _rValue)
+ {
+ PropertyValue aVal;
+ if (_rValue >>= aVal)
+ {
+ if (0 == aVal.Name.compareToAscii("DataSource"))
+ {
+#if OSL_DEBUG_LEVEL > 0
+ sal_Bool bSuccess =
+#endif
+ aVal.Value >>= m_xDataSource;
+ OSL_ENSURE( bSuccess, "OAddressBookSourceDialogUno::implInitialize: invalid type for DataSource!" );
+ return;
+ }
+
+ if (0 == aVal.Name.compareToAscii("DataSourceName"))
+ {
+#if OSL_DEBUG_LEVEL > 0
+ sal_Bool bSuccess =
+#endif
+ aVal.Value >>= m_sDataSourceName;
+ OSL_ENSURE( bSuccess, "OAddressBookSourceDialogUno::implInitialize: invalid type for DataSourceName!" );
+ return;
+ }
+
+ if (0 == aVal.Name.compareToAscii("Command"))
+ {
+#if OSL_DEBUG_LEVEL > 0
+ sal_Bool bSuccess =
+#endif
+ aVal.Value >>= m_sTable;
+ OSL_ENSURE( bSuccess, "OAddressBookSourceDialogUno::implInitialize: invalid type for Command!" );
+ return;
+ }
+ }
+
+ OAddressBookSourceDialogUnoBase::implInitialize( _rValue );
+ }
+
+ //------------------------------------------------------------------------------
+ Dialog* OAddressBookSourceDialogUno::createDialog(Window* _pParent)
+ {
+ if ( m_xDataSource.is() && m_sTable.getLength() )
+ return new AddressBookSourceDialog(_pParent, m_aContext.getLegacyServiceFactory(), m_xDataSource, m_sDataSourceName, m_sTable, m_aAliases );
+ else
+ return new AddressBookSourceDialog( _pParent, m_aContext.getLegacyServiceFactory() );
+ }
+
+// .......................................................................
+} // namespace svt
+// .......................................................................
+
diff --git a/svtools/source/uno/contextmenuhelper.cxx b/svtools/source/uno/contextmenuhelper.cxx
new file mode 100644
index 000000000000..9eb36cf18a45
--- /dev/null
+++ b/svtools/source/uno/contextmenuhelper.cxx
@@ -0,0 +1,687 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "contextmenuhelper.hxx"
+#include <svtools/menuoptions.hxx>
+#include <svtools/miscopt.hxx>
+
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include <osl/conditn.hxx>
+#include <cppuhelper/weak.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/image.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxmenu.hxx>
+
+using namespace ::com::sun::star;
+
+namespace svt
+{
+
+// internal helper class to retrieve status updates
+class StateEventHelper : public ::com::sun::star::frame::XStatusListener,
+ public ::cppu::OWeakObject
+{
+ public:
+ StateEventHelper( const uno::Reference< frame::XDispatchProvider >& xDispatchProvider,
+ const uno::Reference< util::XURLTransformer >& xURLTransformer,
+ const rtl::OUString& aCommandURL );
+ virtual ~StateEventHelper();
+
+ bool isCommandEnabled();
+
+ // XInterface
+ virtual uno::Any SAL_CALL queryInterface( const uno::Type& aType ) throw ( uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const lang::EventObject& Source) throw( uno::RuntimeException );
+
+ // XStatusListener
+ virtual void SAL_CALL statusChanged(const frame::FeatureStateEvent& Event) throw( uno::RuntimeException );
+
+ private:
+ StateEventHelper();
+ StateEventHelper( const StateEventHelper& );
+ StateEventHelper& operator=( const StateEventHelper& );
+
+ bool m_bCurrentCommandEnabled;
+ ::rtl::OUString m_aCommandURL;
+ uno::Reference< frame::XDispatchProvider > m_xDispatchProvider;
+ uno::Reference< util::XURLTransformer > m_xURLTransformer;
+ osl::Condition m_aCondition;
+};
+
+StateEventHelper::StateEventHelper(
+ const uno::Reference< frame::XDispatchProvider >& xDispatchProvider,
+ const uno::Reference< util::XURLTransformer >& xURLTransformer,
+ const rtl::OUString& rCommandURL ) :
+ m_bCurrentCommandEnabled( true ),
+ m_aCommandURL( rCommandURL ),
+ m_xDispatchProvider( xDispatchProvider ),
+ m_xURLTransformer( xURLTransformer )
+{
+ m_aCondition.reset();
+}
+
+StateEventHelper::~StateEventHelper()
+{}
+
+uno::Any SAL_CALL StateEventHelper::queryInterface(
+ const uno::Type& aType )
+throw ( uno::RuntimeException )
+{
+ uno::Any a = ::cppu::queryInterface(
+ aType,
+ SAL_STATIC_CAST( XStatusListener*, this ));
+
+ if( a.hasValue() )
+ return a;
+
+ return ::cppu::OWeakObject::queryInterface( aType );
+}
+
+void SAL_CALL StateEventHelper::acquire()
+throw ()
+{
+ ::cppu::OWeakObject::acquire();
+}
+
+void SAL_CALL StateEventHelper::release()
+throw ()
+{
+ ::cppu::OWeakObject::release();
+}
+
+void SAL_CALL StateEventHelper::disposing(
+ const lang::EventObject& )
+throw ( uno::RuntimeException )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_xDispatchProvider.clear();
+ m_xURLTransformer.clear();
+ m_aCondition.set();
+}
+
+void SAL_CALL StateEventHelper::statusChanged(
+ const frame::FeatureStateEvent& Event )
+throw ( uno::RuntimeException )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ m_bCurrentCommandEnabled = Event.IsEnabled;
+ m_aCondition.set();
+}
+
+bool StateEventHelper::isCommandEnabled()
+{
+ // Be sure that we cannot die during condition wait
+ uno::Reference< frame::XStatusListener > xSelf(
+ SAL_STATIC_CAST( frame::XStatusListener*, this ));
+
+ uno::Reference< frame::XDispatch > xDispatch;
+ util::URL aTargetURL;
+ {
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ if ( m_xDispatchProvider.is() && m_xURLTransformer.is() )
+ {
+ ::rtl::OUString aSelf( RTL_CONSTASCII_USTRINGPARAM( "_self" ));
+
+ aTargetURL.Complete = m_aCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ try
+ {
+ xDispatch = m_xDispatchProvider->queryDispatch( aTargetURL, aSelf, 0 );
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ bool bResult( false );
+ if ( xDispatch.is() )
+ {
+ try
+ {
+ // add/remove ourself to retrieve status by callback
+ xDispatch->addStatusListener( xSelf, aTargetURL );
+ xDispatch->removeStatusListener( xSelf, aTargetURL );
+
+ // wait for anwser
+ m_aCondition.wait();
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ bResult = m_bCurrentCommandEnabled;
+ }
+
+ return bResult;
+}
+
+/*************************************************************************/
+
+struct ExecuteInfo
+{
+ uno::Reference< frame::XDispatch > xDispatch;
+ util::URL aTargetURL;
+ uno::Sequence< beans::PropertyValue > aArgs;
+};
+
+static const PopupMenu* lcl_FindPopupFromItemId( const PopupMenu* pPopupMenu, sal_uInt16 nItemId )
+{
+ if ( pPopupMenu )
+ {
+ sal_uInt16 nCount = pPopupMenu->GetItemCount();
+ for ( sal_uInt16 i = 0; i < nCount; i++ )
+ {
+ sal_uInt16 nId = pPopupMenu->GetItemId( i );
+ if ( nId == nItemId )
+ return pPopupMenu;
+ else
+ {
+ const PopupMenu* pResult( 0 );
+
+ const PopupMenu* pSubPopup = pPopupMenu->GetPopupMenu( i );
+ if ( pPopupMenu )
+ pResult = lcl_FindPopupFromItemId( pSubPopup, nItemId );
+ if ( pResult != 0 )
+ return pResult;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static ::rtl::OUString lcl_GetItemCommandRecursive( const PopupMenu* pPopupMenu, sal_uInt16 nItemId )
+{
+ const PopupMenu* pPopup = lcl_FindPopupFromItemId( pPopupMenu, nItemId );
+ if ( pPopup )
+ return pPopup->GetItemCommand( nItemId );
+ else
+ return ::rtl::OUString();
+}
+
+/*************************************************************************/
+
+ContextMenuHelper::ContextMenuHelper(
+ const uno::Reference< frame::XFrame >& xFrame,
+ bool bAutoRefresh ) :
+ m_xWeakFrame( xFrame ),
+ m_aSelf( RTL_CONSTASCII_USTRINGPARAM( "_self" )),
+ m_bAutoRefresh( bAutoRefresh ),
+ m_bUICfgMgrAssociated( false )
+{
+}
+
+ContextMenuHelper::~ContextMenuHelper()
+{
+}
+
+void
+ContextMenuHelper::completeAndExecute(
+ const Point& aPos,
+ PopupMenu& rPopupMenu )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ associateUIConfigurationManagers();
+ completeMenuProperties( &rPopupMenu );
+ executePopupMenu( aPos, &rPopupMenu );
+ resetAssociations();
+}
+
+void
+ContextMenuHelper::completeAndExecute(
+ const Point& aPos,
+ const uno::Reference< awt::XPopupMenu >& xPopupMenu )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ VCLXMenu* pXMenu = VCLXMenu::GetImplementation( xPopupMenu );
+ if ( pXMenu )
+ {
+ PopupMenu* pPopupMenu = dynamic_cast< PopupMenu* >( pXMenu->GetMenu() );
+ // as dynamic_cast can return zero check pointer
+ if ( pPopupMenu )
+ {
+ associateUIConfigurationManagers();
+ completeMenuProperties( pPopupMenu );
+ executePopupMenu( aPos, pPopupMenu );
+ resetAssociations();
+ }
+ }
+}
+
+uno::Reference< awt::XPopupMenu >
+ContextMenuHelper::create(
+ const ::rtl::OUString& /*aPopupMenuResourceId*/ )
+{
+ // NOT IMPLEMENTED YET!
+ return uno::Reference< awt::XPopupMenu >();
+}
+
+bool
+ContextMenuHelper::createAndExecute(
+ const Point& /*aPos*/,
+ const ::rtl::OUString& /*aPopupMenuResourceId*/ )
+{
+ // NOT IMPLEMENTED YET!
+ return false;
+}
+
+// private member
+
+void
+ContextMenuHelper::executePopupMenu(
+ const Point& rPos,
+ PopupMenu* pMenu )
+{
+ if ( pMenu )
+ {
+ uno::Reference< frame::XFrame > xFrame( m_xWeakFrame );
+ if ( xFrame.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow() );
+ if ( xWindow.is() )
+ {
+ Window* pParent = VCLUnoHelper::GetWindow( xWindow );
+ sal_uInt16 nResult = pMenu->Execute( pParent, rPos );
+
+ if ( nResult > 0 )
+ {
+ ::rtl::OUString aCommand = lcl_GetItemCommandRecursive( pMenu, nResult );
+ if ( aCommand.getLength() > 0 )
+ dispatchCommand( xFrame, aCommand );
+ }
+ }
+ }
+ }
+}
+
+bool
+ContextMenuHelper::dispatchCommand(
+ const uno::Reference< ::frame::XFrame >& rFrame,
+ const ::rtl::OUString& aCommandURL )
+{
+ if ( !m_xURLTransformer.is() )
+ {
+ m_xURLTransformer = uno::Reference< util::XURLTransformer >(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.util.URLTransformer" ))),
+ uno::UNO_QUERY );
+ }
+
+ util::URL aTargetURL;
+ uno::Reference< frame::XDispatch > xDispatch;
+ if ( m_xURLTransformer.is() )
+ {
+ aTargetURL.Complete = aCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider(
+ rFrame, uno::UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ {
+ try
+ {
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, m_aSelf, 0 );
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ if ( xDispatch.is() )
+ {
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+ pExecuteInfo->xDispatch = xDispatch;
+ pExecuteInfo->aTargetURL = aTargetURL;
+ pExecuteInfo->aArgs = m_aDefaultArgs;
+
+ Application::PostUserEvent( STATIC_LINK(0, ContextMenuHelper , ExecuteHdl_Impl), pExecuteInfo );
+ return true;
+ }
+
+ return false;
+}
+
+// retrieves and stores references to our user-interface
+// configuration managers, like image manager, ui command
+// description manager.
+bool
+ContextMenuHelper::associateUIConfigurationManagers()
+{
+ uno::Reference< frame::XFrame > xFrame( m_xWeakFrame );
+ if ( !m_bUICfgMgrAssociated && xFrame.is() )
+ {
+ // clear current state
+ m_xDocImageMgr.clear();
+ m_xModuleImageMgr.clear();
+ m_xUICommandLabels.clear();
+
+ try
+ {
+ uno::Reference < frame::XController > xController;
+ uno::Reference < frame::XModel > xModel;
+ xController = xFrame->getController();
+ if ( xController.is() )
+ xModel = xController->getModel();
+
+ if ( xModel.is() )
+ {
+ // retrieve document image manager form model
+ uno::Reference< ui::XUIConfigurationManagerSupplier > xSupplier( xModel, uno::UNO_QUERY );
+ if ( xSupplier.is() )
+ {
+ uno::Reference< ui::XUIConfigurationManager > xDocUICfgMgr(
+ xSupplier->getUIConfigurationManager(), uno::UNO_QUERY );
+ m_xDocImageMgr = uno::Reference< ui::XImageManager >(
+ xDocUICfgMgr->getImageManager(), uno::UNO_QUERY );
+ }
+ }
+
+ uno::Reference< frame::XModuleManager > xModuleManager(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.ModuleManager" ))),
+ uno::UNO_QUERY );
+
+ uno::Reference< ui::XImageManager > xModuleImageManager;
+ rtl::OUString aModuleId;
+ if ( xModuleManager.is() )
+ {
+ // retrieve module image manager
+ aModuleId = xModuleManager->identify( xFrame );
+
+ uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ))),
+ uno::UNO_QUERY );
+ if ( xModuleCfgMgrSupplier.is() )
+ {
+ uno::Reference< ui::XUIConfigurationManager > xUICfgMgr(
+ xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleId ));
+ if ( xUICfgMgr.is() )
+ {
+ m_xModuleImageMgr = uno::Reference< ui::XImageManager >(
+ xUICfgMgr->getImageManager(), uno::UNO_QUERY );
+ }
+ }
+ }
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.UICommandDescription" ))),
+ uno::UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ uno::Any a = xNameAccess->getByName( aModuleId );
+ a >>= m_xUICommandLabels;
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ }
+ }
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ m_bUICfgMgrAssociated = true;
+ return false;
+ }
+ m_bUICfgMgrAssociated = true;
+ }
+
+ return true;
+}
+
+Image
+ContextMenuHelper::getImageFromCommandURL(
+ const ::rtl::OUString& aCmdURL,
+ bool bHiContrast ) const
+{
+ Image aImage;
+ sal_Int16 nImageType( ui::ImageType::COLOR_NORMAL|
+ ui::ImageType::SIZE_DEFAULT );
+ if ( bHiContrast )
+ nImageType |= ui::ImageType::COLOR_HIGHCONTRAST;
+
+ uno::Sequence< uno::Reference< graphic::XGraphic > > aGraphicSeq;
+ uno::Sequence< ::rtl::OUString > aImageCmdSeq( 1 );
+ aImageCmdSeq[0] = aCmdURL;
+
+ if ( m_xDocImageMgr.is() )
+ {
+ try
+ {
+ aGraphicSeq = m_xDocImageMgr->getImages( nImageType, aImageCmdSeq );
+ uno::Reference< graphic::XGraphic > xGraphic = aGraphicSeq[0];
+ aImage = Image( xGraphic );
+
+ if ( !!aImage )
+ return aImage;
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ if ( m_xModuleImageMgr.is() )
+ {
+ try
+ {
+ aGraphicSeq = m_xModuleImageMgr->getImages( nImageType, aImageCmdSeq );
+ uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic = aGraphicSeq[0];
+ aImage = Image( xGraphic );
+
+ if ( !!aImage )
+ return aImage;
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ return aImage;
+}
+
+rtl::OUString
+ContextMenuHelper::getLabelFromCommandURL(
+ const ::rtl::OUString& aCmdURL ) const
+{
+ ::rtl::OUString aLabel;
+
+ if ( m_xUICommandLabels.is() )
+ {
+ try
+ {
+ if ( aCmdURL.getLength() > 0 )
+ {
+ rtl::OUString aStr;
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ uno::Any a( m_xUICommandLabels->getByName( aCmdURL ));
+ if ( a >>= aPropSeq )
+ {
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAscii( "Label" ))
+ {
+ aPropSeq[i].Value >>= aStr;
+ break;
+ }
+ }
+ }
+ aLabel = aStr;
+ }
+ }
+ catch ( uno::RuntimeException& )
+ {
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ return aLabel;
+}
+
+void
+ContextMenuHelper::completeMenuProperties(
+ Menu* pMenu )
+{
+ // Retrieve some settings necessary to display complete context
+ // menu correctly.
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ bool bShowMenuImages( rSettings.GetUseImagesInMenus() );
+ bool bIsHiContrast( rSettings.GetHighContrastMode() );
+
+ if ( pMenu )
+ {
+ uno::Reference< frame::XFrame > xFrame( m_xWeakFrame );
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider( xFrame, uno::UNO_QUERY );
+
+ if ( !m_xURLTransformer.is() )
+ {
+ m_xURLTransformer = uno::Reference< util::XURLTransformer >(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.util.URLTransformer" ))),
+ uno::UNO_QUERY );
+ }
+
+ for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nId = pMenu->GetItemId( nPos );
+ PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nId );
+ if ( pPopupMenu )
+ completeMenuProperties( pPopupMenu );
+ if ( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
+ {
+ ::rtl::OUString aCmdURL( pMenu->GetItemCommand( nId ));
+
+ if ( bShowMenuImages )
+ {
+ Image aImage;
+ if ( aCmdURL.getLength() > 0 )
+ aImage = getImageFromCommandURL( aCmdURL, bIsHiContrast );
+ pMenu->SetItemImage( nId, aImage );
+ }
+ else
+ pMenu->SetItemImage( nId, Image() );
+
+ if ( pMenu->GetItemText( nId ).Len() == 0 )
+ {
+ ::rtl::OUString aLabel( getLabelFromCommandURL( aCmdURL ));
+ pMenu->SetItemText( nId, aLabel );
+ }
+
+ // Use helper to retrieve state of the command URL
+ StateEventHelper* pHelper = new StateEventHelper(
+ xDispatchProvider,
+ m_xURLTransformer,
+ aCmdURL );
+
+ uno::Reference< frame::XStatusListener > xHelper( pHelper );
+ pMenu->EnableItem( nId, pHelper->isCommandEnabled() );
+ }
+ }
+ }
+}
+
+
+IMPL_STATIC_LINK_NOINSTANCE( ContextMenuHelper, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ // Release solar mutex to prevent deadlocks with clipboard thread
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction while we are
+ // on the stack. Stack unwinding would access the destroyed context menu.
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ // Acquire solar mutex again
+ Application::AcquireSolarMutex( nRef );
+ delete pExecuteInfo;
+ return 0;
+}
+
+} // namespace svt
diff --git a/svtools/source/uno/framestatuslistener.cxx b/svtools/source/uno/framestatuslistener.cxx
new file mode 100644
index 000000000000..20176160b396
--- /dev/null
+++ b/svtools/source/uno/framestatuslistener.cxx
@@ -0,0 +1,444 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <framestatuslistener.hxx>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::cppu;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+namespace svt
+{
+
+FrameStatusListener::FrameStatusListener(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& xFrame ) :
+ OWeakObject()
+ , m_bInitialized( sal_True )
+ , m_bDisposed( sal_False )
+ , m_xFrame( xFrame )
+ , m_xServiceManager( rServiceManager )
+{
+}
+
+FrameStatusListener::~FrameStatusListener()
+{
+}
+
+Reference< XFrame > FrameStatusListener::getFrameInterface() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_xFrame;
+}
+
+Reference< XMultiServiceFactory > FrameStatusListener::getServiceManager() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_xServiceManager;
+}
+
+// XInterface
+Any SAL_CALL FrameStatusListener::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ static_cast< XComponent* >( this ),
+ static_cast< XFrameActionListener* >( this ),
+ static_cast< XStatusListener* >( this ),
+ static_cast< XEventListener* >( static_cast< XStatusListener* >( this )),
+ static_cast< XEventListener* >( static_cast< XFrameActionListener* >( this )));
+
+ if ( a.hasValue() )
+ return a;
+
+ return OWeakObject::queryInterface( rType );
+}
+
+void SAL_CALL FrameStatusListener::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL FrameStatusListener::release() throw ()
+{
+ OWeakObject::release();
+}
+
+// XComponent
+void SAL_CALL FrameStatusListener::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ try
+ {
+ Reference< XDispatch > xDispatch( pIter->second );
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ ++pIter;
+ }
+
+ m_bDisposed = sal_True;
+}
+
+void SAL_CALL FrameStatusListener::addEventListener( const Reference< XEventListener >& )
+throw ( RuntimeException )
+{
+ // helper class for status updates - no need to support listener
+}
+
+void SAL_CALL FrameStatusListener::removeEventListener( const Reference< XEventListener >& )
+throw ( RuntimeException )
+{
+ // helper class for status updates - no need to support listener
+}
+
+// XEventListener
+void SAL_CALL FrameStatusListener::disposing( const EventObject& Source )
+throw ( RuntimeException )
+{
+ Reference< XInterface > xSource( Source.Source );
+
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ // Compare references and release dispatch references if they are equal.
+ Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
+ if ( xSource == xIfac )
+ pIter->second.clear();
+ }
+
+ Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
+ if ( xIfac == xSource )
+ m_xFrame.clear();
+}
+
+// XStatusListener
+void SAL_CALL FrameStatusListener::statusChanged( const FeatureStateEvent& )
+throw ( RuntimeException )
+{
+ // must be implemented by sub class
+}
+
+void FrameStatusListener::frameAction( const FrameActionEvent& Action )
+throw ( RuntimeException )
+{
+ if ( Action.Action == FrameAction_CONTEXT_CHANGED )
+ bindListener();
+}
+
+void FrameStatusListener::addStatusListener( const rtl::OUString& aCommandURL )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+
+ // Already in the list of status listener. Do nothing.
+ if ( pIter != m_aListenerMap.end() )
+ return;
+
+ // Check if we are already initialized. Implementation starts adding itself as status listener when
+ // intialize is called.
+ if ( !m_bInitialized )
+ {
+ // Put into the hash_map of status listener. Will be activated when initialized is called
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
+ return;
+ }
+ else
+ {
+ // Add status listener directly as intialize has already been called.
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
+ if ( aIter != m_aListenerMap.end() )
+ {
+ Reference< XDispatch > xOldDispatch( aIter->second );
+ aIter->second = xDispatch;
+
+ try
+ {
+ if ( xOldDispatch.is() )
+ xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
+ }
+ }
+ }
+
+ // Call without locked mutex as we are called back from dispatch implementation
+ try
+ {
+ if ( xDispatch.is() )
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+void FrameStatusListener::removeStatusListener( const rtl::OUString& aCommandURL )
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XDispatch > xDispatch( pIter->second );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ m_aListenerMap.erase( pIter );
+
+ try
+ {
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void FrameStatusListener::bindListener()
+{
+ std::vector< Listener > aDispatchVector;
+ Reference< XStatusListener > xStatusListener;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Collect all registered command URL's and store them temporary
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch( pIter->second );
+ if ( xDispatch.is() )
+ {
+ // We already have a dispatch object => we have to requery.
+ // Release old dispatch object and remove it as listener
+ try
+ {
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ // Query for dispatch object. Old dispatch will be released with this, too.
+ try
+ {
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ }
+ catch ( Exception& )
+ {
+ }
+ pIter->second = xDispatch;
+
+ Listener aListener( aTargetURL, xDispatch );
+ aDispatchVector.push_back( aListener );
+ ++pIter;
+ }
+ }
+ }
+
+ // Call without locked mutex as we are called back from dispatch implementation
+ if ( xStatusListener.is() )
+ {
+ try
+ {
+ for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
+ {
+ Listener& rListener = aDispatchVector[i];
+ if ( rListener.xDispatch.is() )
+ rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void FrameStatusListener::unbindListener()
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Collect all registered command URL's and store them temporary
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch( pIter->second );
+ if ( xDispatch.is() )
+ {
+ // We already have a dispatch object => we have to requery.
+ // Release old dispatch object and remove it as listener
+ try
+ {
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ pIter->second.clear();
+ ++pIter;
+ }
+ }
+}
+
+void FrameStatusListener::updateStatus( const rtl::OUString aCommandURL )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Try to find a dispatch object for the requested command URL
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 );
+ }
+ }
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ {
+ // Catch exception as we release our mutex, it is possible that someone else
+ // has already disposed this instance!
+ // Add/remove status listener to get a update status information from the
+ // requested command.
+ try
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+} // svt
diff --git a/svtools/source/uno/generictoolboxcontroller.cxx b/svtools/source/uno/generictoolboxcontroller.cxx
new file mode 100644
index 000000000000..a58d9b784cca
--- /dev/null
+++ b/svtools/source/uno/generictoolboxcontroller.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/generictoolboxcontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+
+namespace svt
+{
+
+struct ExecuteInfo
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatch;
+ ::com::sun::star::util::URL aTargetURL;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
+};
+
+GenericToolboxController::GenericToolboxController( const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbox,
+ USHORT nID,
+ const ::rtl::OUString& aCommand ) :
+ svt::ToolboxController( rServiceManager, rFrame, aCommand )
+ , m_pToolbox( pToolbox )
+ , m_nID( nID )
+{
+ // Initialization is done through ctor
+ m_bInitialized = sal_True;
+
+ // insert main command to our listener map
+ if ( m_aCommandURL.getLength() )
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommand, Reference< XDispatch >() ));
+}
+
+GenericToolboxController::~GenericToolboxController()
+{
+}
+
+void SAL_CALL GenericToolboxController::dispose()
+throw ( RuntimeException )
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ svt::ToolboxController::dispose();
+
+ m_pToolbox = 0;
+ m_nID = 0;
+}
+
+void SAL_CALL GenericToolboxController::execute( sal_Int16 /*KeyModifier*/ )
+throw ( RuntimeException )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XURLTransformer > xURLTransformer;
+ ::rtl::OUString aCommandURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+ xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+
+ aCommandURL = m_aCommandURL;
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ xDispatch = pIter->second;
+ }
+ }
+
+ if ( xDispatch.is() && xURLTransformer.is() )
+ {
+ com::sun::star::util::URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ // Execute dispatch asynchronously
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+ pExecuteInfo->xDispatch = xDispatch;
+ pExecuteInfo->aTargetURL = aTargetURL;
+ pExecuteInfo->aArgs = aArgs;
+ Application::PostUserEvent( STATIC_LINK(0, GenericToolboxController , ExecuteHdl_Impl), pExecuteInfo );
+ }
+}
+
+void GenericToolboxController::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ return;
+
+ if ( m_pToolbox )
+ {
+ m_pToolbox->EnableItem( m_nID, Event.IsEnabled );
+
+ USHORT nItemBits = m_pToolbox->GetItemBits( m_nID );
+ nItemBits &= ~TIB_CHECKABLE;
+ TriState eTri = STATE_NOCHECK;
+
+ sal_Bool bValue = sal_Bool();
+ rtl::OUString aStrValue;
+ ItemStatus aItemState;
+
+ if ( Event.State >>= bValue )
+ {
+ // Boolean, treat it as checked/unchecked
+ m_pToolbox->SetItemBits( m_nID, nItemBits );
+ m_pToolbox->CheckItem( m_nID, bValue );
+ if ( bValue )
+ eTri = STATE_CHECK;
+ nItemBits |= TIB_CHECKABLE;
+ }
+ else if ( Event.State >>= aStrValue )
+ {
+ m_pToolbox->SetItemText( m_nID, aStrValue );
+ }
+ else if ( Event.State >>= aItemState )
+ {
+ eTri = STATE_DONTKNOW;
+ nItemBits |= TIB_CHECKABLE;
+ }
+
+ m_pToolbox->SetItemState( m_nID, eTri );
+ m_pToolbox->SetItemBits( m_nID, nItemBits );
+ }
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( GenericToolboxController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
+ }
+ catch ( Exception& )
+ {
+ }
+ delete pExecuteInfo;
+ return 0;
+}
+
+} // namespace
diff --git a/svtools/source/uno/genericunodialog.cxx b/svtools/source/uno/genericunodialog.cxx
new file mode 100644
index 000000000000..a7ece1acc369
--- /dev/null
+++ b/svtools/source/uno/genericunodialog.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_svtools.hxx"
+
+#include "svtools/genericunodialog.hxx"
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
+
+#include <toolkit/awt/vclxwindow.hxx>
+#include <cppuhelper/extract.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/property.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <vcl/msgbox.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::comphelper;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ucb;
+
+//.........................................................................
+namespace svt
+{
+//.........................................................................
+
+//=========================================================================
+//-------------------------------------------------------------------------
+OGenericUnoDialog::OGenericUnoDialog(const Reference< XMultiServiceFactory >& _rxORB)
+ :OPropertyContainer(GetBroadcastHelper())
+ ,m_pDialog(NULL)
+ ,m_bExecuting(sal_False)
+ ,m_bCanceled(sal_False)
+ ,m_bTitleAmbiguous(sal_True)
+ ,m_bInitialized( false )
+ ,m_bNeedInitialization( false )
+ ,m_aContext( _rxORB )
+{
+ registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT,
+ &m_sTitle, getCppuType(&m_sTitle));
+ registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT,
+ &m_xParent, getCppuType(&m_xParent));
+}
+
+//-------------------------------------------------------------------------
+OGenericUnoDialog::OGenericUnoDialog(const Reference< XComponentContext >& _rxContext)
+ :OPropertyContainer(GetBroadcastHelper())
+ ,m_pDialog(NULL)
+ ,m_bExecuting(sal_False)
+ ,m_bCanceled(sal_False)
+ ,m_bTitleAmbiguous(sal_True)
+ ,m_bInitialized( false )
+ ,m_bNeedInitialization( false )
+ ,m_aContext(_rxContext)
+{
+ registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT,
+ &m_sTitle, getCppuType(&m_sTitle));
+ registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT,
+ &m_xParent, getCppuType(&m_xParent));
+}
+
+//-------------------------------------------------------------------------
+OGenericUnoDialog::~OGenericUnoDialog()
+{
+ if ( m_pDialog )
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pDialog )
+ destroyDialog();
+ }
+}
+
+//-------------------------------------------------------------------------
+Any SAL_CALL OGenericUnoDialog::queryInterface(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OGenericUnoDialogBase::queryInterface(_rType);
+
+ if (!aReturn.hasValue())
+ aReturn = ::cppu::queryInterface(_rType
+ ,static_cast<XPropertySet*>(this)
+ ,static_cast<XMultiPropertySet*>(this)
+ ,static_cast<XFastPropertySet*>(this)
+ );
+
+ return aReturn;
+}
+
+//-------------------------------------------------------------------------
+Sequence<Type> SAL_CALL OGenericUnoDialog::getTypes( ) throw(RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ OGenericUnoDialogBase::getTypes(),
+ ::comphelper::OPropertyContainer::getTypes()
+ );
+}
+
+//-------------------------------------------------------------------------
+Sequence<sal_Int8> SAL_CALL OGenericUnoDialog::getImplementationId( ) throw(RuntimeException)
+{
+ static ::cppu::OImplementationId aId;
+ return aId.getImplementationId();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OGenericUnoDialog::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
+ const ::rtl::OUString* pArray = aSupported.getConstArray();
+ for (sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray)
+ if (pArray->equals(ServiceName))
+ return sal_True;
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+void OGenericUnoDialog::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw(Exception)
+{
+ // TODO : need some handling if we're currently executing ...
+
+ OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, rValue);
+
+ if (UNODIALOG_PROPERTY_ID_TITLE == nHandle)
+ {
+ // from now on m_sTitle is valid
+ m_bTitleAmbiguous = sal_False;
+
+ if (m_pDialog)
+ m_pDialog->SetText(String(m_sTitle));
+ }
+}
+
+//-------------------------------------------------------------------------
+sal_Bool OGenericUnoDialog::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw(IllegalArgumentException)
+{
+ switch (nHandle)
+ {
+ case UNODIALOG_PROPERTY_ID_PARENT:
+ {
+ Reference<starawt::XWindow> xNew;
+ ::cppu::extractInterface(xNew, rValue);
+ if (xNew != m_xParent)
+ {
+ rConvertedValue <<= xNew;
+ rOldValue <<= m_xParent;
+ return sal_True;
+ }
+ return sal_False;
+ }
+ }
+ return OPropertyContainer::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL OGenericUnoDialog::setTitle( const ::rtl::OUString& _rTitle ) throw(RuntimeException)
+{
+ UnoDialogEntryGuard aGuard( *this );
+
+ try
+ {
+ setPropertyValue(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), makeAny(_rTitle));
+ }
+ catch(RuntimeException&)
+ {
+ // allowed to pass
+ throw;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ // not allowed to pass
+ }
+}
+
+//-------------------------------------------------------------------------
+bool OGenericUnoDialog::impl_ensureDialog_lck()
+{
+ if ( m_pDialog )
+ return true;
+
+ // get the parameters for the dialog from the current settings
+
+ // the parent window
+ Window* pParent = NULL;
+ VCLXWindow* pImplementation = VCLXWindow::GetImplementation(m_xParent);
+ if (pImplementation)
+ pParent = pImplementation->GetWindow();
+
+ // the title
+ String sTitle = m_sTitle;
+
+ Dialog* pDialog = createDialog( pParent );
+ OSL_ENSURE( pDialog, "OGenericUnoDialog::impl_ensureDialog_lck: createDialog returned nonsense!" );
+ if ( !pDialog )
+ return false;
+
+ // do some initialisations
+ if ( !m_bTitleAmbiguous )
+ pDialog->SetText( sTitle );
+
+ // be notified when the dialog is killed by somebody else
+ // #i65958# / 2006-07-07 / frank.schoenheit@sun.com
+ pDialog->AddEventListener( LINK( this, OGenericUnoDialog, OnDialogDying ) );
+
+ m_pDialog = pDialog;
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+sal_Int16 SAL_CALL OGenericUnoDialog::execute( ) throw(RuntimeException)
+{
+ // both creation and execution of the dialog must be guarded with the SolarMutex, so be generous here
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ Dialog* pDialogToExecute = NULL;
+ // create the dialog, if neccessary
+ {
+ UnoDialogEntryGuard aGuard( *this );
+
+ if (m_bExecuting)
+ throw RuntimeException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "already executing the dialog (recursive call)" ) ),
+ *this
+ );
+
+ m_bCanceled = sal_False;
+ m_bExecuting = sal_True;
+
+ if ( !impl_ensureDialog_lck() )
+ return 0;
+
+ pDialogToExecute = m_pDialog;
+ }
+
+ // start execution
+ sal_Int16 nReturn(0);
+ if ( pDialogToExecute )
+ nReturn = pDialogToExecute->Execute();
+
+ {
+ ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex);
+ if (m_bCanceled)
+ nReturn = RET_CANCEL;
+ }
+
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // get the settings of the dialog
+ executedDialog( nReturn );
+
+ m_bExecuting = sal_False;
+ }
+
+ // outta here
+ return nReturn;
+}
+
+#ifdef AWT_DIALOG
+//-------------------------------------------------------------------------
+void SAL_CALL OGenericUnoDialog::endExecute( ) throw(RuntimeException)
+{
+ UnoDialogEntryGuard aGuard( *this );
+ if (!m_bExecuting)
+ throw RuntimeException();
+
+ {
+ ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex);
+ OSL_ENSURE(m_pDialog, "OGenericUnoDialog::endExecute : executing which dialog ?");
+ // m_bExecuting is true but we have no dialog ?
+ if (!m_pDialog)
+ throw RuntimeException();
+
+ if (!m_pDialog->IsInExecute())
+ // we tighly missed it ... another thread finished the execution of the dialog,
+ // but did not manage it to reset m_bExecuting, it currently tries to acquire
+ // m_aMutex or m_aExecutionMutex
+ // => nothing to do
+ return;
+
+ m_pDialog->EndDialog(RET_CANCEL);
+ m_bCanceled = sal_True;
+ }
+}
+#endif
+
+//-------------------------------------------------------------------------
+void OGenericUnoDialog::implInitialize(const Any& _rValue)
+{
+ try
+ {
+ PropertyValue aProperty;
+ NamedValue aValue;
+ if ( _rValue >>= aProperty )
+ {
+ setPropertyValue( aProperty.Name, aProperty.Value );
+ }
+ else if ( _rValue >>= aValue )
+ {
+ setPropertyValue( aValue.Name, aValue.Value );
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL OGenericUnoDialog::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bInitialized )
+ throw AlreadyInitializedException( ::rtl::OUString(), *this );
+
+ const Any* pArguments = aArguments.getConstArray();
+ for (sal_Int32 i=0; i<aArguments.getLength(); ++i, ++pArguments)
+ implInitialize(*pArguments);
+
+ m_bInitialized = true;
+}
+
+//-------------------------------------------------------------------------
+void OGenericUnoDialog::destroyDialog()
+{
+ delete m_pDialog;
+ m_pDialog = NULL;
+}
+
+//-------------------------------------------------------------------------
+IMPL_LINK( OGenericUnoDialog, OnDialogDying, VclWindowEvent*, _pEvent )
+{
+ OSL_ENSURE( _pEvent->GetWindow() == m_pDialog, "OGenericUnoDialog::OnDialogDying: where does this come from?" );
+ if ( _pEvent->GetId() == VCLEVENT_OBJECT_DYING )
+ m_pDialog = NULL;
+ return 0L;
+}
+
+//.........................................................................
+} // namespace svt
+//.........................................................................
+
diff --git a/svtools/source/uno/makefile.mk b/svtools/source/uno/makefile.mk
new file mode 100644
index 000000000000..7c1c44006047
--- /dev/null
+++ b/svtools/source/uno/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=unoiface
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/addrtempuno.obj \
+ $(SLO)$/contextmenuhelper.obj \
+ $(SLO)$/framestatuslistener.obj \
+ $(SLO)$/generictoolboxcontroller.obj \
+ $(SLO)$/genericunodialog.obj \
+ $(SLO)$/miscservices.obj\
+ $(SLO)$/statusbarcontroller.obj \
+ $(SLO)$/toolboxcontroller.obj \
+ $(SLO)$/treecontrolpeer.obj \
+ $(SLO)$/unocontroltablemodel.obj \
+ $(SLO)$/unoevent.obj \
+ $(SLO)$/unoiface.obj \
+ $(SLO)$/unoimap.obj \
+ $(SLO)$/svtxgridcontrol.obj \
+ $(SLO)$/popupwindowcontroller.obj \
+ $(SLO)$/popupmenucontrollerbase.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/uno/miscservices.cxx b/svtools/source/uno/miscservices.cxx
new file mode 100644
index 000000000000..e16a1ecb56dc
--- /dev/null
+++ b/svtools/source/uno/miscservices.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_svtools.hxx"
+#include "sal/types.h"
+#include "rtl/ustring.hxx"
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <osl/diagnose.h>
+#include <uno/mapping.hxx>
+#include "provider.hxx"
+#include "renderer.hxx"
+#include "unowizard.hxx"
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "comphelper/servicedecl.hxx"
+
+#include "cppuhelper/implementationentry.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::lang;
+using namespace unographic;
+
+using rtl::OUString;
+
+namespace sdecl = comphelper::service_decl;
+
+namespace unographic {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+// -------------------------------------------------------------------------------------
+
+// for CreateInstance functions implemented elsewhere
+#define DECLARE_CREATEINSTANCE( ImplName ) \
+ Reference< XInterface > SAL_CALL ImplName##_CreateInstance( const Reference< XMultiServiceFactory >& );
+
+// for CreateInstance functions implemented elsewhere, while the function is within a namespace
+#define DECLARE_CREATEINSTANCE_NAMESPACE( nmspe, ImplName ) \
+ namespace nmspe { \
+ Reference< XInterface > SAL_CALL ImplName##_CreateInstance( const Reference< XMultiServiceFactory >& ); \
+ }
+
+namespace
+{
+ static struct ::cppu::ImplementationEntry s_aServiceEntries[] =
+ {
+ {
+ ::svt::uno::Wizard::Create,
+ ::svt::uno::Wizard::getImplementationName_static,
+ ::svt::uno::Wizard::getSupportedServiceNames_static,
+ ::cppu::createSingleComponentFactory, NULL, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+ };
+}
+
+// -------------------------------------------------------------------------------------
+
+DECLARE_CREATEINSTANCE_NAMESPACE( svt, OAddressBookSourceDialogUno )
+DECLARE_CREATEINSTANCE( SvFilterOptionsDialog )
+DECLARE_CREATEINSTANCE_NAMESPACE( unographic, GraphicProvider )
+DECLARE_CREATEINSTANCE_NAMESPACE( unographic, GraphicRendererVCL )
+
+// -------------------------------------------------------------------------------------
+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, void * _pRegistryKey )
+{
+ if (_pRegistryKey)
+ {
+ Reference< XRegistryKey > xRegistryKey (
+ reinterpret_cast< XRegistryKey* >( _pRegistryKey ));
+ Reference< XRegistryKey > xNewKey;
+ uno::Sequence< ::rtl::OUString > aServices;
+
+ xNewKey = xRegistryKey->createKey (
+ OUString::createFromAscii( "/com.sun.star.comp.svtools.OAddressBookSourceDialogUno/UNO/SERVICES" ) );
+ xNewKey->createKey(
+ OUString::createFromAscii( "com.sun.star.ui.AddressBookSourceDialog" ) );
+
+ xNewKey = xRegistryKey->createKey (
+ OUString::createFromAscii( "/com.sun.star.svtools.SvFilterOptionsDialog/UNO/SERVICES" ) );
+ xNewKey->createKey (
+ OUString::createFromAscii( "com.sun.star.ui.dialogs.FilterOptionsDialog" ) );
+
+ // GraphicProvider
+ xNewKey = reinterpret_cast< registry::XRegistryKey * >( _pRegistryKey )->createKey(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
+ GraphicProvider::getImplementationName_Static() +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );
+
+ aServices = GraphicProvider::getSupportedServiceNames_Static();
+ int i;
+ for( i = 0; i < aServices.getLength(); i++ )
+ xNewKey->createKey( aServices.getConstArray()[ i ] );
+
+ // GraphicRendererVCL
+ xNewKey = reinterpret_cast< registry::XRegistryKey * >( _pRegistryKey )->createKey(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
+ GraphicRendererVCL::getImplementationName_Static() +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );
+
+ aServices = ( GraphicRendererVCL::getSupportedServiceNames_Static() );
+ for( i = 0; i < aServices.getLength(); i++ )
+ xNewKey->createKey( aServices.getConstArray()[ i ] );
+
+ if ( !component_writeInfoHelper( reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ), reinterpret_cast< registry::XRegistryKey* >( _pRegistryKey ), serviceDecl ) )
+ return false;
+
+ return ::cppu::component_writeInfoHelper( pServiceManager, _pRegistryKey, s_aServiceEntries );
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
+ const sal_Char * pImplementationName, void * _pServiceManager, void * pRegistryKey)
+{
+ void * pResult = 0;
+ if ( _pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ if (rtl_str_compare (
+ pImplementationName, "com.sun.star.comp.svtools.OAddressBookSourceDialogUno") == 0)
+ {
+ Sequence< OUString > aServiceNames(1);
+ aServiceNames.getArray()[0] =
+ OUString::createFromAscii( "com.sun.star.ui.AddressBookSourceDialog" );
+
+ xFactory = ::cppu::createSingleFactory (
+ reinterpret_cast< XMultiServiceFactory* >( _pServiceManager ),
+ OUString::createFromAscii( pImplementationName ),
+ svt::OAddressBookSourceDialogUno_CreateInstance,
+ aServiceNames);
+ }
+ else if (rtl_str_compare (
+ pImplementationName, "com.sun.star.svtools.SvFilterOptionsDialog") == 0)
+ {
+ Sequence< OUString > aServiceNames(1);
+ aServiceNames.getArray()[0] =
+ OUString::createFromAscii( "com.sun.star.ui.dialogs.FilterOptionsDialog" );
+
+ xFactory = ::cppu::createSingleFactory (
+ reinterpret_cast< XMultiServiceFactory* >( _pServiceManager ),
+ OUString::createFromAscii( pImplementationName ),
+ SvFilterOptionsDialog_CreateInstance,
+ aServiceNames);
+ }
+ else if( 0 == GraphicProvider::getImplementationName_Static().compareToAscii( pImplementationName ) )
+ {
+ xFactory = ::cppu::createOneInstanceFactory(
+ reinterpret_cast< lang::XMultiServiceFactory * >( _pServiceManager ),
+ GraphicProvider::getImplementationName_Static(),
+ GraphicProvider_CreateInstance,
+ GraphicProvider::getSupportedServiceNames_Static() );
+ }
+ else if( 0 == GraphicRendererVCL::getImplementationName_Static().compareToAscii( pImplementationName ) )
+ {
+ xFactory = ::cppu::createOneInstanceFactory(
+ reinterpret_cast< lang::XMultiServiceFactory * >( _pServiceManager ),
+ GraphicRendererVCL::getImplementationName_Static(),
+ GraphicRendererVCL_CreateInstance,
+ GraphicRendererVCL::getSupportedServiceNames_Static() );
+ }
+ else
+ {
+ pResult = component_getFactoryHelper( pImplementationName, reinterpret_cast< lang::XMultiServiceFactory * >( _pServiceManager ),reinterpret_cast< registry::XRegistryKey* >( pRegistryKey ), serviceDecl );
+ if ( !pResult )
+ pResult = ::cppu::component_getFactoryHelper( pImplementationName, _pServiceManager, pRegistryKey, s_aServiceEntries );
+ }
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pResult = xFactory.get();
+ }
+ }
+ return pResult;
+}
+
+} // "C"
+
diff --git a/svtools/source/uno/popupmenucontrollerbase.cxx b/svtools/source/uno/popupmenucontrollerbase.cxx
new file mode 100644
index 000000000000..ac75a1b9a24b
--- /dev/null
+++ b/svtools/source/uno/popupmenucontrollerbase.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_svtools.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "svtools/popupmenucontrollerbase.hxx"
+
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#ifndef _VCL_MENU_HXX_
+#include <vcl/menu.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+#include <vos/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+//
+
+using ::rtl::OUString;
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace svt
+{
+
+struct PopupMenuControllerBaseDispatchInfo
+{
+ Reference< XDispatch > mxDispatch;
+ const URL maURL;
+ const Sequence< PropertyValue > maArgs;
+
+ PopupMenuControllerBaseDispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
+ : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
+};
+
+PopupMenuControllerBase::PopupMenuControllerBase( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ::comphelper::OBaseMutex(),
+ PopupMenuControllerBaseType(m_aMutex),
+ m_bInitialized( false ),
+ m_xServiceManager( xServiceManager )
+{
+ if ( m_xServiceManager.is() )
+ m_xURLTransformer.set( m_xServiceManager->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),UNO_QUERY );
+}
+
+PopupMenuControllerBase::~PopupMenuControllerBase()
+{
+}
+
+// protected function
+void PopupMenuControllerBase::throwIfDisposed() throw ( RuntimeException )
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ throw com::sun::star::lang::DisposedException();
+}
+
+// protected function
+void PopupMenuControllerBase::resetPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = 0;
+ if ( rPopupMenu.is() && rPopupMenu->getItemCount() > 0 )
+ {
+ pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ if ( pPopupMenu )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+ pVCLPopupMenu->Clear();
+ }
+ }
+}
+
+void SAL_CALL PopupMenuControllerBase::disposing()
+{
+ // Reset our members and set disposed flag
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xPopupMenu.clear();
+ m_xServiceManager.clear();
+}
+
+// XServiceInfo
+
+sal_Bool SAL_CALL PopupMenuControllerBase::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
+{
+ const Sequence< rtl::OUString > aSNL( getSupportedServiceNames() );
+ const rtl::OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// XEventListener
+void SAL_CALL PopupMenuControllerBase::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xPopupMenu.clear();
+}
+
+// XMenuListener
+void SAL_CALL PopupMenuControllerBase::highlight( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void PopupMenuControllerBase::impl_select(const Reference< XDispatch >& _xDispatch,const URL& aURL)
+{
+ Sequence<PropertyValue> aArgs;
+ OSL_ENSURE(_xDispatch.is(),"PopupMenuControllerBase::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aURL, aArgs );
+}
+
+void SAL_CALL PopupMenuControllerBase::select( const awt::MenuEvent& rEvent ) throw (RuntimeException)
+{
+ throwIfDisposed();
+
+ osl::MutexGuard aLock( m_aMutex );
+
+ Reference< awt::XMenuExtended > xExtMenu( m_xPopupMenu, UNO_QUERY );
+ if( xExtMenu.is() )
+ {
+ Sequence<PropertyValue> aArgs;
+ dispatchCommand( xExtMenu->getCommand( rEvent.MenuId ), aArgs );
+ }
+}
+
+void PopupMenuControllerBase::dispatchCommand( const ::rtl::OUString& sCommandURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ try
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
+ URL aURL;
+ aURL.Complete = sCommandURL;
+ m_xURLTransformer->parseStrict( aURL );
+
+ Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
+
+ Application::PostUserEvent( STATIC_LINK(0, PopupMenuControllerBase, ExecuteHdl_Impl), new PopupMenuControllerBaseDispatchInfo( xDispatch, aURL, rArgs ) );
+
+ }
+ catch( Exception& )
+ {
+ }
+
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( PopupMenuControllerBase, ExecuteHdl_Impl, PopupMenuControllerBaseDispatchInfo*, pDispatchInfo )
+{
+ pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
+ delete pDispatchInfo;
+ return 0;
+}
+
+void SAL_CALL PopupMenuControllerBase::activate( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void SAL_CALL PopupMenuControllerBase::deactivate( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void SAL_CALL PopupMenuControllerBase::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ updateCommand( m_aCommandURL );
+}
+
+void SAL_CALL PopupMenuControllerBase::updateCommand( const rtl::OUString& rCommandURL )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XDispatch > xDispatch( m_xDispatch );
+ URL aTargetURL;
+ aTargetURL.Complete = rCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ // Add/remove status listener to get a status update once
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+}
+
+
+// XDispatchProvider
+Reference< XDispatch > SAL_CALL
+PopupMenuControllerBase::queryDispatch(
+ const URL& /*aURL*/,
+ const rtl::OUString& /*sTarget*/,
+ sal_Int32 /*nFlags*/ )
+throw( RuntimeException )
+{
+ // must be implemented by subclass
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+
+ return Reference< XDispatch >();
+}
+
+Sequence< Reference< XDispatch > > SAL_CALL PopupMenuControllerBase::queryDispatches( const Sequence< DispatchDescriptor >& lDescriptor ) throw( RuntimeException )
+{
+ // Create return list - which must have same size then the given descriptor
+ // It's not allowed to pack it!
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ sal_Int32 nCount = lDescriptor.getLength();
+ uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount );
+
+ // Step over all descriptors and try to get any dispatcher for it.
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = queryDispatch( lDescriptor[i].FeatureURL ,
+ lDescriptor[i].FrameName ,
+ lDescriptor[i].SearchFlags );
+ }
+
+ return lDispatcher;
+}
+
+// XDispatch
+void SAL_CALL
+PopupMenuControllerBase::dispatch(
+ const URL& /*aURL*/,
+ const Sequence< PropertyValue >& /*seqProperties*/ )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ // must be implemented by subclass
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+}
+
+void SAL_CALL
+PopupMenuControllerBase::addStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ bool bStatusUpdate( false );
+ rBHelper.addListener( ::getCppuType( &xControl ), xControl );
+
+ aLock.reset();
+ if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
+ bStatusUpdate = true;
+ aLock.clear();
+
+ if ( bStatusUpdate )
+ {
+ // Dummy update for popup menu controllers
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = aURL;
+ aEvent.IsEnabled = sal_True;
+ aEvent.Requery = sal_False;
+ aEvent.State = Any();
+ xControl->statusChanged( aEvent );
+ }
+}
+
+void SAL_CALL PopupMenuControllerBase::removeStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& /*aURL*/ )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ rBHelper.removeListener( ::getCppuType( &xControl ), xControl );
+}
+
+::rtl::OUString PopupMenuControllerBase::determineBaseURL( const ::rtl::OUString& aURL )
+{
+ // Just use the main part of the URL for popup menu controllers
+ sal_Int32 nQueryPart( 0 );
+ sal_Int32 nSchemePart( 0 );
+ rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
+
+ nSchemePart = aURL.indexOf( ':' );
+ if (( nSchemePart > 0 ) &&
+ ( aURL.getLength() > ( nSchemePart+1 )))
+ {
+ nQueryPart = aURL.indexOf( '?', nSchemePart );
+ if ( nQueryPart > 0 )
+ aMainURL += aURL.copy( nSchemePart, nQueryPart-nSchemePart );
+ else if ( nQueryPart == -1 )
+ aMainURL += aURL.copy( nSchemePart+1 );
+ }
+
+ return aMainURL;
+}
+
+// XInitialization
+void SAL_CALL PopupMenuControllerBase::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ sal_Bool bInitalized( m_bInitialized );
+ if ( !bInitalized )
+ {
+ PropertyValue aPropValue;
+ rtl::OUString aCommandURL;
+ Reference< XFrame > xFrame;
+
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAscii( "Frame" ))
+ aPropValue.Value >>= xFrame;
+ else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
+ aPropValue.Value >>= aCommandURL;
+ }
+ }
+
+ if ( xFrame.is() && aCommandURL.getLength() )
+ {
+ m_xFrame = xFrame;
+ m_aCommandURL = aCommandURL;
+ m_aBaseURL = determineBaseURL( aCommandURL );
+ m_bInitialized = true;
+ }
+ }
+}
+// XPopupMenuController
+void SAL_CALL PopupMenuControllerBase::setPopupMenu( const Reference< awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+
+ if ( m_xFrame.is() && !m_xPopupMenu.is() )
+ {
+ // Create popup menu on demand
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ m_xPopupMenu = xPopupMenu;
+ m_xPopupMenu->addMenuListener( Reference< awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
+
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ URL aTargetURL;
+ aTargetURL.Complete = m_aCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ impl_setPopupMenu();
+
+ updatePopupMenu();
+ }
+}
+void PopupMenuControllerBase::impl_setPopupMenu()
+{
+}
+}
diff --git a/svtools/source/uno/popupwindowcontroller.cxx b/svtools/source/uno/popupwindowcontroller.cxx
new file mode 100644
index 000000000000..4fbaff23714d
--- /dev/null
+++ b/svtools/source/uno/popupwindowcontroller.cxx
@@ -0,0 +1,258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <vcl/toolbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "svtools/popupwindowcontroller.hxx"
+#include "svtools/toolbarmenu.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+
+namespace svt
+{
+
+class PopupWindowControllerImpl
+{
+public:
+ PopupWindowControllerImpl();
+ ~PopupWindowControllerImpl();
+
+ void SetPopupWindow( ::Window* pPopupWindow, ToolBox* pToolBox );
+
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+ DECL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window* );
+
+private:
+ ::Window* mpPopupWindow;
+ ToolBox* mpToolBox;
+};
+
+PopupWindowControllerImpl::PopupWindowControllerImpl()
+: mpPopupWindow( 0 )
+, mpToolBox( 0 )
+{
+}
+
+PopupWindowControllerImpl::~PopupWindowControllerImpl()
+{
+ if( mpPopupWindow )
+ SetPopupWindow(0,0);
+}
+
+void PopupWindowControllerImpl::SetPopupWindow( ::Window* pPopupWindow, ToolBox* pToolBox )
+{
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->RemoveEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ) );
+ Application::PostUserEvent( STATIC_LINK( this, PopupWindowControllerImpl, AsyncDeleteWindowHdl ), mpPopupWindow );
+ }
+ mpPopupWindow = pPopupWindow;
+ mpToolBox = pToolBox;
+
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->AddEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ));
+ }
+}
+
+IMPL_LINK( PopupWindowControllerImpl, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ VclWindowEvent* pWindowEvent = dynamic_cast< VclWindowEvent* >( pEvent );
+ if( pWindowEvent )
+ {
+ switch( pWindowEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_CLOSE:
+ case VCLEVENT_WINDOW_ENDPOPUPMODE:
+ SetPopupWindow(0,0);
+ break;
+
+ case VCLEVENT_WINDOW_SHOW:
+ {
+ if( mpPopupWindow )
+ {
+ if( mpToolBox )
+ mpToolBox->CallEventListeners( VCLEVENT_DROPDOWN_OPEN, (void*)mpPopupWindow );
+ mpPopupWindow->CallEventListeners( VCLEVENT_WINDOW_GETFOCUS, 0 );
+
+ svtools::ToolbarMenu* pToolbarMenu = dynamic_cast< svtools::ToolbarMenu* >( mpPopupWindow );
+ if( pToolbarMenu )
+ pToolbarMenu->highlightFirstEntry();
+ break;
+ }
+ break;
+ }
+ case VCLEVENT_WINDOW_HIDE:
+ {
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->CallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS, 0 );
+ if( mpToolBox )
+ mpToolBox->CallEventListeners( VCLEVENT_DROPDOWN_CLOSE, (void*)mpPopupWindow );
+ }
+ break;
+ }
+ }
+ }
+ return 1;
+}
+
+//--------------------------------------------------------------------
+
+IMPL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window*, pWindow )
+{
+ (void)*pThis;
+ delete pWindow;
+ return 0;
+}
+
+//========================================================================
+// class PopupWindowController
+//========================================================================
+
+PopupWindowController::PopupWindowController( const Reference< lang::XMultiServiceFactory >& rServiceManager,
+ const Reference< frame::XFrame >& xFrame,
+ const OUString& aCommandURL )
+: svt::ToolboxController( rServiceManager, xFrame, aCommandURL )
+, mpImpl( new PopupWindowControllerImpl() )
+{
+}
+
+PopupWindowController::~PopupWindowController()
+{
+}
+
+// XInterface
+Any SAL_CALL PopupWindowController::queryInterface( const Type& aType )
+throw (RuntimeException)
+{
+ Any a( ToolboxController::queryInterface( aType ) );
+ if ( a.hasValue() )
+ return a;
+
+ return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
+}
+
+void SAL_CALL PopupWindowController::acquire() throw ()
+{
+ ToolboxController::acquire();
+}
+
+void SAL_CALL PopupWindowController::release() throw ()
+{
+ ToolboxController::release();
+}
+
+// XServiceInfo
+sal_Bool SAL_CALL PopupWindowController::supportsService( const OUString& ServiceName ) throw(RuntimeException)
+{
+ const Sequence< OUString > aSNL( getSupportedServiceNames() );
+ const OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// XInitialization
+void SAL_CALL PopupWindowController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ svt::ToolboxController::initialize( aArguments );
+ if( m_aCommandURL.getLength() )
+ addStatusListener( m_aCommandURL );
+}
+
+// XComponent
+void SAL_CALL PopupWindowController::dispose() throw (RuntimeException)
+{
+ if( m_aCommandURL.getLength() )
+ removeStatusListener( m_aCommandURL );
+
+ svt::ToolboxController::dispose();
+}
+
+
+// XStatusListener
+void SAL_CALL PopupWindowController::statusChanged( const frame::FeatureStateEvent& rEvent ) throw ( RuntimeException )
+{
+ svt::ToolboxController::statusChanged(rEvent);
+ enable( rEvent.IsEnabled );
+}
+
+// XToolbarController
+void SAL_CALL PopupWindowController::execute( sal_Int16 KeyModifier ) throw (RuntimeException)
+{
+ svt::ToolboxController::execute( KeyModifier );
+}
+
+void SAL_CALL PopupWindowController::click() throw (RuntimeException)
+{
+ svt::ToolboxController::click();
+}
+
+void SAL_CALL PopupWindowController::doubleClick() throw (RuntimeException)
+{
+ svt::ToolboxController::doubleClick();
+}
+
+Reference< awt::XWindow > SAL_CALL PopupWindowController::createPopupWindow() throw (RuntimeException)
+{
+ ToolBox* pToolBox = dynamic_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+ if( pToolBox )
+ {
+ ::Window* pItemWindow = pToolBox->GetItemWindow( pToolBox->GetDownItemId() );
+ ::Window* pWin = createPopupWindow( pItemWindow ? pItemWindow : pToolBox );
+ if( pWin )
+ {
+ pWin->EnableDocking(true);
+ mpImpl->SetPopupWindow(pWin,pToolBox);
+ ::Window::GetDockingManager()->StartPopupMode( pToolBox, pWin, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE |FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE );
+ }
+ }
+ return Reference< awt::XWindow >();
+}
+
+Reference< awt::XWindow > SAL_CALL PopupWindowController::createItemWindow( const Reference< awt::XWindow >& /*Parent*/ )
+ throw (RuntimeException)
+{
+ return Reference< awt::XWindow >();
+}
+
+}
+
diff --git a/svtools/source/uno/statusbarcontroller.cxx b/svtools/source/uno/statusbarcontroller.cxx
new file mode 100644
index 000000000000..14b802a1bf90
--- /dev/null
+++ b/svtools/source/uno/statusbarcontroller.cxx
@@ -0,0 +1,784 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <statusbarcontroller.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/status.hxx>
+#include <imgdef.hxx>
+#include <svtools/miscopt.hxx>
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+
+using namespace ::cppu;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame;
+
+namespace svt
+{
+
+StatusbarController::StatusbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& xFrame,
+ const ::rtl::OUString& aCommandURL,
+ unsigned short nID ) :
+ OWeakObject()
+ , m_bInitialized( sal_False )
+ , m_bDisposed( sal_False )
+ , m_nID( nID )
+ , m_xFrame( xFrame )
+ , m_xServiceManager( rServiceManager )
+ , m_aCommandURL( aCommandURL )
+ , m_aListenerContainer( m_aMutex )
+{
+}
+
+StatusbarController::StatusbarController() :
+ OWeakObject()
+ , m_bInitialized( sal_False )
+ , m_bDisposed( sal_False )
+ , m_nID( 0 )
+ , m_aListenerContainer( m_aMutex )
+{
+}
+
+StatusbarController::~StatusbarController()
+{
+}
+
+Reference< XFrame > StatusbarController::getFrameInterface() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_xFrame;
+}
+
+Reference< XMultiServiceFactory > StatusbarController::getServiceManager() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_xServiceManager;
+}
+
+Reference< XLayoutManager > StatusbarController::getLayoutManager() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ Reference< XLayoutManager > xLayoutManager;
+ Reference< XPropertySet > xPropSet( m_xFrame, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ Any a;
+ a = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
+ a >>= xLayoutManager;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return xLayoutManager;
+}
+
+Reference< XURLTransformer > StatusbarController::getURLTransformer() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ if ( !m_xURLTransformer.is() && m_xServiceManager.is() )
+ {
+ m_xURLTransformer = Reference< XURLTransformer >(
+ m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ }
+
+ return m_xURLTransformer;
+}
+
+// XInterface
+Any SAL_CALL StatusbarController::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ static_cast< XStatusbarController* >( this ),
+ static_cast< XStatusListener* >( this ),
+ static_cast< XEventListener* >( this ),
+ static_cast< XInitialization* >( this ),
+ static_cast< XComponent* >( this ),
+ static_cast< XUpdatable* >( this ));
+
+ if ( a.hasValue() )
+ return a;
+
+ return OWeakObject::queryInterface( rType );
+}
+
+void SAL_CALL StatusbarController::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL StatusbarController::release() throw ()
+{
+ OWeakObject::release();
+}
+
+void SAL_CALL StatusbarController::initialize( const Sequence< Any >& aArguments )
+throw ( Exception, RuntimeException )
+{
+ const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
+ const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ const rtl::OUString aParentWindow( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
+ const rtl::OUString aIdentifier( RTL_CONSTASCII_USTRINGPARAM( "Identifier" ));
+
+ bool bInitialized( true );
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ bInitialized = m_bInitialized;
+ }
+
+ if ( !bInitialized )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ m_bInitialized = sal_True;
+
+ PropertyValue aPropValue;
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAscii( "Frame" ))
+ aPropValue.Value >>= m_xFrame;
+ else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
+ aPropValue.Value >>= m_aCommandURL;
+ else if ( aPropValue.Name.equalsAscii( "ServiceManager" ))
+ aPropValue.Value >>= m_xServiceManager;
+ else if ( aPropValue.Name.equalsAscii( "ParentWindow" ))
+ aPropValue.Value >>= m_xParentWindow;
+ else if ( aPropValue.Name.equalsAscii( "Identifier" ))
+ aPropValue.Value >>= m_nID;
+ }
+ }
+
+ if ( m_aCommandURL.getLength() )
+ m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() ));
+ }
+}
+
+void SAL_CALL StatusbarController::update()
+throw ( RuntimeException )
+{
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ // Bind all registered listeners to their dispatch objects
+ bindListener();
+}
+
+// XComponent
+void SAL_CALL StatusbarController::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XURLTransformer > xURLTransformer = getURLTransformer();
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ com::sun::star::util::URL aTargetURL;
+ while ( pIter != m_aListenerMap.end() )
+ {
+ try
+ {
+ Reference< XDispatch > xDispatch( pIter->second );
+ aTargetURL.Complete = pIter->first;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ ++pIter;
+ }
+
+ // clear hash map
+ m_aListenerMap.clear();
+
+ // release references
+ m_xURLTransformer.clear();
+ m_xServiceManager.clear();
+ m_xFrame.clear();
+ m_xParentWindow.clear();
+
+ m_bDisposed = sal_True;
+}
+
+void SAL_CALL StatusbarController::addEventListener( const Reference< XEventListener >& xListener )
+throw ( RuntimeException )
+{
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL StatusbarController::removeEventListener( const Reference< XEventListener >& aListener )
+throw ( RuntimeException )
+{
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener );
+}
+
+// XEventListener
+void SAL_CALL StatusbarController::disposing( const EventObject& Source )
+throw ( RuntimeException )
+{
+ Reference< XInterface > xSource( Source.Source );
+
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ return;
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ // Compare references and release dispatch references if they are equal.
+ Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
+ if ( xSource == xIfac )
+ pIter->second.clear();
+ pIter++;
+ }
+
+ Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
+ if ( xIfac == xSource )
+ m_xFrame.clear();
+}
+
+// XStatusListener
+void SAL_CALL StatusbarController::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ return;
+
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR && m_nID != 0 )
+ {
+ rtl::OUString aStrValue;
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+
+ if ( Event.State >>= aStrValue )
+ pStatusBar->SetItemText( m_nID, aStrValue );
+ else if ( !Event.State.hasValue() )
+ pStatusBar->SetItemText( m_nID, String() );
+ }
+}
+
+// XStatusbarController
+::sal_Bool SAL_CALL StatusbarController::mouseButtonDown(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL StatusbarController::mouseMove(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL StatusbarController::mouseButtonUp(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL StatusbarController::command(
+ const ::com::sun::star::awt::Point&,
+ ::sal_Int32,
+ ::sal_Bool,
+ const ::com::sun::star::uno::Any& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL StatusbarController::paint(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >&,
+ const ::com::sun::star::awt::Rectangle&,
+ ::sal_Int32,
+ ::sal_Int32 )
+throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL StatusbarController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL StatusbarController::doubleClick() throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ return;
+
+ Sequence< PropertyValue > aArgs;
+ execute( aArgs );
+}
+
+void StatusbarController::addStatusListener( const rtl::OUString& aCommandURL )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+
+ // Already in the list of status listener. Do nothing.
+ if ( pIter != m_aListenerMap.end() )
+ return;
+
+ // Check if we are already initialized. Implementation starts adding itself as status listener when
+ // intialize is called.
+ if ( !m_bInitialized )
+ {
+ // Put into the hash_map of status listener. Will be activated when initialized is called
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
+ return;
+ }
+ else
+ {
+ // Add status listener directly as intialize has already been called.
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XURLTransformer > xURLTransformer = getURLTransformer();
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
+ if ( aIter != m_aListenerMap.end() )
+ {
+ Reference< XDispatch > xOldDispatch( aIter->second );
+ aIter->second = xDispatch;
+
+ try
+ {
+ if ( xOldDispatch.is() )
+ xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
+ }
+ }
+ }
+
+ // Call without locked mutex as we are called back from dispatch implementation
+ try
+ {
+ if ( xDispatch.is() )
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+void StatusbarController::removeStatusListener( const rtl::OUString& aCommandURL )
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XDispatch > xDispatch( pIter->second );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ m_aListenerMap.erase( pIter );
+
+ try
+ {
+ Reference< XURLTransformer > xURLTransformer = getURLTransformer();
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void StatusbarController::bindListener()
+{
+ std::vector< Listener > aDispatchVector;
+ Reference< XStatusListener > xStatusListener;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Collect all registered command URL's and store them temporary
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XURLTransformer > xURLTransformer = getURLTransformer();
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch( pIter->second );
+ if ( xDispatch.is() )
+ {
+ // We already have a dispatch object => we have to requery.
+ // Release old dispatch object and remove it as listener
+ try
+ {
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ pIter->second.clear();
+ xDispatch.clear();
+
+ // Query for dispatch object. Old dispatch will be released with this, too.
+ try
+ {
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ }
+ catch ( Exception& )
+ {
+ }
+ pIter->second = xDispatch;
+
+ Listener aListener( aTargetURL, xDispatch );
+ aDispatchVector.push_back( aListener );
+ ++pIter;
+ }
+ }
+ }
+
+ // Call without locked mutex as we are called back from dispatch implementation
+ if ( xStatusListener.is() )
+ {
+ try
+ {
+ for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
+ {
+ Listener& rListener = aDispatchVector[i];
+ if ( rListener.xDispatch.is() )
+ rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
+ else if ( rListener.aURL.Complete == m_aCommandURL )
+ {
+ try
+ {
+ // Send status changed for the main URL, if we cannot get a valid dispatch object.
+ // UI disables the button. Catch exception as we release our mutex, it is possible
+ // that someone else already disposed this instance!
+ FeatureStateEvent aFeatureStateEvent;
+ aFeatureStateEvent.IsEnabled = sal_False;
+ aFeatureStateEvent.FeatureURL = rListener.aURL;
+ aFeatureStateEvent.State = Any();
+ xStatusListener->statusChanged( aFeatureStateEvent );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void StatusbarController::unbindListener()
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Collect all registered command URL's and store them temporary
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XURLTransformer > xURLTransformer = getURLTransformer();
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch( pIter->second );
+ if ( xDispatch.is() )
+ {
+ // We already have a dispatch object => we have to requery.
+ // Release old dispatch object and remove it as listener
+ try
+ {
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ pIter->second.clear();
+ ++pIter;
+ }
+ }
+}
+
+sal_Bool StatusbarController::isBound() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return sal_False;
+
+ URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ return ( pIter->second.is() );
+
+ return sal_False;
+}
+
+void StatusbarController::updateStatus()
+{
+ bindListener();
+}
+
+void StatusbarController::updateStatus( const rtl::OUString aCommandURL )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Try to find a dispatch object for the requested command URL
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XURLTransformer > xURLTransformer = getURLTransformer();
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 );
+ }
+ }
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ {
+ // Catch exception as we release our mutex, it is possible that someone else
+ // has already disposed this instance!
+ // Add/remove status listener to get a update status information from the
+ // requested command.
+ try
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+::Rectangle StatusbarController::getControlRect() const
+{
+ ::Rectangle aRect;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xParentWindow.is() )
+ {
+ StatusBar* pStatusBar = dynamic_cast< StatusBar* >( VCLUnoHelper::GetWindow( m_xParentWindow ));
+ if ( pStatusBar && pStatusBar->GetType() == WINDOW_STATUSBAR )
+ aRect = pStatusBar->GetItemRect( m_nID );
+ }
+ }
+
+ return aRect;
+}
+
+void StatusbarController::execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XURLTransformer > xURLTransformer;
+ rtl::OUString aCommandURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+ xURLTransformer = getURLTransformer();
+ aCommandURL = m_aCommandURL;
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ xDispatch = pIter->second;
+ }
+ }
+
+ if ( xDispatch.is() && xURLTransformer.is() )
+ {
+ try
+ {
+ com::sun::star::util::URL aTargetURL;
+
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+ catch ( DisposedException& )
+ {
+ }
+ }
+}
+
+void StatusbarController::execute(
+ const rtl::OUString& aCommandURL,
+ const Sequence< ::com::sun::star::beans::PropertyValue >& aArgs )
+{
+ Reference< XDispatch > xDispatch;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+ Reference< XURLTransformer > xURLTransformer( getURLTransformer() );
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ xDispatch = pIter->second;
+ else
+ {
+ Reference< ::com::sun::star::frame::XDispatchProvider > xDispatchProvider(
+ m_xFrame->getController(), UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ }
+ }
+ }
+
+ if ( xDispatch.is() )
+ {
+ try
+ {
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+ catch ( DisposedException& )
+ {
+ }
+ }
+}
+
+} // svt
diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx
new file mode 100755
index 000000000000..f5bc837f60b0
--- /dev/null
+++ b/svtools/source/uno/svtxgridcontrol.cxx
@@ -0,0 +1,899 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "svtxgridcontrol.hxx"
+#include "accessibletableimp.hxx"
+#include <com/sun/star/view/SelectionType.hpp>
+#include "svtools/table/gridtablerenderer.hxx"
+#include "svtools/table/defaultinputhandler.hxx"
+#include "svtools/table/tablecontrol.hxx"
+#include "unocontroltablemodel.hxx"
+#include <comphelper/sequence.hxx>
+#include <rtl/ref.hxx>
+#include <tools/debug.hxx>
+#include <toolkit/helper/property.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/awt/grid/XGridColumn.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/grid/GridInvalidDataException.hpp>
+#include <com/sun/star/awt/grid/GridInvalidModelException.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+
+using ::rtl::OUString;
+using namespace ::svt::table;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt::grid;
+using namespace ::com::sun::star::view;
+using namespace ::toolkit;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleEventId;
+using namespace ::com::sun::star::accessibility::AccessibleTableModelChangeType;
+using ::com::sun::star::accessibility::AccessibleTableModelChange;
+
+
+SVTXGridControl::SVTXGridControl()
+ :m_pTableModel (new UnoControlTableModel()),
+ m_xDataModel(0),
+ m_xColumnModel(0),
+ m_bHasColumnHeaders(false),
+ m_bHasRowHeaders(false),
+ m_bVScroll(false),
+ m_bHScroll(false),
+ m_bUpdate(false),
+ m_nSelectedRowCount(0),
+ m_aSelectionListeners( *this )
+{
+}
+
+//--------------------------------------------------------------------
+SVTXGridControl::~SVTXGridControl()
+{
+}
+
+::com::sun::star::uno::Any SVTXGridControl::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridControl*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridDataListener*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridColumnListener*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
+ return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
+}
+
+// ::com::sun::star::lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( SVTXGridControl )
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridControl>* ) NULL ),
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel>* ) NULL ),
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener>* ) NULL ),
+ VCLXWindow::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+sal_Int32 SAL_CALL SVTXGridControl::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ return pTable->GetCurrentRow( Point(x,y) );
+}
+
+void SAL_CALL SVTXGridControl::setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const com::sun::star::uno::Sequence< sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ pTable->setTooltip(text, columns);
+}
+
+void SAL_CALL SVTXGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_aSelectionListeners.addInterface(listener);
+}
+
+void SAL_CALL SVTXGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_aSelectionListeners.removeInterface(listener);
+}
+
+void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ TableControl* pTable = (TableControl*)GetWindow();
+ switch( GetPropertyId( PropertyName ) )
+ {
+ case BASEPROPERTY_BACKGROUNDCOLOR:
+ {
+ // let the base class handle this for the TableControl
+ VCLXWindow::setProperty( PropertyName, aValue );
+ // and forward to the grid control's data window
+ if ( pTable->IsBackground() )
+ pTable->getDataWindow()->SetBackground( pTable->GetBackground() );
+ else
+ pTable->getDataWindow()->SetBackground();
+ }
+ break;
+
+ case BASEPROPERTY_GRID_SELECTIONMODE:
+ {
+ SelectionType eSelectionType;
+ if( aValue >>= eSelectionType )
+ {
+ SelectionMode eSelMode;
+ switch( eSelectionType )
+ {
+ case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break;
+ case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break;
+ case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break;
+ // case SelectionType_NONE:
+ default: eSelMode = NO_SELECTION; break;
+ }
+ if( pTable->getSelEngine()->GetSelectionMode() != eSelMode )
+ pTable->getSelEngine()->SetSelectionMode( eSelMode );
+ }
+ break;
+ }
+ case BASEPROPERTY_HSCROLL:
+ {
+ sal_Bool bHScroll = true;
+ if( aValue >>= bHScroll )
+ {
+ m_bHScroll = bHScroll;
+ m_pTableModel->setHorizontalScrollbarVisibility(bHScroll);
+ }
+ break;
+ }
+ case BASEPROPERTY_VSCROLL:
+ {
+ sal_Bool bVScroll = true;
+ if( aValue >>= bVScroll )
+ {
+ m_bVScroll = bVScroll;
+ m_pTableModel->setVerticalScrollbarVisibility(bVScroll);
+ }
+ break;
+ }
+
+ case BASEPROPERTY_GRID_SHOWROWHEADER:
+ {
+ sal_Bool rowHeader = true;
+ if( aValue >>= rowHeader )
+ {
+ m_pTableModel->setRowHeaders(rowHeader);
+ }
+ break;
+ }
+ case BASEPROPERTY_GRID_HEADER_BACKGROUND:
+ {
+ sal_Int32 colorHeader = 0xFFFFFF;
+ if( aValue >>= colorHeader )
+ {
+ m_pTableModel->setHeaderBackgroundColor(colorHeader);
+ }
+ break;
+ }
+ case BASEPROPERTY_GRID_LINE_COLOR:
+ {
+ sal_Int32 colorLine = 0xFFFFFF;
+ if( aValue >>= colorLine )
+ {
+ m_pTableModel->setLineColor(colorLine);
+ }
+ break;
+ }
+ case BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND:
+ {
+ sal_Int32 colorEvenRow = 0xFFFFFF;
+ if( aValue >>= colorEvenRow )
+ {
+ m_pTableModel->setEvenRowBackgroundColor(colorEvenRow);
+ }
+ break;
+ }
+ case BASEPROPERTY_GRID_ROW_BACKGROUND:
+ {
+ sal_Int32 colorBackground = 0xFFFFFF;
+ if( aValue >>= colorBackground )
+ {
+ m_pTableModel->setOddRowBackgroundColor(colorBackground);
+ }
+ break;
+ }
+ case BASEPROPERTY_TEXTCOLOR:
+ {
+ sal_Int32 colorText = 0x000000;
+ if( aValue >>= colorText )
+ {
+ m_pTableModel->setTextColor(colorText);
+ }
+ break;
+ }
+ case BASEPROPERTY_VERTICALALIGN:
+ {
+ com::sun::star::style::VerticalAlignment vAlign(com::sun::star::style::VerticalAlignment(0));
+ if( aValue >>= vAlign )
+ {
+ switch( vAlign )
+ {
+ case com::sun::star::style::VerticalAlignment_TOP: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(0)); break;
+ case com::sun::star::style::VerticalAlignment_MIDDLE: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(1)); break;
+ case com::sun::star::style::VerticalAlignment_BOTTOM: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(2)); break;
+ default: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(0)); break;
+ }
+ }
+ break;
+ }
+
+ case BASEPROPERTY_GRID_SHOWCOLUMNHEADER:
+ {
+ sal_Bool colHeader = true;
+ if( aValue >>= colHeader )
+ {
+ m_pTableModel->setColumnHeaders(colHeader);
+ }
+ break;
+ }
+ case BASEPROPERTY_GRID_DATAMODEL:
+ {
+ {
+ m_xDataModel = Reference< XGridDataModel >( aValue, UNO_QUERY );
+ if(m_xDataModel != NULL)
+ {
+ Sequence<Sequence< Any > > cellData = m_xDataModel->getData();
+ if(cellData.getLength()!= 0)
+ {
+ for (int i = 0; i < cellData.getLength(); i++)
+ {
+ std::vector< Any > newRow;
+ Sequence< Any > rawRowData = cellData[i];
+ //check whether the data row vector length matches with the column count
+ if(m_xColumnModel->getColumnCount() == 0)
+ {
+ for ( ::svt::table::ColPos col = 0; col < rawRowData.getLength(); ++col )
+ {
+ UnoControlTableColumn* tableColumn = new UnoControlTableColumn();
+ m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn);
+ }
+ m_xColumnModel->setDefaultColumns(rawRowData.getLength());
+ }
+ else
+ if((unsigned int)rawRowData.getLength()!=(unsigned)m_pTableModel->getColumnCount())
+ throw GridInvalidDataException(rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), m_xDataModel);
+
+ for ( int k = 0; k < rawRowData.getLength(); k++)
+ {
+ newRow.push_back(rawRowData[k]);
+ }
+ m_pTableModel->getCellContent().push_back(newRow);
+ }
+
+ Sequence< ::rtl::OUString > rowHeaders = m_xDataModel->getRowHeaders();
+ std::vector< rtl::OUString > newRow(
+ comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowHeaders));
+ m_pTableModel->setRowCount(m_xDataModel->getRowCount());
+ m_pTableModel->setRowHeaderName(newRow);
+ }
+ }
+ else
+ throw GridInvalidDataException(rtl::OUString::createFromAscii("The data model isn't set!"), m_xDataModel);
+ sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height();
+ if(m_xDataModel->getRowHeight() == 0)
+ {
+ m_pTableModel->setRowHeight(fontHeight);
+ m_xDataModel->setRowHeight(fontHeight);
+ }
+ else
+ m_pTableModel->setRowHeight(m_xDataModel->getRowHeight());
+ m_pTableModel->setRowHeaderWidth(m_xDataModel->getRowHeaderWidth());
+ }
+ break;
+ }
+ case BASEPROPERTY_GRID_COLUMNMODEL:
+ {
+ m_xColumnModel = Reference< XGridColumnModel >( aValue, UNO_QUERY );
+ if(m_xColumnModel != NULL)
+ {
+ if(m_xColumnModel->getColumnCount() != 0)
+ {
+ Sequence<Reference< XGridColumn > > columns = m_xColumnModel->getColumns();
+ std::vector<Reference< XGridColumn > > aNewColumns(
+ comphelper::sequenceToContainer<std::vector<Reference< XGridColumn > > >(columns));
+ sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height();
+ if(m_xColumnModel->getColumnHeaderHeight() == 0)
+ {
+ m_pTableModel->setColumnHeaderHeight(fontHeight);
+ m_xColumnModel->setColumnHeaderHeight(fontHeight);
+ }
+ else
+ m_pTableModel->setColumnHeaderHeight(m_xColumnModel->getColumnHeaderHeight());
+ for ( ::svt::table::ColPos col = 0; col < m_xColumnModel->getColumnCount(); ++col )
+ {
+ UnoControlTableColumn* tableColumn = new UnoControlTableColumn(aNewColumns[col]);
+ Reference< XGridColumn > xGridColumn = m_xColumnModel->getColumn(col);
+ m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn);
+ tableColumn->setHorizontalAlign(xGridColumn->getHorizontalAlign());
+ tableColumn->setWidth(xGridColumn->getColumnWidth());
+ if(xGridColumn->getPreferredWidth() != 0)
+ tableColumn->setPreferredWidth(xGridColumn->getPreferredWidth());
+ if(xGridColumn->getMaxWidth() != 0)
+ tableColumn->setMaxWidth(xGridColumn->getMaxWidth());
+ if(xGridColumn->getMinWidth() != 0)
+ tableColumn->setMinWidth(xGridColumn->getMinWidth());
+ tableColumn->setResizable(xGridColumn->getResizeable());
+ }
+ }
+ }
+ else
+ throw GridInvalidModelException(rtl::OUString::createFromAscii("The column model isn't set!"), m_xColumnModel);
+
+ break;
+ }
+ default:
+ VCLXWindow::setProperty( PropertyName, aValue );
+ break;
+ }
+}
+
+Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ const sal_uInt16 nPropId = GetPropertyId( PropertyName );
+ TableControl* pTable = (TableControl*)GetWindow();
+ if(pTable)
+ {
+ switch(nPropId)
+ {
+ case BASEPROPERTY_GRID_SELECTIONMODE:
+ {
+ SelectionType eSelectionType;
+
+ SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode();
+ switch( eSelMode )
+ {
+ case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break;
+ case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break;
+ case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break;
+// case NO_SELECTION:
+ default: eSelectionType = SelectionType_NONE; break;
+ }
+ return Any( eSelectionType );
+ }
+ case BASEPROPERTY_GRID_SHOWROWHEADER:
+ {
+ return Any ((sal_Bool) m_pTableModel->hasRowHeaders());
+ }
+ case BASEPROPERTY_GRID_SHOWCOLUMNHEADER:
+ return Any ((sal_Bool) m_pTableModel->hasColumnHeaders());
+ case BASEPROPERTY_GRID_DATAMODEL:
+ return Any ( m_xDataModel );
+ case BASEPROPERTY_GRID_COLUMNMODEL:
+ return Any ( m_xColumnModel);
+ case BASEPROPERTY_HSCROLL:
+ return Any ( m_bHScroll);
+ case BASEPROPERTY_VSCROLL:
+ return Any ( m_bVScroll);
+ }
+ }
+ return VCLXWindow::getProperty( PropertyName );
+}
+
+void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ BASEPROPERTY_GRID_SHOWROWHEADER,
+ BASEPROPERTY_GRID_SHOWCOLUMNHEADER,
+ BASEPROPERTY_GRID_DATAMODEL,
+ BASEPROPERTY_GRID_COLUMNMODEL,
+ BASEPROPERTY_GRID_SELECTIONMODE,
+ BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND,
+ BASEPROPERTY_GRID_HEADER_BACKGROUND,
+ BASEPROPERTY_GRID_LINE_COLOR,
+ BASEPROPERTY_GRID_ROW_BACKGROUND,
+ 0);
+ VCLXWindow::ImplGetPropertyIds( rIds, true );
+}
+void SAL_CALL SVTXGridControl::setVisible( sal_Bool bVisible ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ TableControl* pTable = (TableControl*)GetWindow();
+ if ( pTable )
+ {
+ pTable->SetModel(PTableModel(m_pTableModel));
+ pTable->Show( bVisible );
+ }
+}
+void SAL_CALL SVTXGridControl::setFocus() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ if ( GetWindow())
+ GetWindow()->GrabFocus();
+}
+void SAL_CALL SVTXGridControl::rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ std::vector< Any > newRow;
+ Sequence< Any > rawRowData = Event.rowData;
+ int colCount = m_xColumnModel->getColumnCount();
+ if(colCount == 0)
+ {
+ Reference<XGridColumnListener> listener(*this,UNO_QUERY_THROW);
+ m_xColumnModel->setDefaultColumns(rawRowData.getLength());
+ for ( ::svt::table::ColPos col = 0; col < rawRowData.getLength(); ++col )
+ {
+ UnoControlTableColumn* tableColumn = new UnoControlTableColumn();
+ m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn);
+ m_xColumnModel->getColumn(col)->addColumnListener(listener);
+ }
+
+ }
+ else if((unsigned int)rawRowData.getLength()!=(unsigned)colCount)
+ throw GridInvalidDataException(rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), m_xDataModel);
+
+ for ( int k = 0; k < rawRowData.getLength(); k++)
+ newRow.push_back(rawRowData[k]);
+ m_pTableModel->getCellContent().push_back(newRow);
+ if(m_pTableModel->hasRowHeaders())
+ m_pTableModel->getRowHeaderName().push_back(Event.headerName);
+ m_pTableModel->setRowCount(m_pTableModel->getCellContent().size());
+ TableControl* pTable = (TableControl*)GetWindow();
+ pTable->InvalidateDataWindow(m_pTableModel->getCellContent().size()-1, 0, false);
+ if(pTable->isAccessibleAlive())
+ {
+ pTable->commitGridControlEvent(TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(INSERT, m_pTableModel->getRowCount()-1, m_pTableModel->getRowCount(), 0, m_pTableModel->getColumnCount())),
+ Any());
+ pTable->commitGridControlEvent(CHILD,
+ makeAny( pTable->m_pAccessTable->m_pAccessible->getTableHeader(TCTYPE_ROWHEADERBAR)),
+ Any());
+ for (sal_Int32 i = 0 ; i <= m_pTableModel->getColumnCount() ; ++i)
+ {
+ pTable->commitGridControlEvent(
+ CHILD,
+ makeAny( pTable->m_pAccessTable->m_pAccessible->getTable() ),
+ Any());
+ }
+ }
+}
+
+void SAL_CALL SVTXGridControl::rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ TableControl* pTable = (TableControl*)GetWindow();
+ if(Event.index == -1)
+ {
+ if(!isSelectionEmpty())
+ deselectAllRows();
+ if(m_pTableModel->hasRowHeaders())
+ m_pTableModel->getRowHeaderName().clear();
+ pTable->clearSelection();
+ m_pTableModel->getCellContent().clear();
+ if(pTable->isAccessibleAlive())
+ {
+ pTable->commitGridControlEvent(TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(DELETE, 0, m_pTableModel->getColumnCount(), 0, m_pTableModel->getColumnCount())),
+ Any());
+ }
+ }
+ else if(Event.index >= 0 && Event.index < m_pTableModel->getRowCount())
+ {
+ if(isSelectedIndex(Event.index))
+ {
+ Sequence<sal_Int32> selected(1);
+ selected[0]=Event.index;
+ deselectRows(selected);
+ }
+ if(m_pTableModel->hasRowHeaders())
+ m_pTableModel->getRowHeaderName().erase(m_pTableModel->getRowHeaderName().begin()+Event.index);
+ std::vector<std::vector<Any> >::iterator rowPos =m_pTableModel->getCellContent().begin() + Event.index;
+ m_pTableModel->getCellContent().erase( rowPos );
+ }
+ m_pTableModel->setRowCount(m_pTableModel->getCellContent().size());
+ pTable->InvalidateDataWindow(Event.index, Event.index, true);
+ if(pTable->isAccessibleAlive())
+ {
+ pTable->commitGridControlEvent(TABLE_MODEL_CHANGED,
+ makeAny( AccessibleTableModelChange(DELETE, Event.index, Event.index+1, 0, m_pTableModel->getColumnCount())),
+ Any());
+ }
+}
+
+void SAL_CALL SVTXGridControl::columnChanged(const ::com::sun::star::awt::grid::GridColumnEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ TableControl* pTable = (TableControl*)GetWindow();
+ if(Event.valueName == rtl::OUString::createFromAscii("ColumnResize"))
+ {
+ bool resizable = m_pTableModel->getColumnModel()[Event.index]->isResizable();
+ Event.newValue>>=resizable;
+ m_pTableModel->getColumnModel()[Event.index]->setResizable(resizable);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("ColWidth"))
+ {
+ sal_Int32 colWidth = m_pTableModel->getColumnModel()[Event.index]->getWidth();
+ Event.newValue>>=colWidth;
+ m_pTableModel->getColumnModel()[Event.index]->setWidth(colWidth);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("MaxWidth"))
+ {
+ sal_Int32 maxWidth = m_pTableModel->getColumnModel()[Event.index]->getMaxWidth();
+ Event.newValue>>=maxWidth;
+ m_pTableModel->getColumnModel()[Event.index]->setMaxWidth(maxWidth);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("MinWidth"))
+ {
+ sal_Int32 minWidth = m_pTableModel->getColumnModel()[Event.index]->getMinWidth();
+ Event.newValue>>=minWidth;
+ m_pTableModel->getColumnModel()[Event.index]->setMinWidth(minWidth);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("PrefWidth"))
+ {
+ sal_Int32 prefWidth = m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth();
+ Event.newValue>>=prefWidth;
+ m_pTableModel->getColumnModel()[Event.index]->setPreferredWidth(prefWidth);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("HAlign"))
+ {
+ ::com::sun::star::style::HorizontalAlignment hAlign = m_pTableModel->getColumnModel()[Event.index]->getHorizontalAlign();
+ Event.newValue>>=hAlign;
+ m_pTableModel->getColumnModel()[Event.index]->setHorizontalAlign(hAlign);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("UpdateWidth"))
+ {
+ if(m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth() != 0)
+ m_xColumnModel->getColumn(Event.index)->updateColumn(rtl::OUString::createFromAscii("PrefWidth"), m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth());
+ m_xColumnModel->getColumn(Event.index)->updateColumn(rtl::OUString::createFromAscii("ColWidth"), m_pTableModel->getColumnModel()[Event.index]->getWidth());
+ }
+ pTable->Invalidate();
+}
+void SAL_CALL SVTXGridControl::dataChanged(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ TableControl* pTable = (TableControl*)GetWindow();
+ if(Event.valueName == rtl::OUString::createFromAscii("RowHeight"))
+ {
+ sal_Int32 rowHeight = m_pTableModel->getRowHeight();
+ Event.newValue>>=rowHeight;
+ m_pTableModel->setRowHeight(rowHeight);
+ pTable->Invalidate();
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("RowHeaderWidth"))
+ {
+ sal_Int32 rowHeaderWidth = m_pTableModel->getRowHeaderWidth();
+ Event.newValue>>=rowHeaderWidth;
+ m_pTableModel->setRowHeaderWidth(rowHeaderWidth);
+ pTable->Invalidate();
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("RowHeaders"))
+ {
+ Sequence< rtl::OUString > headers(0);
+ Event.newValue>>=headers;
+ std::vector< rtl::OUString > headerNames( comphelper::sequenceToContainer <std::vector< rtl::OUString > >(headers) );
+ m_pTableModel->setRowHeaderName(headerNames);
+ pTable->Invalidate();
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("CellUpdated"))
+ {
+ std::vector< std::vector< Any > >& rowContent = m_pTableModel->getCellContent();
+ sal_Int32 col = -1;
+ Event.oldValue>>=col;
+ rowContent[Event.index][col] = Event.newValue;
+ pTable->InvalidateDataWindow(Event.index, Event.index, false);
+ }
+ else if(Event.valueName == rtl::OUString::createFromAscii("RowUpdated"))
+ {
+ std::vector<std::vector< Any > >& rowContent = m_pTableModel->getCellContent();
+ Sequence< sal_Int32 > cols(0);
+ Sequence< Any > values(0);
+ Event.oldValue>>=cols;
+ Event.newValue>>=values;
+ for(int i = 0; i< cols.getLength(); i++)
+ {
+ if(cols[i]>=0 && cols[i]<m_pTableModel->getColumnCount())
+ rowContent[Event.index][cols[i]]=values[i];
+ else
+ break;
+ }
+ pTable->InvalidateDataWindow(Event.index, Event.index, false);
+ }
+}
+
+void SAL_CALL SVTXGridControl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException)
+{
+ VCLXWindow::disposing( Source );
+}
+
+::sal_Int32 SAL_CALL SVTXGridControl::getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(selectedRows.empty())
+ return -1;
+ else
+ {
+ std::vector<RowPos>::iterator itStart = selectedRows.begin();
+ std::vector<RowPos>::iterator itEnd = selectedRows.end();
+ return *(std::min_element(itStart, itEnd));
+ }
+}
+
+::sal_Int32 SAL_CALL SVTXGridControl::getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(selectedRows.empty())
+ return -1;
+ else
+ {
+ std::vector<RowPos>::iterator itStart = selectedRows.begin();
+ std::vector<RowPos>::iterator itEnd = selectedRows.end();
+ return *(std::max_element(itStart, itEnd));
+ }
+}
+
+void SAL_CALL SVTXGridControl::selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode();
+ if(eSelMode != NO_SELECTION)
+ {
+ sal_Int32 start = rangeOfRows[0];
+ int seqSize = rangeOfRows.getLength();
+ sal_Int32 end = rangeOfRows[seqSize-1];
+ if((start >= 0 && start < m_pTableModel->getRowCount()) && (end >= 0 && end < m_pTableModel->getRowCount()))
+ {
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(eSelMode == SINGLE_SELECTION)
+ {
+ if(!selectedRows.empty())
+ selectedRows.clear();
+ if(rangeOfRows.getLength() == 1)
+ selectedRows.push_back(start);
+ else
+ return;
+ }
+ else
+ {
+ for(int i=0;i<seqSize;i++)
+ {
+ if(!isSelectedIndex(rangeOfRows[i]))
+ selectedRows.push_back(rangeOfRows[i]);
+ }
+ }
+ pTable->selectionChanged(true);
+ pTable->InvalidateDataWindow(start, end, false);
+ SetSynthesizingVCLEvent( sal_True );
+ pTable->Select();
+ SetSynthesizingVCLEvent( sal_False );
+ }
+ }
+}
+
+void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode();
+ if(eSelMode != NO_SELECTION)
+ {
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(!selectedRows.empty())
+ selectedRows.clear();
+ for(int i=0;i<m_pTableModel->getRowCount();i++)
+ selectedRows.push_back(i);
+ pTable->Invalidate();
+ SetSynthesizingVCLEvent( sal_True );
+ pTable->Select();
+ SetSynthesizingVCLEvent( sal_False );
+ }
+}
+
+void SAL_CALL SVTXGridControl::deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ std::vector<RowPos>::iterator itStart = selectedRows.begin();
+ std::vector<RowPos>::iterator itEnd = selectedRows.end();
+ for(int i = 0; i < rangeOfRows.getLength(); i++ )
+ {
+ std::vector<RowPos>::iterator iter = std::find(itStart, itEnd, rangeOfRows[i]);
+ selectedRows.erase(iter);
+ }
+ pTable->selectionChanged(true);
+ pTable->Invalidate();
+ SetSynthesizingVCLEvent( sal_True );
+ pTable->Select();
+ SetSynthesizingVCLEvent( sal_False );
+}
+
+void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(!selectedRows.empty())
+ selectedRows.clear();
+ pTable->Invalidate();
+ SetSynthesizingVCLEvent( sal_True );
+ pTable->Select();
+ SetSynthesizingVCLEvent( sal_False );
+}
+
+::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ Sequence<sal_Int32> selectedRowsToSequence(comphelper::containerToSequence(selectedRows));
+ return selectedRowsToSequence;
+}
+
+::sal_Bool SAL_CALL SVTXGridControl::isCellEditable() throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL SVTXGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(selectedRows.empty())
+ return sal_True;
+ else
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL SVTXGridControl::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
+{
+ TableControl* pTable = (TableControl*)GetWindow();
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ return std::find(selectedRows.begin(),selectedRows.end(), index) != selectedRows.end();
+}
+
+void SAL_CALL SVTXGridControl::selectRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
+{
+ if(index<0 || index>=m_pTableModel->getRowCount())
+ return;
+ TableControl* pTable = (TableControl*)GetWindow();
+ SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode();
+ if(eSelMode != NO_SELECTION)
+ {
+ std::vector<RowPos>& selectedRows = pTable->GetSelectedRows();
+ if(eSelMode == MULTIPLE_SELECTION)
+ {
+ if(!isSelectedIndex(index))
+ selectedRows.push_back(index);
+ else
+ return;
+ }
+ else if(eSelMode == SINGLE_SELECTION)
+ {
+ if(!selectedRows.empty())
+ {
+ if(!isSelectedIndex(index))
+ deselectRows(getSelection());
+ else
+ return;
+ }
+ selectedRows.push_back(index);
+ }
+ pTable->selectionChanged(true);
+ pTable->InvalidateDataWindow(index, index, false);
+ SetSynthesizingVCLEvent( sal_True );
+ pTable->Select();
+ SetSynthesizingVCLEvent( sal_False );
+ }
+}
+
+void SAL_CALL SVTXGridControl::selectColumn(::sal_Int32 x) throw (::com::sun::star::uno::RuntimeException)
+{
+ (void)x;
+}
+void SVTXGridControl::dispose() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::lang::EventObject aObj;
+ aObj.Source = (::cppu::OWeakObject*)this;
+ m_aSelectionListeners.disposeAndClear( aObj );
+ VCLXWindow::dispose();
+}
+
+void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xKeepAlive( this );
+
+ switch ( rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_TABLEROW_SELECT:
+ {
+ TableControl* pTable = (TableControl*)GetWindow();
+
+ if( pTable )
+ {
+ if ( m_aSelectionListeners.getLength() )
+ {
+ ImplCallItemListeners();
+ }
+ }
+ }
+ break;
+
+ default:
+ VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
+ break;
+ }
+}
+
+void SVTXGridControl::ImplCallItemListeners()
+{
+ TableControl* pTable = (TableControl*) GetWindow();
+ if ( pTable && m_aSelectionListeners.getLength() )
+ {
+ ::std::vector<sal_Int32> selRows = pTable->GetSelectedRows();
+ ::com::sun::star::awt::grid::GridSelectionEvent aEvent;
+ aEvent.Source = (::cppu::OWeakObject*)this;
+ aEvent.Column = 0;
+ sal_Int32 actSelRowCount = selRows.size();
+ sal_Int32 diff = actSelRowCount - m_nSelectedRowCount;
+ //row added to selection
+ if(diff >= 1)
+ {
+ aEvent.Action = com::sun::star::awt::grid::SelectionEventType(0);
+ aEvent.Row = selRows[actSelRowCount-1];
+ aEvent.Range = diff;
+ }
+ //selected row changed
+ else if(diff == 0 && actSelRowCount != 0)
+ {
+ aEvent.Row = selRows[actSelRowCount-1];
+ aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2);
+ aEvent.Range = 0;
+ }
+ else
+ {
+ //selection changed: multiple row deselected, only 1 row is selected
+ if(actSelRowCount == 1)
+ {
+ aEvent.Row = selRows[actSelRowCount-1];
+ aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2);
+ }
+ //row is deselected
+ else
+ {
+ aEvent.Row = pTable->GetCurrentRow();
+ aEvent.Action = com::sun::star::awt::grid::SelectionEventType(1);
+ }
+ aEvent.Range = 0;
+ }
+ m_nSelectedRowCount=actSelRowCount;
+ m_aSelectionListeners.selectionChanged( aEvent );
+ }
+}
diff --git a/svtools/source/uno/svtxgridcontrol.hxx b/svtools/source/uno/svtxgridcontrol.hxx
new file mode 100755
index 000000000000..b15507e4614f
--- /dev/null
+++ b/svtools/source/uno/svtxgridcontrol.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 _SVT_GRIDCONTROL_HXX_
+#define _SVT_GRIDCONTROL_HXX_
+
+#include <unocontroltablemodel.hxx>
+#include <svtools/table/tablecontrol.hxx>
+#include <com/sun/star/awt/grid/XGridControl.hpp>
+#include <com/sun/star/awt/grid/XGridDataListener.hpp>
+#include <com/sun/star/awt/grid/XGridColumnListener.hpp>
+#include <com/sun/star/awt/grid/GridDataEvent.hpp>
+#include <com/sun/star/awt/grid/GridColumnEvent.hpp>
+#include <com/sun/star/awt/grid/XGridColumnModel.hpp>
+#include <com/sun/star/awt/grid/XGridDataModel.hpp>
+#include <com/sun/star/awt/grid/XGridSelectionListener.hpp>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxwindows.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <toolkit/helper/listenermultiplexer.hxx>
+
+
+using namespace ::svt::table;
+
+class SVTXGridControl : public ::cppu::ImplInheritanceHelper3< VCLXWindow, ::com::sun::star::awt::grid::XGridControl,
+ ::com::sun::star::awt::grid::XGridDataListener, ::com::sun::star::awt::grid::XGridColumnListener>
+{
+private:
+ ::boost::shared_ptr< UnoControlTableModel > m_pTableModel;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >m_xDataModel;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >m_xColumnModel;
+ bool m_bHasColumnHeaders;
+ bool m_bHasRowHeaders;
+ bool m_bVScroll;
+ bool m_bHScroll;
+ bool m_bUpdate;
+ sal_Int32 m_nSelectedRowCount;
+ SelectionListenerMultiplexer m_aSelectionListeners;
+
+protected:
+ virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
+ void ImplCallItemListeners();
+
+public:
+ SVTXGridControl();
+ ~SVTXGridControl();
+ //XGridDataListener overridables
+ virtual void SAL_CALL rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL dataChanged(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException);
+
+ //XGridColumnListener overridables
+ virtual void SAL_CALL columnChanged(const ::com::sun::star::awt::grid::GridColumnEvent & Event) throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { VCLXWindow::acquire(); }
+ void SAL_CALL release() throw() { VCLXWindow::release(); }
+
+ // ::com::sun::star::lang::XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+
+ //::com::sun::star::awt::grid::XGridControl
+ virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isCellEditable() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectColumn(::sal_Int32 x) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException);
+
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+ static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
+ void SAL_CALL setVisible(sal_Bool bVisible) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setFocus() throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XComponent
+ void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException);
+ };
+ #endif // _SVT_GRIDCONTROL_HXX_
diff --git a/svtools/source/uno/toolboxcontroller.cxx b/svtools/source/uno/toolboxcontroller.cxx
new file mode 100644
index 000000000000..bdb2256a07e8
--- /dev/null
+++ b/svtools/source/uno/toolboxcontroller.cxx
@@ -0,0 +1,886 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+#include <svtools/toolboxcontroller.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <imgdef.hxx>
+#include <svtools/miscopt.hxx>
+
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+#include <vcl/toolbox.hxx>
+//shizhobo
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+const int TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE = 1;
+const int TOOLBARCONTROLLER_PROPCOUNT = 1;
+const rtl::OUString TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE( RTL_CONSTASCII_USTRINGPARAM( "SupportsVisiable" ));
+//end
+
+using ::rtl::OUString;
+
+using namespace ::cppu;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame;
+
+namespace svt
+{
+
+struct DispatchInfo
+{
+ Reference< XDispatch > mxDispatch;
+ const URL maURL;
+ const Sequence< PropertyValue > maArgs;
+
+ DispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
+ : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
+};
+
+struct ToolboxController_Impl
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParentWindow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xUrlTransformer;
+ rtl::OUString m_sModuleName;
+ sal_uInt16 m_nToolBoxId;
+
+ DECL_STATIC_LINK( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo* );
+
+ ToolboxController_Impl()
+ : m_nToolBoxId( SAL_MAX_UINT16 )
+ {}
+};
+
+ToolboxController::ToolboxController(
+
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& xFrame,
+ const ::rtl::OUString& aCommandURL ) :
+ OPropertyContainer(GetBroadcastHelper())
+ , OWeakObject()
+ , m_bInitialized( sal_False )
+ , m_bDisposed( sal_False )
+ , m_xFrame(xFrame)
+ , m_xServiceManager( rServiceManager )
+ , m_aCommandURL( aCommandURL )
+ , m_aListenerContainer( m_aMutex )
+{
+ //registger Propertyh by shizhoubo
+ registerProperty(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE, TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE, com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY,
+ &m_bSupportVisiable, getCppuType(&m_bSupportVisiable));
+
+ m_pImpl = new ToolboxController_Impl;
+
+ try
+ {
+ m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ }
+ catch(const Exception&)
+ {
+ }
+}
+
+ToolboxController::ToolboxController() :
+ OPropertyContainer(GetBroadcastHelper())
+ , OWeakObject()
+ , m_bInitialized( sal_False )
+ , m_bDisposed( sal_False )
+ , m_aListenerContainer( m_aMutex )
+{
+ //registger Propertyh by shizhoubo
+ registerProperty(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE, TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE, com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY,
+ &m_bSupportVisiable, getCppuType(&m_bSupportVisiable));
+
+ m_pImpl = new ToolboxController_Impl;
+}
+
+ToolboxController::~ToolboxController()
+{
+ delete m_pImpl;
+}
+
+Reference< XFrame > ToolboxController::getFrameInterface() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_xFrame;
+}
+
+Reference< XMultiServiceFactory > ToolboxController::getServiceManager() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_xServiceManager;
+}
+
+Reference< XLayoutManager > ToolboxController::getLayoutManager() const
+{
+ Reference< XLayoutManager > xLayoutManager;
+ Reference< XPropertySet > xPropSet;
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ xPropSet = Reference< XPropertySet >( m_xFrame, UNO_QUERY );
+ }
+
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xLayoutManager.set(xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY);
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return xLayoutManager;
+}
+
+// XInterface
+Any SAL_CALL ToolboxController::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ static_cast< XToolbarController* >( this ),
+ static_cast< XStatusListener* >( this ),
+ static_cast< XEventListener* >( this ),
+ static_cast< XInitialization* >( this ),
+ static_cast< XComponent* >( this ),
+ static_cast< XUpdatable* >( this ));
+ if ( !a.hasValue())
+ {
+ a = ::cppu::queryInterface(rType
+ ,static_cast<XPropertySet*>(this)
+ ,static_cast<XMultiPropertySet*>(this)
+ ,static_cast<XFastPropertySet*>(this));
+ if (!a.hasValue())
+ return OWeakObject::queryInterface( rType );
+ }
+ return a;
+}
+
+void SAL_CALL ToolboxController::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ToolboxController::release() throw ()
+{
+ OWeakObject::release();
+}
+
+void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments )
+throw ( Exception, RuntimeException )
+{
+ bool bInitialized( true );
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ bInitialized = m_bInitialized;
+ }
+
+ if ( !bInitialized )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ m_bInitialized = sal_True;
+ //shizhoubo add
+ m_bSupportVisiable = sal_False;
+ PropertyValue aPropValue;
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Frame") ))
+ m_xFrame.set(aPropValue.Value,UNO_QUERY);
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CommandURL") ))
+ aPropValue.Value >>= m_aCommandURL;
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ServiceManager") ))
+ m_xServiceManager.set(aPropValue.Value,UNO_QUERY);
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ))
+ m_pImpl->m_xParentWindow.set(aPropValue.Value,UNO_QUERY);
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ModuleName" ) ) )
+ aPropValue.Value >>= m_pImpl->m_sModuleName;
+ }
+ }
+
+ try
+ {
+ if ( !m_pImpl->m_xUrlTransformer.is() && m_xServiceManager.is() )
+ m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+ }
+ catch(const Exception&)
+ {
+ }
+
+ if ( m_aCommandURL.getLength() )
+ m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() ));
+ }
+}
+
+void SAL_CALL ToolboxController::update()
+throw ( RuntimeException )
+{
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ // Bind all registered listeners to their dispatch objects
+ bindListener();
+}
+
+// XComponent
+void SAL_CALL ToolboxController::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ try
+ {
+ Reference< XDispatch > xDispatch( pIter->second );
+
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ ++pIter;
+ }
+
+ m_bDisposed = sal_True;
+}
+
+void SAL_CALL ToolboxController::addEventListener( const Reference< XEventListener >& xListener )
+throw ( RuntimeException )
+{
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL ToolboxController::removeEventListener( const Reference< XEventListener >& aListener )
+throw ( RuntimeException )
+{
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener );
+}
+
+// XEventListener
+void SAL_CALL ToolboxController::disposing( const EventObject& Source )
+throw ( RuntimeException )
+{
+ Reference< XInterface > xSource( Source.Source );
+
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ return;
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ // Compare references and release dispatch references if they are equal.
+ Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
+ if ( xSource == xIfac )
+ pIter->second.clear();
+ ++pIter;
+ }
+
+ Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
+ if ( xIfac == xSource )
+ m_xFrame.clear();
+}
+
+// XStatusListener
+void SAL_CALL ToolboxController::statusChanged( const FeatureStateEvent& )
+throw ( RuntimeException )
+{
+ // must be implemented by sub class
+}
+
+// XToolbarController
+void SAL_CALL ToolboxController::execute( sal_Int16 KeyModifier )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XDispatch > xDispatch;
+ ::rtl::OUString aCommandURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+
+ aCommandURL = m_aCommandURL;
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ xDispatch = pIter->second;
+ }
+ }
+
+ if ( xDispatch.is() )
+ {
+ try
+ {
+ com::sun::star::util::URL aTargetURL;
+ Sequence<PropertyValue> aArgs( 1 );
+
+ // Provide key modifier information to dispatch function
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value = makeAny( KeyModifier );
+
+ aTargetURL.Complete = aCommandURL;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+ catch ( DisposedException& )
+ {
+ }
+ }
+}
+
+void SAL_CALL ToolboxController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL ToolboxController::doubleClick()
+throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+Reference< XWindow > SAL_CALL ToolboxController::createPopupWindow()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XWindow >();
+}
+
+Reference< XWindow > SAL_CALL ToolboxController::createItemWindow( const Reference< XWindow >& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XWindow >();
+}
+
+void ToolboxController::addStatusListener( const rtl::OUString& aCommandURL )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+
+ // Already in the list of status listener. Do nothing.
+ if ( pIter != m_aListenerMap.end() )
+ return;
+
+ // Check if we are already initialized. Implementation starts adding itself as status listener when
+ // intialize is called.
+ if ( !m_bInitialized )
+ {
+ // Put into the hash_map of status listener. Will be activated when initialized is called
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
+ return;
+ }
+ else
+ {
+ // Add status listener directly as intialize has already been called.
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ aTargetURL.Complete = aCommandURL;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
+ if ( aIter != m_aListenerMap.end() )
+ {
+ Reference< XDispatch > xOldDispatch( aIter->second );
+ aIter->second = xDispatch;
+
+ try
+ {
+ if ( xOldDispatch.is() )
+ xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else
+ m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
+ }
+ }
+ }
+
+ // Call without locked mutex as we are called back from dispatch implementation
+ try
+ {
+ if ( xDispatch.is() )
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+void ToolboxController::removeStatusListener( const rtl::OUString& aCommandURL )
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ {
+ Reference< XDispatch > xDispatch( pIter->second );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ m_aListenerMap.erase( pIter );
+
+ try
+ {
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = aCommandURL;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void ToolboxController::bindListener()
+{
+ std::vector< Listener > aDispatchVector;
+ Reference< XStatusListener > xStatusListener;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Collect all registered command URL's and store them temporary
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch( pIter->second );
+ if ( xDispatch.is() )
+ {
+ // We already have a dispatch object => we have to requery.
+ // Release old dispatch object and remove it as listener
+ try
+ {
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ pIter->second.clear();
+ xDispatch.clear();
+
+ // Query for dispatch object. Old dispatch will be released with this, too.
+ try
+ {
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ }
+ catch ( Exception& )
+ {
+ }
+ pIter->second = xDispatch;
+
+ Listener aListener( aTargetURL, xDispatch );
+ aDispatchVector.push_back( aListener );
+ ++pIter;
+ }
+ }
+ }
+
+ // Call without locked mutex as we are called back from dispatch implementation
+ if ( xStatusListener.is() )
+ {
+ try
+ {
+ for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
+ {
+ Listener& rListener = aDispatchVector[i];
+ if ( rListener.xDispatch.is() )
+ rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
+ else if ( rListener.aURL.Complete == m_aCommandURL )
+ {
+ try
+ {
+ // Send status changed for the main URL, if we cannot get a valid dispatch object.
+ // UI disables the button. Catch exception as we release our mutex, it is possible
+ // that someone else already disposed this instance!
+ FeatureStateEvent aFeatureStateEvent;
+ aFeatureStateEvent.IsEnabled = sal_False;
+ aFeatureStateEvent.FeatureURL = rListener.aURL;
+ aFeatureStateEvent.State = Any();
+ xStatusListener->statusChanged( aFeatureStateEvent );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void ToolboxController::unbindListener()
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Collect all registered command URL's and store them temporary
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
+ while ( pIter != m_aListenerMap.end() )
+ {
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = pIter->first;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch( pIter->second );
+ if ( xDispatch.is() )
+ {
+ // We already have a dispatch object => we have to requery.
+ // Release old dispatch object and remove it as listener
+ try
+ {
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ pIter->second.clear();
+ ++pIter;
+ }
+ }
+}
+
+sal_Bool ToolboxController::isBound() const
+{
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return sal_False;
+
+ URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ return ( pIter->second.is() );
+
+ return sal_False;
+}
+
+sal_Bool ToolboxController::hasBigImages() const
+{
+ return SvtMiscOptions().AreCurrentSymbolsLarge();
+}
+
+sal_Bool ToolboxController::isHighContrast() const
+{
+ sal_Bool bHighContrast( sal_False );
+
+ Reference< XWindow > xWindow = m_pImpl->m_xParentWindow;
+ if ( xWindow.is() )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ bHighContrast = ( ((ToolBox *)pWindow)->GetSettings().GetStyleSettings().GetHighContrastMode() );
+ }
+
+ return bHighContrast;
+}
+
+void ToolboxController::updateStatus()
+{
+ bindListener();
+}
+
+void ToolboxController::updateStatus( const rtl::OUString aCommandURL )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ com::sun::star::util::URL aTargetURL;
+
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ if ( !m_bInitialized )
+ return;
+
+ // Try to find a dispatch object for the requested command URL
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ if ( m_xServiceManager.is() && xDispatchProvider.is() )
+ {
+ aTargetURL.Complete = aCommandURL;
+ if ( m_pImpl->m_xUrlTransformer.is() )
+ m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 );
+ }
+ }
+
+ if ( xDispatch.is() && xStatusListener.is() )
+ {
+ // Catch exception as we release our mutex, it is possible that someone else
+ // has already disposed this instance!
+ // Add/remove status listener to get a update status information from the
+ // requested command.
+ try
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+Reference< XURLTransformer > ToolboxController::getURLTransformer() const
+{
+ return m_pImpl->m_xUrlTransformer;
+}
+
+Reference< ::com::sun::star::awt::XWindow > ToolboxController::getParent() const
+{
+ return m_pImpl->m_xParentWindow;
+}
+
+const rtl::OUString& ToolboxController::getModuleName() const
+{
+ return m_pImpl->m_sModuleName;
+}
+
+void ToolboxController::dispatchCommand( const OUString& sCommandURL, const Sequence< PropertyValue >& rArgs )
+{
+ try
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
+ URL aURL;
+ aURL.Complete = sCommandURL;
+ getURLTransformer()->parseStrict( aURL );
+
+ Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
+
+ Application::PostUserEvent( STATIC_LINK(0, ToolboxController_Impl, ExecuteHdl_Impl), new DispatchInfo( xDispatch, aURL, rArgs ) );
+
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+//
+//-------------------------------------------------------------------------
+// XPropertySet by shizhoubo
+com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL ToolboxController::getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+}
+//-------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& ToolboxController::getInfoHelper()
+{
+ return *const_cast<ToolboxController*>(this)->getArrayHelper();
+}
+//OPropertyArrayUsageHelper by shizhoubo
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* ToolboxController::createArrayHelper( ) const
+{
+ com::sun::star::uno::Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+//shizhoubo for supportsvisiable
+void ToolboxController::setSupportVisiableProperty(sal_Bool bValue)
+{
+ m_bSupportVisiable = bValue;
+}
+//OPropertySetHelper by shizhoubo
+sal_Bool SAL_CALL ToolboxController::convertFastPropertyValue( com::sun::star::uno::Any& aConvertedValue ,
+ com::sun::star::uno::Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const com::sun::star::uno::Any& aValue ) throw( com::sun::star::lang::IllegalArgumentException )
+{
+ switch (nHandle)
+ {
+ case TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE:
+ {
+ sal_Bool aNewValue(sal_False);
+ aValue >>= aNewValue;
+ if (aNewValue != m_bSupportVisiable)
+ {
+ aConvertedValue <<= aNewValue;
+ aOldValue <<= m_bSupportVisiable;
+ return sal_True;
+ }
+ return sal_False;
+ }
+ }
+ return OPropertyContainer::convertFastPropertyValue(aConvertedValue, aOldValue, nHandle, aValue);
+}
+
+void SAL_CALL ToolboxController::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const com::sun::star::uno::Any& aValue )
+throw( com::sun::star::uno::Exception)
+{
+ OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, aValue);
+ if (TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE == nHandle)
+ {
+ sal_Bool rValue(sal_False);
+ if (( aValue >>= rValue ) && m_bInitialized)
+ this->setSupportVisiableProperty( rValue );
+ }
+}
+
+//--------------------------------------------------------------------
+
+IMPL_STATIC_LINK_NOINSTANCE( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo*, pDispatchInfo )
+{
+ pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
+ delete pDispatchInfo;
+ return 0;
+}
+
+void ToolboxController::enable( bool bEnable )
+{
+ ToolBox* pToolBox = 0;
+ sal_uInt16 nItemId = 0;
+ if( getToolboxId( nItemId, &pToolBox ) )
+ {
+ pToolBox->EnableItem( nItemId, bEnable ? TRUE : FALSE );
+ }
+}
+
+bool ToolboxController::getToolboxId( sal_uInt16& rItemId, ToolBox** ppToolBox )
+{
+ if( (m_pImpl->m_nToolBoxId != SAL_MAX_UINT16) && (ppToolBox == 0) )
+ return m_pImpl->m_nToolBoxId;
+
+ ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+
+ if( (m_pImpl->m_nToolBoxId == SAL_MAX_UINT16) && pToolBox )
+ {
+ const sal_uInt16 nCount = pToolBox->GetItemCount();
+ for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
+ {
+ const sal_uInt16 nItemId = pToolBox->GetItemId( nPos );
+ if ( pToolBox->GetItemCommand( nItemId ) == String( m_aCommandURL ) )
+ {
+ m_pImpl->m_nToolBoxId = nItemId;
+ break;
+ }
+ }
+ }
+
+ if( ppToolBox )
+ *ppToolBox = pToolBox;
+
+ rItemId = m_pImpl->m_nToolBoxId;
+
+ return (rItemId != SAL_MAX_UINT16) && (( ppToolBox == 0) || (*ppToolBox != 0) );
+}
+//end
+
+} // svt
diff --git a/svtools/source/uno/treecontrolpeer.cxx b/svtools/source/uno/treecontrolpeer.cxx
new file mode 100644
index 000000000000..7fb1a007960f
--- /dev/null
+++ b/svtools/source/uno/treecontrolpeer.cxx
@@ -0,0 +1,1747 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SVTREEBX_CXX
+#include <tools/debug.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/view/SelectionType.hpp>
+#include <toolkit/helper/property.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <com/sun/star/awt/tree/XMutableTreeNode.hpp>
+#include <treecontrolpeer.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <rtl/ref.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/svtreebx.hxx>
+
+#include <map>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::awt::tree;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::graphic;
+
+#define O(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+struct LockGuard
+{
+public:
+ LockGuard( sal_Int32& rLock )
+ : mrLock( rLock )
+ {
+ rLock++;
+ }
+
+ ~LockGuard()
+ {
+ mrLock--;
+ }
+
+ sal_Int32& mrLock;
+};
+
+// --------------------------------------------------------------------
+
+class ImplGraphicItem : public SvLBoxBmp
+{
+public:
+ ImplGraphicItem( SvLBoxEntry* pEntry, USHORT nFlags, Image& aImage ) : SvLBoxBmp( pEntry, nFlags, aImage ) {}
+
+ OUString msGraphicURL;
+};
+
+// --------------------------------------------------------------------
+
+class ImplContextGraphicItem : public SvLBoxContextBmp
+{
+public:
+ ImplContextGraphicItem( SvLBoxEntry* pEntry,USHORT nFlags,Image& rI1,Image& rI2, USHORT nEntryFlagsBmp1)
+ : SvLBoxContextBmp( pEntry, nFlags, rI1, rI2, nEntryFlagsBmp1 ) {}
+
+ OUString msExpandedGraphicURL;
+ OUString msCollapsedGraphicURL;
+};
+
+// --------------------------------------------------------------------
+
+class UnoTreeListBoxImpl : public SvTreeListBox
+{
+public:
+ UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle );
+ ~UnoTreeListBoxImpl();
+
+ sal_uInt32 insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,ULONG nPos=LIST_APPEND );
+
+ virtual void RequestingChilds( SvLBoxEntry* pParent );
+
+ virtual BOOL EditingEntry( SvLBoxEntry* pEntry, Selection& );
+ virtual BOOL EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText );
+
+ DECL_LINK( OnSelectionChangeHdl, UnoTreeListBoxImpl* );
+ DECL_LINK( OnExpandingHdl, UnoTreeListBoxImpl* );
+ DECL_LINK( OnExpandedHdl, UnoTreeListBoxImpl* );
+
+private:
+ rtl::Reference< TreeControlPeer > mxPeer;
+};
+
+// --------------------------------------------------------------------
+
+class SVT_DLLPUBLIC UnoTreeListItem : public SvLBoxItem
+{
+public:
+ UnoTreeListItem( SvLBoxEntry* );
+ UnoTreeListItem();
+ virtual ~UnoTreeListItem();
+ virtual USHORT IsA();
+ void InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* );
+ OUString GetText() const;
+ void SetText( const OUString& rText );
+ Image GetImage() const;
+ void SetImage( const Image& rImage );
+ OUString GetGraphicURL() const;
+ void SetGraphicURL( const OUString& rGraphicURL );
+ void Paint( const Point&, SvLBox& rDev, USHORT nFlags,SvLBoxEntry* );
+ SvLBoxItem* Create() const;
+ void Clone( SvLBoxItem* pSource );
+
+private:
+ OUString maText;
+ OUString maGraphicURL;
+ Image maImage;
+};
+
+// --------------------------------------------------------------------
+
+class UnoTreeListEntry : public SvLBoxEntry
+{
+public:
+ UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer );
+ virtual ~UnoTreeListEntry();
+
+ Reference< XTreeNode > mxNode;
+ TreeControlPeer* mpPeer;
+};
+
+// --------------------------------------------------------------------
+
+class TreeNodeMap : public std::map< Reference< XTreeNode >, UnoTreeListEntry* >
+{
+};
+
+// --------------------------------------------------------------------
+
+TreeControlPeer::TreeControlPeer()
+: maSelectionListeners( *this )
+, maTreeExpansionListeners( *this )
+, maTreeEditListeners( *this )
+, mpTreeImpl( 0 )
+, mnEditLock( 0 )
+, mpTreeNodeMap( 0 )
+{
+}
+
+// --------------------------------------------------------------------
+
+TreeControlPeer::~TreeControlPeer()
+{
+ if( mpTreeImpl )
+ mpTreeImpl->Clear();
+ delete mpTreeNodeMap;
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry )
+{
+ if( pEntry && pEntry->mxNode.is() )
+ {
+ if( !mpTreeNodeMap )
+ {
+ mpTreeNodeMap = new TreeNodeMap();
+ }
+
+ (*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::removeEntry( UnoTreeListEntry* pEntry )
+{
+ if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() )
+ {
+ TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) );
+ if( aIter != mpTreeNodeMap->end() )
+ {
+ mpTreeNodeMap->erase( aIter );
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode, bool bThrow /* = true */ ) throw( IllegalArgumentException )
+{
+ if( mpTreeNodeMap )
+ {
+ TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) );
+ if( aIter != mpTreeNodeMap->end() )
+ return (*aIter).second;
+ }
+
+ if( bThrow )
+ throw IllegalArgumentException();
+
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+Window* TreeControlPeer::createVclControl( Window* pParent, sal_Int64 nWinStyle )
+{
+ mpTreeImpl = new UnoTreeListBoxImpl( this, pParent, nWinStyle );
+ return mpTreeImpl;
+}
+
+// --------------------------------------------------------------------
+
+/** called from the UnoTreeListBoxImpl when it gets deleted */
+void TreeControlPeer::disposeControl()
+{
+ delete mpTreeNodeMap;
+ mpTreeNodeMap = 0;
+ mpTreeImpl = 0;
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::SetWindow( Window* pWindow )
+{
+ VCLXWindow::SetWindow( pWindow );
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListEntry* TreeControlPeer::createEntry( const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParent, ULONG nPos /* = LIST_APPEND */ )
+{
+ UnoTreeListEntry* pEntry = 0;
+ if( mpTreeImpl )
+ {
+ Image aImage;
+ pEntry = new UnoTreeListEntry( xNode, this );
+ ImplContextGraphicItem* pContextBmp= new ImplContextGraphicItem( pEntry,0, aImage, aImage, SVLISTENTRYFLAG_EXPANDED );
+
+ pEntry->AddItem( pContextBmp );
+
+ UnoTreeListItem * pUnoItem = new UnoTreeListItem( pEntry );
+
+ if( xNode->getNodeGraphicURL().getLength() )
+ {
+ pUnoItem->SetGraphicURL( xNode->getNodeGraphicURL() );
+ Image aNodeImage;
+ loadImage( xNode->getNodeGraphicURL(), aNodeImage );
+ pUnoItem->SetImage( aNodeImage );
+ mpTreeImpl->AdjustEntryHeight( aNodeImage );
+ }
+
+ pEntry->AddItem( pUnoItem );
+
+ mpTreeImpl->insert( pEntry, pParent, nPos );
+
+ if( msDefaultExpandedGraphicURL.getLength() )
+ mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage );
+
+ if( msDefaultCollapsedGraphicURL.getLength() )
+ mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage );
+
+ updateEntry( pEntry );
+ }
+ return pEntry;
+}
+
+// --------------------------------------------------------------------
+
+bool TreeControlPeer::updateEntry( UnoTreeListEntry* pEntry )
+{
+ bool bChanged = false;
+ if( pEntry && pEntry->mxNode.is() && mpTreeImpl )
+ {
+ const OUString aValue( getEntryString( pEntry->mxNode->getDisplayValue() ) );
+ UnoTreeListItem* pUnoItem = dynamic_cast< UnoTreeListItem* >( pEntry->GetItem( 1 ) );
+ if( pUnoItem )
+ {
+ if( aValue != pUnoItem->GetText() )
+ {
+ pUnoItem->SetText( aValue );
+ bChanged = true;
+ }
+
+ if( pUnoItem->GetGraphicURL() != pEntry->mxNode->getNodeGraphicURL() )
+ {
+ Image aImage;
+ if( loadImage( pEntry->mxNode->getNodeGraphicURL(), aImage ) )
+ {
+ pUnoItem->SetGraphicURL( pEntry->mxNode->getNodeGraphicURL() );
+ pUnoItem->SetImage( aImage );
+ mpTreeImpl->AdjustEntryHeight( aImage );
+ bChanged = true;
+ }
+ }
+ }
+
+ if( (pEntry->mxNode->hasChildrenOnDemand() == sal_True) != (pEntry->HasChildsOnDemand() == TRUE) )
+ {
+ pEntry->EnableChildsOnDemand( pEntry->mxNode->hasChildrenOnDemand() ? TRUE : FALSE );
+ bChanged = true;
+ }
+
+ ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) );
+ if( pContextGraphicItem )
+ {
+ if( pContextGraphicItem->msExpandedGraphicURL != pEntry->mxNode->getExpandedGraphicURL() )
+ {
+ Image aImage;
+ if( loadImage( pEntry->mxNode->getExpandedGraphicURL(), aImage ) )
+ {
+ pContextGraphicItem->msExpandedGraphicURL = pEntry->mxNode->getExpandedGraphicURL();
+ mpTreeImpl->SetExpandedEntryBmp( pEntry, aImage );
+ bChanged = true;
+ }
+ }
+ if( pContextGraphicItem->msCollapsedGraphicURL != pEntry->mxNode->getCollapsedGraphicURL() )
+ {
+ Image aImage;
+ if( loadImage( pEntry->mxNode->getCollapsedGraphicURL(), aImage ) )
+ {
+ pContextGraphicItem->msCollapsedGraphicURL = pEntry->mxNode->getCollapsedGraphicURL();
+ mpTreeImpl->SetCollapsedEntryBmp( pEntry, aImage );
+ bChanged = true;
+ }
+ }
+ }
+
+ if( bChanged )
+ mpTreeImpl->GetModel()->InvalidateEntry( pEntry );
+ }
+
+ return bChanged;
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::onSelectionChanged()
+{
+ Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
+ EventObject aEvent( xSource );
+ maSelectionListeners.selectionChanged( aEvent );
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::onRequestChildNodes( const Reference< XTreeNode >& xNode )
+{
+ try
+ {
+ Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
+ TreeExpansionEvent aEvent( xSource, xNode );
+ maTreeExpansionListeners.requestChildNodes( aEvent );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool TreeControlPeer::onExpanding( const Reference< XTreeNode >& xNode, bool bExpanding )
+{
+ try
+ {
+ Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
+ TreeExpansionEvent aEvent( xSource, xNode );
+ if( bExpanding )
+ {
+ maTreeExpansionListeners.treeExpanding( aEvent );
+ }
+ else
+ {
+ maTreeExpansionListeners.treeCollapsing( aEvent );
+ }
+ }
+ catch( Exception& )
+ {
+ return false;
+ }
+ return true;
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::onExpanded( const Reference< XTreeNode >& xNode, bool bExpanding )
+{
+ try
+ {
+ Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
+ TreeExpansionEvent aEvent( xSource, xNode );
+
+ if( bExpanding )
+ {
+ maTreeExpansionListeners.treeExpanded( aEvent );
+ }
+ else
+ {
+ maTreeExpansionListeners.treeCollapsed( aEvent );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::fillTree( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel )
+{
+ rTree.Clear();
+
+ if( xDataModel.is() )
+ {
+ Reference< XTreeNode > xRootNode( xDataModel->getRoot() );
+ if( xRootNode.is() )
+ {
+ if( mbIsRootDisplayed )
+ {
+ addNode( rTree, xRootNode, 0 );
+ }
+ else
+ {
+ const sal_Int32 nChildCount = xRootNode->getChildCount();
+ for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ )
+ addNode( rTree, xRootNode->getChildAt( nChild ), 0 );
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::addNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParentEntry )
+{
+ if( xNode.is() )
+ {
+ UnoTreeListEntry* pEntry = createEntry( xNode, pParentEntry, LIST_APPEND );
+ const sal_Int32 nChildCount = xNode->getChildCount();
+ for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ )
+ addNode( rTree, xNode->getChildAt( nChild ), pEntry );
+ }
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const throw (RuntimeException )
+{
+ if( !mpTreeImpl )
+ throw DisposedException();
+ return *mpTreeImpl;
+}
+
+// --------------------------------------------------------------------
+
+void TreeControlPeer::ChangeNodesSelection( const Any& rSelection, bool bSelect, bool bSetSelection ) throw( RuntimeException, IllegalArgumentException )
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ Reference< XTreeNode > xTempNode;
+ Sequence< XTreeNode > aTempSeq;
+
+ const Reference< XTreeNode > *pNodes = 0;
+ sal_Int32 nCount = 0;
+
+ if( rSelection.hasValue() )
+ {
+ switch( rSelection.getValueTypeClass() )
+ {
+ case TypeClass_INTERFACE:
+ {
+ rSelection >>= xTempNode;
+ if( xTempNode.is() )
+ {
+ nCount = 1;
+ pNodes = &xTempNode;
+ }
+ break;
+ }
+ case TypeClass_SEQUENCE:
+ {
+ if( rSelection.getValueType() == ::getCppuType( (const Sequence< Reference< XTreeNode > > *) 0 ) )
+ {
+ const Sequence< Reference< XTreeNode > >& rSeq( *(const Sequence< Reference< XTreeNode > > *)rSelection.getValue() );
+ nCount = rSeq.getLength();
+ if( nCount )
+ pNodes = rSeq.getConstArray();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( nCount == 0 )
+ throw IllegalArgumentException();
+ }
+
+ if( bSetSelection )
+ rTree.SelectAll( FALSE );
+
+ if( pNodes && nCount )
+ {
+ while( nCount-- )
+ {
+ UnoTreeListEntry* pEntry = getEntry( *pNodes++ );
+ rTree.Select( pEntry, bSelect ? TRUE : FALSE );
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+// ::com::sun::star::view::XSelectionSupplier
+// -------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ ChangeNodesSelection( rSelection, true, true );
+ return sal_True;
+}
+
+// -------------------------------------------------------------------
+
+Any SAL_CALL TreeControlPeer::getSelection() throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ Any aRet;
+
+ ULONG nSelectionCount = rTree.GetSelectionCount();
+ if( nSelectionCount == 1 )
+ {
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
+ if( pEntry && pEntry->mxNode.is() )
+ aRet <<= pEntry->mxNode;
+ }
+ else if( nSelectionCount > 1 )
+ {
+ Sequence< Reference< XTreeNode > > aSelection( nSelectionCount );
+ Reference< XTreeNode >* pNodes = aSelection.getArray();
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
+ while( pEntry && nSelectionCount )
+ {
+ *pNodes++ = pEntry->mxNode;
+ pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) );
+ --nSelectionCount;
+ }
+
+ OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) );
+ aRet <<= aSelection;
+ }
+
+ return aRet;
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
+{
+ maSelectionListeners.addInterface( xListener );
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
+{
+ maSelectionListeners.addInterface( xListener );
+}
+
+// -------------------------------------------------------------------
+// ::com::sun::star::view::XMultiSelectionSupplier
+// -------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
+{
+ ChangeNodesSelection( rSelection, true, false );
+ return sal_True;
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
+{
+ ChangeNodesSelection( rSelection, false, false );
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::clearSelection() throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ getTreeListBoxOrThrow().SelectAll( FALSE );
+}
+
+// -------------------------------------------------------------------
+
+sal_Int32 SAL_CALL TreeControlPeer::getSelectionCount() throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ return getTreeListBoxOrThrow().GetSelectionCount();
+}
+
+// -------------------------------------------------------------------
+
+class TreeSelectionEnumeration : public ::cppu::WeakImplHelper1< XEnumeration >
+{
+public:
+ TreeSelectionEnumeration( std::list< Any >& rSelection );
+ virtual ::sal_Bool SAL_CALL hasMoreElements() throw (RuntimeException);
+ virtual Any SAL_CALL nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ std::list< Any > maSelection;
+ std::list< Any >::iterator maIter;
+};
+
+// -------------------------------------------------------------------
+
+TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection )
+{
+ maSelection.swap( rSelection );
+ maIter = maSelection.begin();
+}
+
+// -------------------------------------------------------------------
+
+::sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() throw (RuntimeException)
+{
+ return maIter != maSelection.end();
+}
+
+// -------------------------------------------------------------------
+
+Any SAL_CALL TreeSelectionEnumeration::nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ if( maIter == maSelection.end() )
+ throw NoSuchElementException();
+
+ return (*maIter++);
+}
+
+// -------------------------------------------------------------------
+
+Reference< XEnumeration > SAL_CALL TreeControlPeer::createSelectionEnumeration() throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ sal_uInt32 nSelectionCount = rTree.GetSelectionCount();
+ std::list< Any > aSelection( nSelectionCount );
+
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
+ while( pEntry && nSelectionCount )
+ {
+ aSelection.push_back( Any( pEntry->mxNode ) );
+ pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) );
+ --nSelectionCount;
+ }
+
+ OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) );
+
+ return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) );
+}
+
+// -------------------------------------------------------------------
+
+Reference< XEnumeration > SAL_CALL TreeControlPeer::createReverseSelectionEnumeration() throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ sal_uInt32 nSelectionCount = rTree.GetSelectionCount();
+ std::list< Any > aSelection;
+
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
+ while( pEntry && nSelectionCount )
+ {
+ aSelection.push_front( Any( pEntry->mxNode ) );
+ pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) );
+ --nSelectionCount;
+ }
+
+ OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) );
+
+ return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) );
+}
+
+// --------------------------------------------------------------------
+// ::com::sun::star::awt::XTreeControl
+// --------------------------------------------------------------------
+
+OUString SAL_CALL TreeControlPeer::getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ return msDefaultExpandedGraphicURL;
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::setDefaultExpandedGraphicURL( const ::rtl::OUString& sDefaultExpandedGraphicURL ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ if( msDefaultExpandedGraphicURL != sDefaultExpandedGraphicURL )
+ {
+ if( sDefaultExpandedGraphicURL.getLength() )
+ loadImage( sDefaultExpandedGraphicURL, maDefaultExpandedImage );
+ else
+ maDefaultExpandedImage = Image();
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ SvLBoxEntry* pEntry = rTree.First();
+ while( pEntry )
+ {
+ ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) );
+ if( pContextGraphicItem )
+ {
+ if( pContextGraphicItem->msExpandedGraphicURL.getLength() == 0 )
+ rTree.SetExpandedEntryBmp( pEntry, maDefaultExpandedImage );
+ }
+ pEntry = rTree.Next( pEntry );
+ }
+
+ msDefaultExpandedGraphicURL = sDefaultExpandedGraphicURL;
+ }
+}
+
+// --------------------------------------------------------------------
+
+OUString SAL_CALL TreeControlPeer::getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ return msDefaultCollapsedGraphicURL;
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::setDefaultCollapsedGraphicURL( const ::rtl::OUString& sDefaultCollapsedGraphicURL ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ if( msDefaultCollapsedGraphicURL != sDefaultCollapsedGraphicURL )
+ {
+ if( sDefaultCollapsedGraphicURL.getLength() )
+ loadImage( sDefaultCollapsedGraphicURL, maDefaultCollapsedImage );
+ else
+ maDefaultCollapsedImage = Image();
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ SvLBoxEntry* pEntry = rTree.First();
+ while( pEntry )
+ {
+ ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) );
+ if( pContextGraphicItem )
+ {
+ if( pContextGraphicItem->msCollapsedGraphicURL.getLength() == 0 )
+ rTree.SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage );
+ }
+ pEntry = rTree.Next( pEntry );
+ }
+
+ msDefaultCollapsedGraphicURL = sDefaultCollapsedGraphicURL;
+ }
+}
+
+// --------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( xNode );
+ return ( pEntry && rTree.IsExpanded( pEntry ) ) ? sal_True : sal_False;
+}
+
+// -------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ return !isNodeExpanded( xNode );
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( xNode );
+ if( pEntry )
+ rTree.MakeVisible( pEntry );
+}
+
+// -------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( xNode );
+ return ( pEntry && rTree.IsEntryVisible( pEntry ) ) ? sal_True : sal_False;
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( xNode );
+ if( pEntry )
+ rTree.Expand( pEntry );
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( xNode );
+ if( pEntry )
+ rTree.Collapse( pEntry );
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
+{
+ maTreeExpansionListeners.addInterface( xListener );
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
+{
+ maTreeExpansionListeners.removeInterface( xListener );
+}
+
+// -------------------------------------------------------------------
+
+Reference< XTreeNode > SAL_CALL TreeControlPeer::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ Reference< XTreeNode > xNode;
+
+ const Point aPos( x, y );
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, TRUE ) );
+ if( pEntry )
+ xNode = pEntry->mxNode;
+
+ return xNode;
+}
+
+// -------------------------------------------------------------------
+
+Reference< XTreeNode > SAL_CALL TreeControlPeer::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ Reference< XTreeNode > xNode;
+
+ const Point aPos( x, y );
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, TRUE ) );
+ if( pEntry )
+ xNode = pEntry->mxNode;
+
+ return xNode;
+}
+
+// -------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL TreeControlPeer::getNodeRect( const Reference< XTreeNode >& i_Node ) throw (IllegalArgumentException, RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( i_Node, true );
+
+ ::Rectangle aEntryRect( rTree.GetFocusRect( pEntry, rTree.GetEntryPosition( pEntry ).Y() ) );
+ return VCLUnoHelper::ConvertToAWTRect( aEntryRect );
+}
+
+// -------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::isEditing( ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ return rTree.IsEditingActive() ? sal_True : sal_False;
+}
+
+// -------------------------------------------------------------------
+
+sal_Bool SAL_CALL TreeControlPeer::stopEditing() throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ if( rTree.IsEditingActive() )
+ {
+ rTree.EndEditing(FALSE);
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::cancelEditing( ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ rTree.EndEditing(FALSE);
+}
+
+// -------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ UnoTreeListEntry* pEntry = getEntry( xNode );
+ rTree.EditEntry( pEntry );
+}
+
+void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
+{
+ maTreeEditListeners.addInterface( xListener );
+}
+
+void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
+{
+ maTreeEditListeners.removeInterface( xListener );
+}
+
+bool TreeControlPeer::onEditingEntry( UnoTreeListEntry* pEntry )
+{
+ if( mpTreeImpl && pEntry && pEntry->mxNode.is() && (maTreeEditListeners.getLength() > 0) )
+ {
+ try
+ {
+ maTreeEditListeners.nodeEditing( pEntry->mxNode );
+ }
+ catch( VetoException& )
+ {
+ return false;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ return true;
+}
+
+bool TreeControlPeer::onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText )
+{
+ if( mpTreeImpl && pEntry && pEntry->mxNode.is() ) try
+ {
+ LockGuard aLockGuard( mnEditLock );
+ const OUString aNewText( rNewText );
+ if( maTreeEditListeners.getLength() > 0 )
+ {
+ maTreeEditListeners.nodeEdited( pEntry->mxNode, aNewText );
+ return false;
+ }
+ else
+ {
+ Reference< XMutableTreeNode > xMutableNode( pEntry->mxNode, UNO_QUERY );
+ if( xMutableNode.is() )
+ xMutableNode->setDisplayValue( Any( aNewText ) );
+ else
+ return false;
+ }
+
+ }
+ catch( Exception& )
+ {
+ }
+
+ return true;
+}
+
+// --------------------------------------------------------------------
+// ::com::sun::star::awt::tree::TreeDataModelListener
+// --------------------------------------------------------------------
+
+void SAL_CALL TreeControlPeer::treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ if( mnEditLock != 0 )
+ return;
+
+ updateTree( rEvent, true );
+}
+
+void SAL_CALL TreeControlPeer::treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ if( mnEditLock != 0 )
+ return;
+
+ updateTree( rEvent, true );
+}
+
+void SAL_CALL TreeControlPeer::treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ if( mnEditLock != 0 )
+ return;
+
+ updateTree( rEvent, true );
+}
+
+void SAL_CALL TreeControlPeer::treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ if( mnEditLock != 0 )
+ return;
+
+ updateTree( rEvent, true );
+}
+
+void TreeControlPeer::updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive )
+{
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ Sequence< Reference< XTreeNode > > Nodes;
+ Reference< XTreeNode > xNode( rEvent.ParentNode );
+ if( !xNode.is() && Nodes.getLength() )
+ {
+ xNode = Nodes[0];
+ }
+
+ if( xNode.is() )
+ updateNode( rTree, xNode, bRecursive );
+}
+
+void TreeControlPeer::updateNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, bool bRecursive )
+{
+ if( xNode.is() )
+ {
+ UnoTreeListEntry* pNodeEntry = getEntry( xNode, false );
+
+ if( !pNodeEntry )
+ {
+ Reference< XTreeNode > xParentNode( xNode->getParent() );
+ UnoTreeListEntry* pParentEntry = 0;
+ ULONG nChild = LIST_APPEND;
+
+ if( xParentNode.is() )
+ {
+ pParentEntry = getEntry( xParentNode );
+ nChild = xParentNode->getIndex( xNode );
+ }
+
+ pNodeEntry = createEntry( xNode, pParentEntry, nChild );
+ }
+
+ if( bRecursive )
+ updateChildNodes( rTree, xNode, pNodeEntry );
+ }
+}
+
+void TreeControlPeer::updateChildNodes( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry )
+{
+ if( xParentNode.is() && pParentEntry )
+ {
+ UnoTreeListEntry* pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.FirstChild( pParentEntry ) );
+
+ const sal_Int32 nChildCount = xParentNode->getChildCount();
+ for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ )
+ {
+ Reference< XTreeNode > xNode( xParentNode->getChildAt( nChild ) );
+ if( !pCurrentChild || ( pCurrentChild->mxNode != xNode ) )
+ {
+ UnoTreeListEntry* pNodeEntry = getEntry( xNode, false );
+ if( pNodeEntry == 0 )
+ {
+ // child node is not yet part of the tree, add it
+ pCurrentChild = createEntry( xNode, pParentEntry, nChild );
+ }
+ else if( pNodeEntry != pCurrentChild )
+ {
+ // node is already part of the tree, but not on the correct position
+ rTree.GetModel()->Move( pNodeEntry, pParentEntry, nChild );
+ pCurrentChild = pNodeEntry;
+ updateEntry( pCurrentChild );
+ }
+ }
+ else
+ {
+ // child node has entry and entry is equal to current entry,
+ // so no structural changes happened
+ updateEntry( pCurrentChild );
+ }
+
+ pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) );
+ }
+
+ // check if we have entries without nodes left, we need to remove them
+ while( pCurrentChild )
+ {
+ UnoTreeListEntry* pNextChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) );
+ rTree.GetModel()->Remove( pCurrentChild );
+ pCurrentChild = pNextChild;
+ }
+ }
+}
+
+OUString TreeControlPeer::getEntryString( const Any& rValue )
+{
+ OUString sValue;
+ if( rValue.hasValue() )
+ {
+ switch( rValue.getValueTypeClass() )
+ {
+ case TypeClass_SHORT:
+ case TypeClass_LONG:
+ {
+ sal_Int32 nValue = 0;
+ if( rValue >>= nValue )
+ sValue = OUString::valueOf( nValue );
+ break;
+ }
+ case TypeClass_BYTE:
+ case TypeClass_UNSIGNED_SHORT:
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 nValue = 0;
+ if( rValue >>= nValue )
+ sValue = OUString::valueOf( (sal_Int64)nValue );
+ break;
+ }
+ case TypeClass_HYPER:
+ {
+ sal_Int64 nValue = 0;
+ if( rValue >>= nValue )
+ sValue = OUString::valueOf( nValue );
+ break;
+ }
+ case TypeClass_UNSIGNED_HYPER:
+ {
+ sal_uInt64 nValue = 0;
+ if( rValue >>= nValue )
+ sValue = OUString::valueOf( (sal_Int64)nValue );
+ break;
+ }
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ {
+ double fValue = 0.0;
+ if( rValue >>= fValue )
+ sValue = OUString::valueOf( fValue );
+ break;
+ }
+ case TypeClass_STRING:
+ rValue >>= sValue;
+ break;
+ /*
+ case TypeClass_INTERFACE:
+ // @todo
+ break;
+ case TypeClass_SEQUENCE:
+ {
+ Sequence< Any > aValues;
+ if( aValue >>= aValues )
+ {
+ updateEntry( SvLBoxEntry& rEntry, aValues );
+ return;
+ }
+ }
+ break;
+ */
+ default:
+ break;
+ }
+ }
+ return sValue;
+}
+
+// XEventListener
+void SAL_CALL TreeControlPeer::disposing( const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException)
+{
+ // model is disposed, so we clear our tree
+ ::vos::OGuard aGuard( GetMutex() );
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ rTree.Clear();
+ mxDataModel.clear();
+}
+
+void TreeControlPeer::onChangeDataModel( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel )
+{
+ if( xDataModel.is() && (mxDataModel == xDataModel) )
+ return; // do nothing
+
+ Reference< XTreeDataModelListener > xListener( this );
+
+ if( mxDataModel.is() )
+ mxDataModel->removeTreeDataModelListener( xListener );
+
+ if( !xDataModel.is() )
+ {
+ static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.tree.DefaultTreeDataModel" ) );
+ Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() );
+ if( xORB.is() )
+ {
+ mxDataModel.query( xORB->createInstance( aSN ) );
+ }
+ }
+
+ mxDataModel = xDataModel;
+
+ fillTree( rTree, mxDataModel );
+
+ if( mxDataModel.is() )
+ mxDataModel->addTreeDataModelListener( xListener );
+}
+
+// --------------------------------------------------------------------
+// ::com::sun::star::awt::XLayoutConstrains
+// --------------------------------------------------------------------
+
+::com::sun::star::awt::Size TreeControlPeer::getMinimumSize() throw(RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz;
+/* todo
+ MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
+ if ( pEdit )
+ aSz = AWTSize(pEdit->CalcMinimumSize());
+*/
+ return aSz;
+}
+
+::com::sun::star::awt::Size TreeControlPeer::getPreferredSize() throw(RuntimeException)
+{
+ return getMinimumSize();
+}
+
+::com::sun::star::awt::Size TreeControlPeer::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz = rNewSize;
+/* todo
+ MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
+ if ( pEdit )
+ aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize )));
+*/
+ return aSz;
+}
+
+// --------------------------------------------------------------------
+// ::com::sun::star::awt::XVclWindowPeer
+// --------------------------------------------------------------------
+
+void TreeControlPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ switch( GetPropertyId( PropertyName ) )
+ {
+ case BASEPROPERTY_TREE_SELECTIONTYPE:
+ {
+ SelectionType eSelectionType;
+ if( aValue >>= eSelectionType )
+ {
+ SelectionMode eSelMode;
+ switch( eSelectionType )
+ {
+ case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break;
+ case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break;
+ case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break;
+ // case SelectionType_NONE:
+ default: eSelMode = NO_SELECTION; break;
+ }
+ if( rTree.GetSelectionMode() != eSelMode )
+ rTree.SetSelectionMode( eSelMode );
+ }
+ break;
+ }
+
+ case BASEPROPERTY_TREE_DATAMODEL:
+ onChangeDataModel( rTree, Reference< XTreeDataModel >( aValue, UNO_QUERY ) );
+ break;
+ case BASEPROPERTY_TREE_ROWHEIGHT:
+ {
+ sal_Int32 nHeight = 0;
+ if( aValue >>= nHeight )
+ rTree.SetEntryHeight( (short)nHeight );
+ break;
+ }
+ case BASEPROPERTY_TREE_EDITABLE:
+ {
+ sal_Bool bEnabled = false;
+ if( aValue >>= bEnabled )
+ rTree.EnableInplaceEditing( bEnabled ? TRUE : FALSE );
+ break;
+ }
+ case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING:
+ break; // @todo
+ case BASEPROPERTY_TREE_ROOTDISPLAYED:
+ {
+ sal_Bool bDisplayed = false;
+ if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) )
+ {
+ onChangeRootDisplayed(bDisplayed);
+ }
+ break;
+ }
+ case BASEPROPERTY_TREE_SHOWSHANDLES:
+ {
+ sal_Bool bEnabled = false;
+ if( aValue >>= bEnabled )
+ {
+ WinBits nBits = rTree.GetWindowBits() & (~WB_HASLINES);
+ if( bEnabled )
+ nBits |= WB_HASLINES;
+ if( nBits != rTree.GetWindowBits() )
+ rTree.SetWindowBits( nBits );
+ }
+ break;
+ }
+ case BASEPROPERTY_TREE_SHOWSROOTHANDLES:
+ {
+ sal_Bool bEnabled = false;
+ if( aValue >>= bEnabled )
+ {
+ WinBits nBits = rTree.GetWindowBits() & (~WB_HASLINESATROOT);
+ if( bEnabled )
+ nBits |= WB_HASLINESATROOT;
+ if( nBits != rTree.GetWindowBits() )
+ rTree.SetWindowBits( nBits );
+ }
+ break;
+ }
+ default:
+ VCLXWindow::setProperty( PropertyName, aValue );
+ break;
+ }
+}
+
+Any TreeControlPeer::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ const sal_uInt16 nPropId = GetPropertyId( PropertyName );
+ if( (nPropId >= BASEPROPERTY_TREE_START) && (nPropId <= BASEPROPERTY_TREE_END) )
+ {
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+ switch(nPropId)
+ {
+ case BASEPROPERTY_TREE_SELECTIONTYPE:
+ {
+ SelectionType eSelectionType;
+
+ SelectionMode eSelMode = rTree.GetSelectionMode();
+ switch( eSelMode )
+ {
+ case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break;
+ case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break;
+ case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break;
+// case NO_SELECTION:
+ default: eSelectionType = SelectionType_NONE; break;
+ }
+ return Any( eSelectionType );
+ }
+ case BASEPROPERTY_TREE_ROWHEIGHT:
+ return Any( (sal_Int32)rTree.GetEntryHeight() );
+ case BASEPROPERTY_TREE_DATAMODEL:
+ return Any( mxDataModel );
+ case BASEPROPERTY_TREE_EDITABLE:
+ return Any( rTree.IsInplaceEditingEnabled() ? sal_True : sal_False );
+ case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING:
+ return Any( sal_True ); // @todo
+ case BASEPROPERTY_TREE_ROOTDISPLAYED:
+ return Any( mbIsRootDisplayed );
+ case BASEPROPERTY_TREE_SHOWSHANDLES:
+ return Any( (rTree.GetWindowBits() & WB_HASLINES) != 0 ? sal_True : sal_False );
+ case BASEPROPERTY_TREE_SHOWSROOTHANDLES:
+ return Any( (rTree.GetWindowBits() & WB_HASLINESATROOT) != 0 ? sal_True : sal_False );
+ }
+ }
+ return VCLXWindow::getProperty( PropertyName );
+}
+
+void TreeControlPeer::onChangeRootDisplayed( sal_Bool bIsRootDisplayed )
+{
+ if( mbIsRootDisplayed == bIsRootDisplayed )
+ return;
+
+ mbIsRootDisplayed = bIsRootDisplayed;
+
+ UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
+
+ if( rTree.GetEntryCount() == 0 )
+ return;
+
+ // todo
+ fillTree( rTree, mxDataModel );
+ if( mbIsRootDisplayed )
+ {
+ }
+ else
+ {
+ }
+}
+
+bool TreeControlPeer::loadImage( const ::rtl::OUString& rURL, Image& rImage )
+{
+ if( !mxGraphicProvider.is() )
+ {
+ static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) );
+ Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() );
+ if( xORB.is() )
+ {
+ Reference< XInterface > x( xORB->createInstance( aSN ) );
+ mxGraphicProvider.query( x );
+ mxGraphicProvider = Reference< XGraphicProvider >( x, UNO_QUERY );
+ }
+ }
+
+ if( mxGraphicProvider.is() ) try
+ {
+ ::com::sun::star::beans::PropertyValues aProps( 1 );
+ aProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ aProps[0].Value <<= rURL;
+
+ Reference< XGraphic > xGraphic( mxGraphicProvider->queryGraphic( aProps ) );
+
+ Graphic aGraphic( xGraphic );
+ rImage = aGraphic.GetBitmapEx();
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+
+ return false;
+}
+
+// ====================================================================
+// class UnoTreeListBoxImpl
+// ====================================================================
+
+UnoTreeListBoxImpl::UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle )
+: SvTreeListBox( pParent, nWinStyle )
+, mxPeer( pPeer )
+{
+ SetWindowBits( WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_HSCROLL );
+ SetNodeDefaultImages();
+ SetSelectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) );
+ SetDeselectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) );
+
+ SetExpandingHdl( LINK(this, UnoTreeListBoxImpl, OnExpandingHdl) );
+ SetExpandedHdl( LINK(this, UnoTreeListBoxImpl, OnExpandedHdl) );
+
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListBoxImpl::~UnoTreeListBoxImpl()
+{
+ if( mxPeer.is() )
+ mxPeer->disposeControl();
+}
+
+// --------------------------------------------------------------------
+
+IMPL_LINK( UnoTreeListBoxImpl, OnSelectionChangeHdl, UnoTreeListBoxImpl*, EMPTYARG )
+{
+ if( mxPeer.is() )
+ mxPeer->onSelectionChanged();
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+IMPL_LINK(UnoTreeListBoxImpl, OnExpandingHdl, UnoTreeListBoxImpl*, EMPTYARG )
+{
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() );
+
+ if( pEntry && mxPeer.is() )
+ {
+ return mxPeer->onExpanding( pEntry->mxNode, !IsExpanded( pEntry ) ) ? 1 : 0;
+ }
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+IMPL_LINK(UnoTreeListBoxImpl, OnExpandedHdl, UnoTreeListBoxImpl*, EMPTYARG )
+{
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() );
+ if( pEntry && mxPeer.is() )
+ {
+ mxPeer->onExpanded( pEntry->mxNode, IsExpanded( pEntry ) );
+ }
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+sal_uInt32 UnoTreeListBoxImpl::insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,ULONG nPos )
+{
+ if( pParent )
+ return SvTreeListBox::Insert( pEntry, pParent, nPos );
+ else
+ return SvTreeListBox::Insert( pEntry, nPos );
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListBoxImpl::RequestingChilds( SvLBoxEntry* pParent )
+{
+ UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( pParent );
+ if( pEntry && pEntry->mxNode.is() && mxPeer.is() )
+ mxPeer->onRequestChildNodes( pEntry->mxNode );
+}
+
+// --------------------------------------------------------------------
+
+BOOL UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& )
+{
+ return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false;
+}
+
+// --------------------------------------------------------------------
+
+BOOL UnoTreeListBoxImpl::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
+{
+ return mxPeer.is() ? mxPeer->onEditedEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ), rNewText ) : false;
+}
+
+// ====================================================================
+// class UnoTreeListItem
+// ====================================================================
+
+UnoTreeListItem::UnoTreeListItem( SvLBoxEntry* pEntry )
+: SvLBoxItem( pEntry, 0 )
+{
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListItem::UnoTreeListItem()
+: SvLBoxItem()
+{
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListItem::~UnoTreeListItem()
+{
+}
+
+// --------------------------------------------------------------------
+
+USHORT UnoTreeListItem::IsA()
+{
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListItem::Paint( const Point& rPos, SvLBox& rDev, USHORT /* nFlags */, SvLBoxEntry* _pEntry)
+{
+ Point aPos( rPos );
+ if( _pEntry )
+ {
+ Size aSize( GetSize(&rDev,_pEntry) );
+ if( !!maImage )
+ {
+ rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE );
+ int nWidth = maImage.GetSizePixel().Width() + 6;
+ aPos.X() += nWidth;
+ aSize.Width() -= nWidth;
+ }
+ rDev.DrawText( Rectangle(aPos,aSize),maText, rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE );
+ }
+ else
+ {
+ if( !!maImage )
+ {
+ rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE);
+ aPos.X() += maImage.GetSizePixel().Width() + 6;
+ }
+ rDev.DrawText( aPos, maText);
+ }
+}
+
+// --------------------------------------------------------------------
+
+SvLBoxItem* UnoTreeListItem::Create() const
+{
+ return new UnoTreeListItem;
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListItem::Clone( SvLBoxItem* pSource )
+{
+ UnoTreeListItem* pSourceItem = dynamic_cast< UnoTreeListItem* >( pSource );
+ if( pSourceItem )
+ {
+ maText = pSourceItem->maText;
+ maImage = pSourceItem->maImage;
+ }
+}
+
+// --------------------------------------------------------------------
+
+OUString UnoTreeListItem::GetText() const
+{
+ return maText;
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListItem::SetText( const OUString& rText )
+{
+ maText = rText;
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListItem::SetImage( const Image& rImage )
+{
+ maImage = rImage;
+}
+
+// --------------------------------------------------------------------
+
+OUString UnoTreeListItem::GetGraphicURL() const
+{
+ return maGraphicURL;
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL )
+{
+ maGraphicURL = rGraphicURL;
+}
+
+// --------------------------------------------------------------------
+
+void UnoTreeListItem::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
+{
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+
+ pViewData->aSize = maImage.GetSizePixel();
+
+ const Size aTextSize(pView->GetTextWidth( maText ), pView->GetTextHeight());
+ if( pViewData->aSize.Width() )
+ {
+ pViewData->aSize.Width() += 6 + aTextSize.Width();
+ if( pViewData->aSize.Height() < aTextSize.Height() )
+ pViewData->aSize.Height() = aTextSize.Height();
+ }
+ else
+ {
+ pViewData->aSize = aTextSize;
+ }
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListEntry::UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer )
+: SvLBoxEntry()
+, mxNode( xNode )
+, mpPeer( pPeer )
+{
+ if( mpPeer )
+ mpPeer->addEntry( this );
+}
+
+// --------------------------------------------------------------------
+
+UnoTreeListEntry::~UnoTreeListEntry()
+{
+ if( mpPeer )
+ mpPeer->removeEntry( this );
+}
diff --git a/svtools/source/uno/treecontrolpeer.hxx b/svtools/source/uno/treecontrolpeer.hxx
new file mode 100644
index 000000000000..336830804a6f
--- /dev/null
+++ b/svtools/source/uno/treecontrolpeer.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 _TREE_CONTROL_PEER_HXX_
+#define _TREE_CONTROL_PEER_HXX_
+
+#include <com/sun/star/awt/tree/XTreeControl.hpp>
+#include <com/sun/star/awt/tree/XTreeDataModel.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxwindows.hxx>
+
+#include <vcl/image.hxx>
+
+//#include <comphelper/uno3.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+
+class UnoTreeListEntry;
+class TreeControlPeer;
+class UnoTreeListBoxImpl;
+class TreeNodeMap;
+
+// ----------------------------------------------------
+// class TreeControlPeer
+// ----------------------------------------------------
+class TreeControlPeer : public ::cppu::ImplInheritanceHelper2< VCLXWindow, ::com::sun::star::awt::tree::XTreeControl, ::com::sun::star::awt::tree::XTreeDataModelListener >
+{
+ friend class UnoTreeListBoxImpl;
+ friend class UnoTreeListEntry;
+public:
+ TreeControlPeer();
+ virtual ~TreeControlPeer();
+
+ Window* createVclControl( Window* pParent, sal_Int64 nWinStyle );
+
+ // VCLXWindow
+ virtual void SetWindow( Window* pWindow );
+
+ // ::com::sun::star::view::XSelectionSupplier
+ virtual ::sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& xSelection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getSelection( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::view::XMultiSelectionSupplier
+ virtual ::sal_Bool SAL_CALL addSelection( const ::com::sun::star::uno::Any& Selection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSelection( const ::com::sun::star::uno::Any& Selection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearSelection( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getSelectionCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createSelectionEnumeration( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createReverseSelectionEnumeration( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XTreeControl
+ virtual ::rtl::OUString SAL_CALL getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDefaultExpandedGraphicURL( const ::rtl::OUString& _defaultexpandedgraphicurl ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDefaultCollapsedGraphicURL( const ::rtl::OUString& _defaultcollapsedgraphicurl ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isNodeExpanded( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isNodeCollapsed( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL makeNodeVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isNodeVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL expandNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL collapseNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addTreeExpansionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeExpansionListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeTreeExpansionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeExpansionListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getNodeForLocation( ::sal_Int32 x, ::sal_Int32 y ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getClosestNodeForLocation( ::sal_Int32 x, ::sal_Int32 y ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getNodeRect( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isEditing( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL stopEditing( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancelEditing( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL startEditingAtNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addTreeEditListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeEditListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeTreeEditListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeEditListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::tree::TreeDataModelListener
+ virtual void SAL_CALL treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XLayoutConstrains
+ ::com::sun::star::awt::Size SAL_CALL getMinimumSize() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Size SAL_CALL getPreferredSize() throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::awt::Size SAL_CALL calcAdjustedSize( const ::com::sun::star::awt::Size& aNewSize ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XVclWindowPeer
+ void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+private:
+ UnoTreeListEntry* getEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bThrow = true ) throw (::com::sun::star::lang::IllegalArgumentException );
+
+ void disposeControl();
+
+ bool onEditingEntry( UnoTreeListEntry* pEntry );
+ bool onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText );
+
+ void eraseTree( UnoTreeListBoxImpl& rTree );
+ void fillTree( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModel >& xDataModel );
+ void addNode( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, UnoTreeListEntry* pParentEntry );
+
+ UnoTreeListEntry* createEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, UnoTreeListEntry* pParent, ULONG nPos = LIST_APPEND );
+ bool updateEntry( UnoTreeListEntry* pEntry );
+
+ void updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive );
+ void updateNode( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bRecursive );
+ void updateChildNodes( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry );
+
+ ::rtl::OUString getEntryString( const ::com::sun::star::uno::Any& rValue );
+
+ UnoTreeListBoxImpl& getTreeListBoxOrThrow() const throw (::com::sun::star::uno::RuntimeException );
+ void ChangeNodesSelection( const ::com::sun::star::uno::Any& rSelection, bool bSelect, bool bSetSelection ) throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );
+
+ void onChangeDataModel( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModel >& xDataModel );
+
+ void onSelectionChanged();
+ void onRequestChildNodes( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode );
+ bool onExpanding( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bExpanding );
+ void onExpanded( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bExpanding );
+
+ void onChangeRootDisplayed( sal_Bool bIsRootDisplayed );
+
+ void addEntry( UnoTreeListEntry* pEntry );
+ void removeEntry( UnoTreeListEntry* pEntry );
+
+ bool loadImage( const ::rtl::OUString& rURL, Image& rImage );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModel >mxDataModel;
+ TreeSelectionListenerMultiplexer maSelectionListeners;
+ TreeExpansionListenerMultiplexer maTreeExpansionListeners;
+ TreeEditListenerMultiplexer maTreeEditListeners;
+ sal_Bool mbIsRootDisplayed;
+ UnoTreeListBoxImpl* mpTreeImpl;
+ sal_Int32 mnEditLock;
+ ::rtl::OUString msDefaultCollapsedGraphicURL;
+ ::rtl::OUString msDefaultExpandedGraphicURL;
+ Image maDefaultExpandedImage;
+ Image maDefaultCollapsedImage;
+ TreeNodeMap* mpTreeNodeMap;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicProvider > mxGraphicProvider;
+};
+
+#endif // _TREE_CONTROL_PEER_HXX_
diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx
new file mode 100644
index 000000000000..d239ee3c740d
--- /dev/null
+++ b/svtools/source/uno/unocontroltablemodel.cxx
@@ -0,0 +1,513 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "unocontroltablemodel.hxx"
+#include <com/sun/star/view/SelectionType.hpp>
+#include "svtools/table/gridtablerenderer.hxx"
+#include "svtools/table/defaultinputhandler.hxx"
+#include "svtools/table/tablecontrol.hxx"
+#include <comphelper/sequence.hxx>
+#include <rtl/ref.hxx>
+#include <tools/debug.hxx>
+#include <toolkit/helper/property.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/awt/grid/XGridColumn.hpp>
+
+using ::rtl::OUString;
+using namespace ::svt::table;
+using namespace ::com::sun::star::uno;
+
+
+ //--------------------------------------------------------------------
+ UnoControlTableColumn::UnoControlTableColumn(Reference<XGridColumn> m_xGridColumn)
+ :m_nID( 0 )
+ ,m_sName()
+ ,m_bIsResizable( true )
+ ,m_nWidth( 4 )
+ ,m_nMinWidth( 0 )
+ ,m_nMaxWidth( 0 )
+ ,m_nPrefWidth ( 0 )
+ ,m_xHorizontalAlign(com::sun::star::style::HorizontalAlignment(0))
+ {
+ m_sName = m_xGridColumn->getTitle();
+ }
+ //--------------------------------------------------------------------
+ UnoControlTableColumn::UnoControlTableColumn()
+ :m_nID( 0 )
+ ,m_sName()
+ ,m_bIsResizable( true )
+ ,m_nWidth( 4 )
+ ,m_nMinWidth( 0 )
+ ,m_nMaxWidth( 0 )
+ ,m_nPrefWidth ( 0 )
+ ,m_xHorizontalAlign(com::sun::star::style::HorizontalAlignment(0))
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ColumnID UnoControlTableColumn::getID() const
+ {
+ return m_nID;
+ }
+
+ //--------------------------------------------------------------------
+ bool UnoControlTableColumn::setID( const ColumnID _nID )
+ {
+ m_nID = _nID;
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ String UnoControlTableColumn::getName() const
+ {
+ return m_sName;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setName( const String& _rName )
+ {
+ m_sName = _rName;
+ }
+ //--------------------------------------------------------------------
+ bool UnoControlTableColumn::isResizable() const
+ {
+ return m_bIsResizable;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setResizable( bool _bResizable )
+ {
+ m_bIsResizable = _bResizable;
+ }
+
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableColumn::getWidth() const
+ {
+ return m_nWidth;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setWidth( TableMetrics _nWidth )
+ {
+ m_nWidth = _nWidth;
+ }
+
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableColumn::getMinWidth() const
+ {
+ return m_nMinWidth;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setMinWidth( TableMetrics _nMinWidth )
+ {
+ m_nMinWidth = _nMinWidth;
+ }
+
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableColumn::getMaxWidth() const
+ {
+ return m_nMaxWidth;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setMaxWidth( TableMetrics _nMaxWidth )
+ {
+ m_nMaxWidth = _nMaxWidth;
+ }
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableColumn::getPreferredWidth() const
+ {
+ return m_nPrefWidth;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setPreferredWidth( TableMetrics _nPrefWidth )
+ {
+ m_nPrefWidth = _nPrefWidth;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::style::HorizontalAlignment UnoControlTableColumn::getHorizontalAlign()
+ {
+ return m_xHorizontalAlign;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableColumn::setHorizontalAlign( com::sun::star::style::HorizontalAlignment _align )
+ {
+ m_xHorizontalAlign = _align;
+ }
+
+ //====================================================================
+ //= DefaultTableModel_Impl
+ //====================================================================
+ struct UnoControlTableModel_Impl
+ {
+ ::std::vector< PColumnModel > aColumns;
+ TableSize nRowCount;
+ bool bHasColumnHeaders;
+ bool bHasRowHeaders;
+ bool bVScroll;
+ bool bHScroll;
+ PTableRenderer pRenderer;
+ PTableInputHandler pInputHandler;
+ TableMetrics nRowHeight;
+ TableMetrics nColumnHeaderHeight;
+ TableMetrics nRowHeaderWidth;
+ std::vector<rtl::OUString> aRowHeadersTitle;
+ std::vector<std::vector< Any > > aCellContent;
+ ::com::sun::star::util::Color m_xLineColor;
+ ::com::sun::star::util::Color m_xHeaderColor;
+ ::com::sun::star::util::Color m_xTextColor;
+ ::com::sun::star::util::Color m_xRowColor1;
+ ::com::sun::star::util::Color m_xRowColor2;
+ ::com::sun::star::style::VerticalAlignment m_xVerticalAlign;
+
+ UnoControlTableModel_Impl()
+ :aColumns ( )
+ ,nRowCount ( 0 )
+ ,bHasColumnHeaders ( false )
+ ,bHasRowHeaders ( false )
+ ,bVScroll ( false )
+ ,bHScroll ( false )
+ ,pRenderer ( )
+ ,pInputHandler ( )
+ ,nRowHeight ( 0 )
+ ,nColumnHeaderHeight( 0 )
+ ,nRowHeaderWidth ( 10 )
+ ,aRowHeadersTitle ( )
+ ,aCellContent ( )
+ ,m_xLineColor ( 0xFFFFFF )
+ ,m_xHeaderColor ( 0xFFFFFF )
+ ,m_xTextColor ( 0 )//black as default
+ ,m_xRowColor1 ( 0xFFFFFF )
+ ,m_xRowColor2 ( 0xFFFFFF )
+ ,m_xVerticalAlign (com::sun::star::style::VerticalAlignment(0))
+ {
+ }
+ };
+
+ //====================================================================
+ //= UnoControlTableModel
+ //====================================================================
+ //--------------------------------------------------------------------
+ UnoControlTableModel::UnoControlTableModel()
+ :m_pImpl( new UnoControlTableModel_Impl )
+ {
+ m_pImpl->bHasColumnHeaders = false;
+ m_pImpl->bHasRowHeaders = false;
+ m_pImpl->pRenderer.reset( new GridTableRenderer( *this ) );
+ m_pImpl->pInputHandler.reset( new DefaultInputHandler );
+ }
+
+ //--------------------------------------------------------------------
+ UnoControlTableModel::~UnoControlTableModel()
+ {
+ DELETEZ( m_pImpl );
+ }
+
+ //--------------------------------------------------------------------
+ TableSize UnoControlTableModel::getColumnCount() const
+ {
+ return (TableSize)m_pImpl->aColumns.size();
+ }
+
+ //--------------------------------------------------------------------
+ TableSize UnoControlTableModel::getRowCount() const
+ {
+ return m_pImpl->nRowCount;
+ }
+
+ //--------------------------------------------------------------------
+ bool UnoControlTableModel::hasColumnHeaders() const
+ {
+ return m_pImpl->bHasColumnHeaders;
+ }
+
+ //--------------------------------------------------------------------
+ bool UnoControlTableModel::hasRowHeaders() const
+ {
+ return m_pImpl->bHasRowHeaders;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setRowHeaders(bool _bRowHeaders)
+ {
+ m_pImpl->bHasRowHeaders = _bRowHeaders;
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setColumnHeaders(bool _bColumnHeaders)
+ {
+ m_pImpl->bHasColumnHeaders = _bColumnHeaders;
+ }
+
+ void UnoControlTableModel::setColumnCount(TableSize _nColCount)
+ {
+ m_pImpl->aColumns.resize( _nColCount);
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setRowCount(TableSize _nRowCount)
+ {
+ m_pImpl->nRowCount = _nRowCount;
+ }
+ //--------------------------------------------------------------------
+ bool UnoControlTableModel::isCellEditable( ColPos col, RowPos row ) const
+ {
+ (void)col;
+ (void)row;
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::addTableModelListener( const PTableModelListener& listener )
+ {
+ (void) listener;
+ // TODO
+ DBG_ERROR( "DefaultTableModel::addTableModelListener: not yet implemented!" );
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::removeTableModelListener( const PTableModelListener& listener )
+ {
+ (void)listener;
+ // TODO
+ DBG_ERROR( "DefaultTableModel::removeTableModelListener: not yet implemented!" );
+ }
+
+ //--------------------------------------------------------------------
+ PColumnModel UnoControlTableModel::getColumnModel( ColPos column )
+ {
+ DBG_ASSERT( ( column >= 0 ) && ( column < getColumnCount() ),
+ "DefaultTableModel::getColumnModel: invalid index!" );
+ return m_pImpl->aColumns[ column ];
+ }
+
+ //--------------------------------------------------------------------
+ std::vector<PColumnModel>& UnoControlTableModel::getColumnModel()
+ {
+ return m_pImpl->aColumns;
+ }
+ //--------------------------------------------------------------------
+ PColumnModel UnoControlTableModel::getColumnModelByID( ColumnID id )
+ {
+ (void)id;
+ // TODO
+ DBG_ERROR( "DefaultTableModel::getColumnModelByID: not yet implemented!" );
+ return PColumnModel();
+ }
+
+ //--------------------------------------------------------------------
+ PTableRenderer UnoControlTableModel::getRenderer() const
+ {
+ return m_pImpl->pRenderer;
+ }
+
+ //--------------------------------------------------------------------
+ PTableInputHandler UnoControlTableModel::getInputHandler() const
+ {
+ return m_pImpl->pInputHandler;
+ }
+
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableModel::getRowHeight() const
+ {
+ return m_pImpl->nRowHeight;
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setRowHeight(TableMetrics _nRowHeight)
+ {
+ m_pImpl->nRowHeight = _nRowHeight;
+ }
+
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableModel::getColumnHeaderHeight() const
+ {
+ DBG_ASSERT( hasColumnHeaders(), "DefaultTableModel::getColumnHeaderHeight: invalid call!" );
+ return m_pImpl->nColumnHeaderHeight;
+ }
+
+ //--------------------------------------------------------------------
+ TableMetrics UnoControlTableModel::getRowHeaderWidth() const
+ {
+ DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" );
+ return m_pImpl->nRowHeaderWidth;
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setColumnHeaderHeight(TableMetrics _nHeight)
+ {
+ m_pImpl->nColumnHeaderHeight = _nHeight;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setRowHeaderWidth(TableMetrics _nWidth)
+ {
+ m_pImpl->nRowHeaderWidth = _nWidth;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::SetTitleHeight( TableMetrics _nHeight )
+ {
+ DBG_ASSERT( _nHeight > 0, "DefaultTableModel::SetTitleHeight: invalid height value!" );
+ m_pImpl->nColumnHeaderHeight = _nHeight;
+ // TODO: notification
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::SetHandleWidth( TableMetrics _nWidth )
+ {
+ DBG_ASSERT( _nWidth > 0, "DefaultTableModel::SetHandleWidth: invalid width value!" );
+ m_pImpl->nRowHeaderWidth = _nWidth;
+ // TODO: notification
+ }
+
+ //--------------------------------------------------------------------
+ ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const
+ {
+ if(overAllHeight>=actHeight && !m_pImpl->bVScroll)
+ return ScrollbarShowNever;
+ else
+ return ScrollbarShowAlways;
+ }
+
+ //--------------------------------------------------------------------
+ ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const
+ {
+ if(overAllWidth>=actWidth && !m_pImpl->bHScroll)
+ return ScrollbarShowNever;
+ else
+ return ScrollbarShowAlways;
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setVerticalScrollbarVisibility(bool _bVScroll) const
+ {
+ m_pImpl->bVScroll = _bVScroll;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setHorizontalScrollbarVisibility(bool _bHScroll) const
+ {
+ m_pImpl->bHScroll = _bHScroll;
+ }
+ //--------------------------------------------------------------------
+ bool UnoControlTableModel::hasVerticalScrollbar()
+ {
+ return m_pImpl->bVScroll;
+ }
+ //--------------------------------------------------------------------
+ bool UnoControlTableModel::hasHorizontalScrollbar()
+ {
+ return m_pImpl->bHScroll;
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setCellContent(const std::vector<std::vector< Any > >& cellContent)
+ {
+ m_pImpl->aCellContent = cellContent;
+ }
+
+ std::vector<std::vector< Any > >& UnoControlTableModel::getCellContent()
+ {
+ return m_pImpl->aCellContent;
+ }
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent)
+ {
+ m_pImpl->aRowHeadersTitle = cellColumnContent;
+ }
+
+ std::vector<rtl::OUString>& UnoControlTableModel::getRowHeaderName()
+ {
+ return m_pImpl->aRowHeadersTitle;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::util::Color UnoControlTableModel::getLineColor()
+ {
+ return m_pImpl->m_xLineColor;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setLineColor( ::com::sun::star::util::Color _rColor )
+ {
+ m_pImpl->m_xLineColor = _rColor;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::util::Color UnoControlTableModel::getHeaderBackgroundColor()
+ {
+ return m_pImpl->m_xHeaderColor;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setHeaderBackgroundColor( ::com::sun::star::util::Color _rColor )
+ {
+ m_pImpl->m_xHeaderColor = _rColor;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::util::Color UnoControlTableModel::getTextColor()
+ {
+ return m_pImpl->m_xTextColor;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setTextColor( ::com::sun::star::util::Color _rColor )
+ {
+ m_pImpl->m_xTextColor = _rColor;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::util::Color UnoControlTableModel::getOddRowBackgroundColor()
+ {
+ return m_pImpl->m_xRowColor1;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setOddRowBackgroundColor( ::com::sun::star::util::Color _rColor )
+ {
+ m_pImpl->m_xRowColor1 = _rColor;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::util::Color UnoControlTableModel::getEvenRowBackgroundColor()
+ {
+ return m_pImpl->m_xRowColor2;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setEvenRowBackgroundColor( ::com::sun::star::util::Color _rColor )
+ {
+ m_pImpl->m_xRowColor2 = _rColor;
+ }
+ //--------------------------------------------------------------------
+ ::com::sun::star::style::VerticalAlignment UnoControlTableModel::getVerticalAlign()
+ {
+ return m_pImpl->m_xVerticalAlign;
+ }
+
+ //--------------------------------------------------------------------
+ void UnoControlTableModel::setVerticalAlign( com::sun::star::style::VerticalAlignment _xAlign )
+ {
+ m_pImpl->m_xVerticalAlign = _xAlign;
+ }
+
diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx
new file mode 100644
index 000000000000..c00642448f79
--- /dev/null
+++ b/svtools/source/uno/unocontroltablemodel.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 _UNOCONTROL_TABLEMODEL_HXX_
+#define _UNOCONTROL_TABLEMODEL_HXX_
+
+#include <svtools/table/tablemodel.hxx>
+#include <svtools/table/tablecontrol.hxx>
+#include <com/sun/star/awt/grid/XGridControl.hpp>
+#include <com/sun/star/awt/grid/XGridDataListener.hpp>
+#include <com/sun/star/awt/grid/GridDataEvent.hpp>
+#include <com/sun/star/awt/grid/XGridColumnModel.hpp>
+#include <com/sun/star/awt/grid/XGridDataModel.hpp>
+#include <com/sun/star/awt/grid/XGridSelectionListener.hpp>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxwindows.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/awt/grid/XGridColumn.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/style/HorizontalAlignment.hpp>
+
+
+using namespace ::svt::table;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt::grid;
+
+class UnoControlTableColumn : public IColumnModel
+{
+ private:
+ ColumnID m_nID;
+ String m_sName;
+ bool m_bIsResizable;
+ TableMetrics m_nWidth;
+ TableMetrics m_nMinWidth;
+ TableMetrics m_nMaxWidth;
+ TableMetrics m_nPrefWidth;
+ ::com::sun::star::style::HorizontalAlignment m_xHorizontalAlign;
+
+ public:
+ UnoControlTableColumn(Reference<XGridColumn>);
+ UnoControlTableColumn();
+
+ // IColumnModel overridables
+ virtual ColumnID getID() const;
+ virtual bool setID( const ColumnID _nID );
+ virtual String getName() const;
+ virtual void setName( const String& _rName );
+ virtual bool isResizable() const;
+ virtual void setResizable( bool _bResizable );
+ virtual TableMetrics getWidth() const;
+ virtual void setWidth( TableMetrics _nWidth );
+ virtual TableMetrics getMinWidth() const;
+ virtual void setMinWidth( TableMetrics _nMinWidth );
+ virtual TableMetrics getMaxWidth() const;
+ virtual void setMaxWidth( TableMetrics _nMaxWidth );
+ virtual TableMetrics getPreferredWidth() const;
+ virtual void setPreferredWidth( TableMetrics _nPrefWidth );
+ virtual ::com::sun::star::style::HorizontalAlignment getHorizontalAlign();
+ virtual void setHorizontalAlign(::com::sun::star::style::HorizontalAlignment _xAlign);
+};
+
+struct UnoControlTableModel_Impl;
+
+class UnoControlTableModel : public ITableModel
+{
+ private:
+ UnoControlTableModel_Impl* m_pImpl;
+
+ public:
+ UnoControlTableModel();
+ ~UnoControlTableModel();
+
+ /// returns the current row height, in 1/100 millimeters
+ inline TableMetrics GetRowHeight() const { return getRowHeight(); }
+ /// sets a new row height.
+ void setRowHeight( TableMetrics _nHeight );
+ /// sets a new row header width.
+ void setRowHeaderWidth( TableMetrics _nWidth );
+ /// sets a new column header height.
+ void setColumnHeaderHeight( TableMetrics _nHeight );
+
+ /// returns the height of the title row (containing the column headers)
+ inline TableMetrics GetTitleHeight() const { return getColumnHeaderHeight(); }
+ /// sets a new height for the title row (containing the column headers)
+ void SetTitleHeight( TableMetrics _nHeight );
+
+ /// returns the width of the handle column (containing the row headers)
+ inline TableMetrics GetHandleWidth() const { return getRowHeaderWidth(); }
+ /// sets a new width for the handle column (containing the row headers)
+ void SetHandleWidth( TableMetrics _nWidth );
+
+ /// sets the width of a column
+ inline void SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM );
+ /// retrieves the width of a column, in 1/100th millimeters
+ inline TableMetrics GetColumnWidth( ColPos _nColumn );
+
+ public:
+ // ITableModel overridables
+ virtual TableSize getColumnCount() const;
+ virtual TableSize getRowCount() const;
+ virtual void setColumnCount(TableSize _nColCount);
+ virtual void setRowCount(TableSize _nRowCount);
+ virtual bool hasColumnHeaders() const;
+ virtual bool hasRowHeaders() const;
+ virtual void setRowHeaders(bool _bRowHeaders);
+ virtual void setColumnHeaders(bool _bColumnHeaders);
+ virtual bool isCellEditable( ColPos col, RowPos row ) const;
+ virtual void addTableModelListener( const PTableModelListener& listener );
+ virtual void removeTableModelListener( const PTableModelListener& listener );
+ virtual PColumnModel getColumnModel( ColPos column );
+ virtual std::vector<PColumnModel>& getColumnModel();
+ virtual PColumnModel getColumnModelByID( ColumnID id );
+ virtual PTableRenderer getRenderer() const;
+ virtual PTableInputHandler getInputHandler() const;
+ virtual TableMetrics getRowHeight() const;
+ virtual TableMetrics getColumnHeaderHeight() const;
+ virtual TableMetrics getRowHeaderWidth() const;
+ virtual ScrollbarVisibility getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const;
+ virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const;
+ virtual void setVerticalScrollbarVisibility(bool _bVScroll) const;
+ virtual void setHorizontalScrollbarVisibility(bool _bHScroll) const;
+ virtual void setCellContent(const std::vector<std::vector< Any > >& cellContent);
+ virtual std::vector<std::vector< Any > >& getCellContent();
+ virtual void setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent);
+ virtual std::vector<rtl::OUString>& getRowHeaderName();
+ virtual ::com::sun::star::util::Color getLineColor();
+ virtual void setLineColor(::com::sun::star::util::Color _rColor);
+ virtual ::com::sun::star::util::Color getHeaderBackgroundColor();
+ virtual void setHeaderBackgroundColor(::com::sun::star::util::Color _rColor);
+ virtual ::com::sun::star::util::Color getTextColor();
+ virtual void setTextColor(::com::sun::star::util::Color _rColor);
+ virtual ::com::sun::star::util::Color getOddRowBackgroundColor();
+ virtual void setOddRowBackgroundColor(::com::sun::star::util::Color _rColor);
+ virtual ::com::sun::star::util::Color getEvenRowBackgroundColor();
+ virtual void setEvenRowBackgroundColor(::com::sun::star::util::Color _rColor);
+ virtual ::com::sun::star::style::VerticalAlignment getVerticalAlign();
+ virtual void setVerticalAlign(::com::sun::star::style::VerticalAlignment _rAlign);
+ virtual bool hasVerticalScrollbar();
+ virtual bool hasHorizontalScrollbar();
+};
+
+inline void UnoControlTableModel::SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM )
+{
+ getColumnModel( _nColumn )->setWidth( _nWidth100thMM );
+}
+
+inline TableMetrics UnoControlTableModel::GetColumnWidth( ColPos _nColumn )
+{
+ return getColumnModel( _nColumn )->getWidth();
+}
+ #endif // _UNOCONTROL_TABLEMODEL_HXX_
diff --git a/svtools/source/uno/unoevent.cxx b/svtools/source/uno/unoevent.cxx
new file mode 100644
index 000000000000..526cdbb5d03a
--- /dev/null
+++ b/svtools/source/uno/unoevent.cxx
@@ -0,0 +1,610 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP
+#include <com/sun/star/beans/PropertyValue.hpp>
+#endif
+#include <rtl/ustrbuf.hxx>
+
+
+#include <tools/rtti.hxx>
+#include <tools/solar.h>
+#include "unoevent.hxx"
+#include <svl/macitem.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+using ::com::sun::star::container::NoSuchElementException;
+using ::com::sun::star::container::XNameReplace;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::lang::WrappedTargetException;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::beans::PropertyValue;
+using ::cppu::WeakImplHelper2;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+
+const sal_Char sAPI_ServiceName[] = "com.sun.star.container.XNameReplace";
+const sal_Char sAPI_SvDetachedEventDescriptor[] = "SvDetachedEventDescriptor";
+
+//
+// SvBaseEventDescriptor
+//
+
+SvBaseEventDescriptor::SvBaseEventDescriptor( const SvEventDescription* pSupportedMacroItems ) :
+ sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
+ sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")),
+ sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
+ sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic")),
+ sJavaScript(RTL_CONSTASCII_USTRINGPARAM("JavaScript")),
+ sScript(RTL_CONSTASCII_USTRINGPARAM("Script")),
+ sNone(RTL_CONSTASCII_USTRINGPARAM("None")),
+ sServiceName(RTL_CONSTASCII_USTRINGPARAM(sAPI_ServiceName)),
+ sEmpty(),
+ mpSupportedMacroItems(pSupportedMacroItems),
+ mnMacroItems(0)
+{
+ DBG_ASSERT(pSupportedMacroItems != NULL, "Need a list of supported events!");
+
+ for( ; mpSupportedMacroItems[mnMacroItems].mnEvent != 0; mnMacroItems++) ;
+}
+
+
+SvBaseEventDescriptor::~SvBaseEventDescriptor()
+{
+}
+
+void SvBaseEventDescriptor::replaceByName(
+ const OUString& rName,
+ const Any& rElement )
+ throw(
+ IllegalArgumentException,
+ NoSuchElementException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ sal_uInt16 nMacroID = getMacroID(rName);
+
+ // error checking
+ if (0 == nMacroID)
+ throw NoSuchElementException();
+ if (rElement.getValueType() != getElementType())
+ throw IllegalArgumentException();
+
+ // get sequence
+ Sequence<PropertyValue> aSequence;
+ rElement >>= aSequence;
+
+ // perform replace (in subclass)
+ SvxMacro aMacro(sEmpty,sEmpty);
+ getMacroFromAny(aMacro, rElement);
+ replaceByName(nMacroID, aMacro);
+}
+
+Any SvBaseEventDescriptor::getByName(
+ const OUString& rName )
+ throw(
+ NoSuchElementException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ sal_uInt16 nMacroID = getMacroID(rName);
+
+ // error checking
+ if (0 == nMacroID)
+ throw NoSuchElementException();
+
+ // perform get (in subclass)
+ Any aAny;
+ SvxMacro aMacro( sEmpty, sEmpty );
+ getByName(aMacro, nMacroID);
+ getAnyFromMacro(aAny, aMacro);
+ return aAny;
+}
+
+Sequence<OUString> SvBaseEventDescriptor::getElementNames()
+ throw(RuntimeException)
+{
+ // create and fill sequence
+ Sequence<OUString> aSequence(mnMacroItems);
+ for( sal_Int16 i = 0; i < mnMacroItems; i++)
+ {
+ aSequence[i] = OUString::createFromAscii( mpSupportedMacroItems[i].mpEventName );
+ }
+
+ return aSequence;
+}
+
+sal_Bool SvBaseEventDescriptor::hasByName(
+ const OUString& rName )
+ throw(RuntimeException)
+{
+ sal_uInt16 nMacroID = getMacroID(rName);
+ return (nMacroID != 0);
+}
+
+Type SvBaseEventDescriptor::getElementType()
+ throw(RuntimeException)
+{
+ return ::getCppuType((Sequence<PropertyValue> *)0);
+}
+
+sal_Bool SvBaseEventDescriptor::hasElements()
+ throw(RuntimeException)
+{
+ return mnMacroItems != 0;
+}
+
+sal_Bool SvBaseEventDescriptor::supportsService(const OUString& rServiceName)
+ throw(RuntimeException)
+{
+ return sServiceName.equals(rServiceName);
+}
+
+Sequence<OUString> SvBaseEventDescriptor::getSupportedServiceNames(void)
+ throw(RuntimeException)
+{
+ Sequence<OUString> aSequence(1);
+ aSequence[0] = sServiceName;
+
+ return aSequence;
+}
+
+sal_uInt16 SvBaseEventDescriptor::mapNameToEventID(const OUString& rName) const
+{
+ // iterate over known event names
+ for(sal_Int16 i = 0; i < mnMacroItems; i++)
+ {
+ if (0 == rName.compareToAscii(mpSupportedMacroItems[i].mpEventName))
+ {
+ return mpSupportedMacroItems[i].mnEvent;
+ }
+ }
+
+ // not found -> return zero
+ return 0;
+}
+
+OUString SvBaseEventDescriptor::mapEventIDToName(sal_uInt16 nPoolID) const
+{
+ // iterate over known event IDs
+ for(sal_Int16 i = 0; i < mnMacroItems; i++)
+ {
+ if (nPoolID == mpSupportedMacroItems[i].mnEvent)
+ {
+ return OUString::createFromAscii(mpSupportedMacroItems[i].mpEventName);
+ }
+ }
+
+ // not found -> return empty string
+ return OUString();
+}
+
+sal_uInt16 SvBaseEventDescriptor::getMacroID(const OUString& rName) const
+{
+ return mapNameToEventID(rName);
+}
+
+void SvBaseEventDescriptor::getAnyFromMacro(Any& rAny,
+ const SvxMacro& rMacro)
+{
+ sal_Bool bRetValueOK = sal_False; // do we have a ret value?
+
+ if (rMacro.HasMacro())
+ {
+ switch (rMacro.GetScriptType())
+ {
+ case STARBASIC:
+ {
+ // create sequence
+ Sequence<PropertyValue> aSequence(3);
+ Any aTmp;
+
+ // create type
+ PropertyValue aTypeValue;
+ aTypeValue.Name = sEventType;
+ aTmp <<= sStarBasic;
+ aTypeValue.Value = aTmp;
+ aSequence[0] = aTypeValue;
+
+ // macro name
+ PropertyValue aNameValue;
+ aNameValue.Name = sMacroName;
+ OUString sNameTmp(rMacro.GetMacName());
+ aTmp <<= sNameTmp;
+ aNameValue.Value = aTmp;
+ aSequence[1] = aNameValue;
+
+ // library name
+ PropertyValue aLibValue;
+ aLibValue.Name = sLibrary;
+ OUString sLibTmp(rMacro.GetLibName());
+ aTmp <<= sLibTmp;
+ aLibValue.Value = aTmp;
+ aSequence[2] = aLibValue;
+
+ rAny <<= aSequence;
+ bRetValueOK = sal_True;
+ break;
+ }
+ case EXTENDED_STYPE:
+ {
+ // create sequence
+ Sequence<PropertyValue> aSequence(2);
+ Any aTmp;
+
+ // create type
+ PropertyValue aTypeValue;
+ aTypeValue.Name = sEventType;
+ aTmp <<= sScript;
+ aTypeValue.Value = aTmp;
+ aSequence[0] = aTypeValue;
+
+ // macro name
+ PropertyValue aNameValue;
+ aNameValue.Name = sScript;
+ OUString sNameTmp(rMacro.GetMacName());
+ aTmp <<= sNameTmp;
+ aNameValue.Value = aTmp;
+ aSequence[1] = aNameValue;
+
+ rAny <<= aSequence;
+ bRetValueOK = sal_True;
+ break;
+ }
+ case JAVASCRIPT:
+ default:
+ DBG_ERROR("not implemented");
+ }
+ }
+ // else: bRetValueOK not set
+
+ // if we don't have a return value, make an empty one
+ if (! bRetValueOK)
+ {
+ // create "None" macro
+ Sequence<PropertyValue> aSequence(1);
+
+ PropertyValue aKindValue;
+ aKindValue.Name = sEventType;
+ Any aTmp;
+ aTmp <<= sNone;
+ aKindValue.Value = aTmp;
+ aSequence[0] = aKindValue;
+
+ rAny <<= aSequence;
+ bRetValueOK = sal_True;
+ }
+}
+
+
+void SvBaseEventDescriptor::getMacroFromAny(
+ SvxMacro& rMacro,
+ const Any& rAny)
+ throw ( IllegalArgumentException )
+{
+ // get sequence
+ Sequence<PropertyValue> aSequence;
+ rAny >>= aSequence;
+
+ // process ...
+ sal_Bool bTypeOK = sal_False;
+ sal_Bool bNone = sal_False; // true if EventType=="None"
+ enum ScriptType eType = EXTENDED_STYPE;
+ OUString sScriptVal;
+ OUString sMacroVal;
+ OUString sLibVal;
+ sal_Int32 nCount = aSequence.getLength();
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ PropertyValue& aValue = aSequence[i];
+ if (aValue.Name.equals(sEventType))
+ {
+ OUString sTmp;
+ aValue.Value >>= sTmp;
+ if (sTmp.equals(sStarBasic))
+ {
+ eType = STARBASIC;
+ bTypeOK = sal_True;
+ }
+ else if (sTmp.equals(sJavaScript))
+ {
+ eType = JAVASCRIPT;
+ bTypeOK = sal_True;
+ }
+ else if (sTmp.equals(sScript))
+ {
+ eType = EXTENDED_STYPE;
+ bTypeOK = sal_True;
+ }
+ else if (sTmp.equals(sNone))
+ {
+ bNone = sal_True;
+ bTypeOK = sal_True;
+ }
+ // else: unknown script type
+ }
+ else if (aValue.Name.equals(sMacroName))
+ {
+ aValue.Value >>= sMacroVal;
+ }
+ else if (aValue.Name.equals(sLibrary))
+ {
+ aValue.Value >>= sLibVal;
+ }
+ else if (aValue.Name.equals(sScript))
+ {
+ aValue.Value >>= sScriptVal;
+ }
+ // else: unknown PropertyValue -> ignore
+ }
+
+ if (bTypeOK)
+ {
+ if (bNone)
+ {
+ // return empty macro
+ rMacro = SvxMacro( sEmpty, sEmpty );
+ }
+ else
+ {
+ if (eType == STARBASIC)
+ {
+ // create macro and return
+ SvxMacro aMacro(sMacroVal, sLibVal, eType);
+ rMacro = aMacro;
+ }
+ else if (eType == EXTENDED_STYPE)
+ {
+ SvxMacro aMacro(sScriptVal, sScript);
+ rMacro = aMacro;
+ }
+ else
+ {
+ // we can't process type: abort
+ // TODO: JavaScript macros
+ throw IllegalArgumentException();
+ }
+ }
+ }
+ else
+ {
+ // no valid type: abort
+ throw IllegalArgumentException();
+ }
+}
+
+
+
+
+//
+// SvEventDescriptor
+//
+
+
+SvEventDescriptor::SvEventDescriptor(
+ XInterface& rParent,
+ const SvEventDescription* pSupportedMacroItems) :
+ SvBaseEventDescriptor(pSupportedMacroItems),
+ xParentRef(&rParent)
+{
+}
+
+
+SvEventDescriptor::~SvEventDescriptor()
+{
+ // automatically release xParentRef !
+}
+
+void SvEventDescriptor::replaceByName(
+ const sal_uInt16 nEvent,
+ const SvxMacro& rMacro)
+ throw(
+ IllegalArgumentException,
+ NoSuchElementException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ SvxMacroItem aItem(getMacroItemWhich());
+ aItem.SetMacroTable(getMacroItem().GetMacroTable());
+ aItem.SetMacro(nEvent, rMacro);
+ setMacroItem(aItem);
+}
+
+void SvEventDescriptor::getByName(
+ SvxMacro& rMacro,
+ const sal_uInt16 nEvent )
+ throw(
+ NoSuchElementException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ const SvxMacroItem& rItem = getMacroItem();
+ if( rItem.HasMacro( nEvent ) )
+ rMacro = rItem.GetMacro(nEvent);
+ else
+ {
+ SvxMacro aEmptyMacro(sEmpty, sEmpty);
+ rMacro = aEmptyMacro;
+ }
+}
+
+
+
+
+//
+// SvDetachedEventDescriptor
+//
+
+SvDetachedEventDescriptor::SvDetachedEventDescriptor(
+ const SvEventDescription* pSupportedMacroItems) :
+ SvBaseEventDescriptor(pSupportedMacroItems),
+ sImplName(RTL_CONSTASCII_USTRINGPARAM(sAPI_SvDetachedEventDescriptor))
+{
+ // allocate aMacros
+ aMacros = new SvxMacro*[mnMacroItems];
+
+ // ... and initialize
+ for(sal_Int16 i = 0; i < mnMacroItems; i++)
+ {
+ aMacros[i] = NULL;
+ }
+}
+
+SvDetachedEventDescriptor::~SvDetachedEventDescriptor()
+{
+ // delete contents of aMacros
+ for(sal_Int16 i = 0; i < mnMacroItems; i++)
+ {
+ if (NULL != aMacros[i])
+ delete aMacros[i];
+ }
+
+ delete [] aMacros;
+}
+
+sal_Int16 SvDetachedEventDescriptor::getIndex(const sal_uInt16 nID) const
+{
+ // iterate over supported events
+ sal_Int16 nIndex = 0;
+ while ( (mpSupportedMacroItems[nIndex].mnEvent != nID) &&
+ (mpSupportedMacroItems[nIndex].mnEvent != 0) )
+ {
+ nIndex++;
+ }
+ return (mpSupportedMacroItems[nIndex].mnEvent == nID) ? nIndex : -1;
+}
+
+OUString SvDetachedEventDescriptor::getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ return sImplName;
+}
+
+
+void SvDetachedEventDescriptor::replaceByName(
+ const sal_uInt16 nEvent,
+ const SvxMacro& rMacro)
+ throw(
+ IllegalArgumentException,
+ NoSuchElementException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ sal_Int16 nIndex = getIndex(nEvent);
+ if (-1 == nIndex)
+ throw IllegalArgumentException();
+
+ aMacros[nIndex] = new SvxMacro(rMacro.GetMacName(), rMacro.GetLibName(),
+ rMacro.GetScriptType() );
+}
+
+
+void SvDetachedEventDescriptor::getByName(
+ SvxMacro& rMacro,
+ const sal_uInt16 nEvent )
+ throw(
+ NoSuchElementException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ sal_Int16 nIndex = getIndex(nEvent);
+ if (-1 == nIndex )
+ throw NoSuchElementException();
+
+ if( aMacros[nIndex] )
+ rMacro = (*aMacros[nIndex]);
+}
+
+sal_Bool SvDetachedEventDescriptor::hasByName(
+ const sal_uInt16 nEvent ) const /// item ID of event
+ throw(IllegalArgumentException)
+{
+ sal_Int16 nIndex = getIndex(nEvent);
+ if (-1 == nIndex)
+ throw IllegalArgumentException();
+
+ return (NULL == aMacros[nIndex]) ? sal_False : aMacros[nIndex]->HasMacro();
+}
+
+
+//
+// SvMacroTableEventDescriptor
+//
+
+SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(const SvEventDescription* pSupportedMacroItems) :
+ SvDetachedEventDescriptor(pSupportedMacroItems)
+{
+}
+
+SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(
+ const SvxMacroTableDtor& rMacroTable,
+ const SvEventDescription* pSupportedMacroItems) :
+ SvDetachedEventDescriptor(pSupportedMacroItems)
+{
+ copyMacrosFromTable(rMacroTable);
+}
+
+SvMacroTableEventDescriptor::~SvMacroTableEventDescriptor()
+{
+}
+
+void SvMacroTableEventDescriptor::copyMacrosFromTable(
+ const SvxMacroTableDtor& rMacroTable)
+{
+ for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++)
+ {
+ const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent;
+ const SvxMacro* pMacro = rMacroTable.Get(nEvent);
+ if (NULL != pMacro)
+ replaceByName(nEvent, *pMacro);
+ }
+
+}
+
+void SvMacroTableEventDescriptor::copyMacrosIntoTable(
+ SvxMacroTableDtor& rMacroTable)
+{
+ for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++)
+ {
+ const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent;
+ if (hasByName(nEvent))
+ {
+ SvxMacro* pMacro = new SvxMacro(sEmpty, sEmpty);
+ getByName(*pMacro, nEvent);
+ rMacroTable.Insert(nEvent, pMacro);
+ }
+ }
+}
+
+
+
diff --git a/svtools/source/uno/unoiface.cxx b/svtools/source/uno/unoiface.cxx
new file mode 100644
index 000000000000..2d22d9cedb33
--- /dev/null
+++ b/svtools/source/uno/unoiface.cxx
@@ -0,0 +1,2367 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#define _SVT_UNOIFACE_CXX
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svtools/svmedit.hxx>
+#include <unoiface.hxx>
+#include "filedlg.hxx"
+#include "filectrl.hxx"
+#include "roadmap.hxx"
+#include <svtools/fixedhyper.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/awt/LineEndFormat.hpp>
+#include <comphelper/processfactory.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <toolkit/helper/property.hxx>
+#include <svtools/fmtfield.hxx>
+#include <svl/numuno.hxx>
+#include <calendar.hxx>
+#include <prgsbar.hxx>
+
+#include <svtools/svtreebx.hxx>
+#include "treecontrolpeer.hxx"
+#include "svtxgridcontrol.hxx"
+#include <svtools/table/tablecontrol.hxx>
+
+namespace
+{
+ static void lcl_setWinBits( Window* _pWindow, WinBits _nBits, sal_Bool _bSet )
+ {
+ WinBits nStyle = _pWindow->GetStyle();
+ if ( _bSet )
+ nStyle |= _nBits;
+ else
+ nStyle &= ~_nBits;
+ _pWindow->SetStyle( nStyle );
+ }
+}
+
+// ----------------------------------------------------
+// help function for the toolkit...
+// ----------------------------------------------------
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT Window* CreateWindow( VCLXWindow** ppNewComp, const ::com::sun::star::awt::WindowDescriptor* pDescriptor, Window* pParent, WinBits nWinBits )
+{
+ Window* pWindow = NULL;
+ String aServiceName( pDescriptor->WindowServiceName );
+ if ( aServiceName.EqualsIgnoreCaseAscii( "MultiLineEdit" ) )
+ {
+ if ( pParent )
+ {
+ pWindow = new MultiLineEdit( pParent, nWinBits|WB_IGNORETAB);
+ *ppNewComp = new VCLXMultiLineEdit;
+ }
+ else
+ {
+ *ppNewComp = NULL;
+ return NULL;
+ }
+ }
+ else if ( aServiceName.EqualsIgnoreCaseAscii( "FileControl" ) )
+ {
+ if ( pParent )
+ {
+ pWindow = new FileControl( pParent, nWinBits );
+ *ppNewComp = new VCLXFileControl;
+ }
+ else
+ {
+ *ppNewComp = NULL;
+ return NULL;
+ }
+ }
+ else if (aServiceName.EqualsIgnoreCaseAscii("FormattedField") )
+ {
+ pWindow = new FormattedField( pParent, nWinBits );
+ *ppNewComp = new SVTXFormattedField;
+ }
+ else if (aServiceName.EqualsIgnoreCaseAscii("NumericField") )
+ {
+ pWindow = new DoubleNumericField( pParent, nWinBits );
+ *ppNewComp = new SVTXNumericField;
+ }
+ else if (aServiceName.EqualsIgnoreCaseAscii("LongCurrencyField") )
+ {
+ pWindow = new DoubleCurrencyField( pParent, nWinBits );
+ *ppNewComp = new SVTXCurrencyField;
+ }
+ else if (aServiceName.EqualsIgnoreCaseAscii("datefield") )
+ {
+ pWindow = new CalendarField( pParent, nWinBits);
+ static_cast<CalendarField*>(pWindow)->EnableToday();
+ static_cast<CalendarField*>(pWindow)->EnableNone();
+ static_cast<CalendarField*>(pWindow)->EnableEmptyFieldValue( TRUE );
+ *ppNewComp = new SVTXDateField;
+ ((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(DateField*)pWindow );
+ }
+ else if (aServiceName.EqualsIgnoreCaseAscii("roadmap") )
+ {
+ pWindow = new ::svt::ORoadmap( pParent, WB_TABSTOP );
+ *ppNewComp = new SVTXRoadmap;
+ }
+ else if ( aServiceName.EqualsIgnoreCaseAscii( "ProgressBar" ) )
+ {
+ if ( pParent )
+ {
+ pWindow = new ProgressBar( pParent, nWinBits );
+ *ppNewComp = new VCLXProgressBar;
+ }
+ else
+ {
+ *ppNewComp = NULL;
+ return NULL;
+ }
+ }
+ else if ( aServiceName.EqualsIgnoreCaseAscii( "Tree" ) )
+ {
+ TreeControlPeer* pPeer = new TreeControlPeer;
+ *ppNewComp = pPeer;
+ pWindow = pPeer->createVclControl( pParent, nWinBits );
+ }
+ else if ( aServiceName.EqualsIgnoreCaseAscii( "FixedHyperlink" ) )
+ {
+ if ( pParent )
+ {
+ pWindow = new ::svt::FixedHyperlink( pParent, nWinBits );
+ *ppNewComp = new VCLXFixedHyperlink;
+ }
+ else
+ {
+ *ppNewComp = NULL;
+ return NULL;
+ }
+ }
+ else if ( aServiceName.EqualsIgnoreCaseAscii( "Grid" ) )
+ {
+ if ( pParent )
+ {
+ pWindow = new ::svt::table::TableControl(pParent, nWinBits);
+ *ppNewComp = new SVTXGridControl;
+ }
+ else
+ {
+ *ppNewComp = NULL;
+ return NULL;
+ }
+ }
+ return pWindow;
+}
+
+} // extern "C"
+
+// ----------------------------------------------------
+// class VCLXMultiLineEdit
+// ----------------------------------------------------
+VCLXMultiLineEdit::VCLXMultiLineEdit()
+ :maTextListeners( *this )
+ ,meLineEndType( LINEEND_LF ) // default behavior before introducing this property: LF (unix-like)
+{
+}
+
+VCLXMultiLineEdit::~VCLXMultiLineEdit()
+{
+}
+
+::com::sun::star::uno::Any VCLXMultiLineEdit::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::awt::XTextComponent*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::XTextArea*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::XTextLayoutConstrains*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
+ return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
+}
+
+// ::com::sun::star::lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( VCLXMultiLineEdit )
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent>* ) NULL ),
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextArea>* ) NULL ),
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains>* ) NULL ),
+ VCLXWindow::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+void VCLXMultiLineEdit::addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException)
+{
+ maTextListeners.addInterface( l );
+}
+
+void VCLXMultiLineEdit::removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException)
+{
+ maTextListeners.removeInterface( l );
+}
+
+void VCLXMultiLineEdit::setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow();
+ if ( pEdit )
+ {
+ pEdit->SetText( aText );
+
+ // #107218# Call same listeners like VCL would do after user interaction
+ SetSynthesizingVCLEvent( sal_True );
+ pEdit->SetModifyFlag();
+ pEdit->Modify();
+ SetSynthesizingVCLEvent( sal_False );
+ }
+}
+
+void VCLXMultiLineEdit::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow();
+ if ( pEdit )
+ {
+ setSelection( rSel );
+ pEdit->ReplaceSelected( aText );
+ }
+}
+
+::rtl::OUString VCLXMultiLineEdit::getText() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::rtl::OUString aText;
+ MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow();
+ if ( pEdit )
+ aText = pEdit->GetText( meLineEndType );
+ return aText;
+}
+
+::rtl::OUString VCLXMultiLineEdit::getSelectedText() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::rtl::OUString aText;
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ if ( pMultiLineEdit)
+ aText = pMultiLineEdit->GetSelected( meLineEndType );
+ return aText;
+
+}
+
+void VCLXMultiLineEdit::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ if ( pMultiLineEdit )
+ {
+ pMultiLineEdit->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
+ }
+}
+
+::com::sun::star::awt::Selection VCLXMultiLineEdit::getSelection() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Selection aSel;
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ if ( pMultiLineEdit )
+ {
+ aSel.Min = pMultiLineEdit->GetSelection().Min();
+ aSel.Max = pMultiLineEdit->GetSelection().Max();
+ }
+ return aSel;
+}
+
+sal_Bool VCLXMultiLineEdit::isEditable() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ return ( pMultiLineEdit && !pMultiLineEdit->IsReadOnly() && pMultiLineEdit->IsEnabled() ) ? sal_True : sal_False;
+}
+
+void VCLXMultiLineEdit::setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ if ( pMultiLineEdit )
+ pMultiLineEdit->SetReadOnly( !bEditable );
+}
+
+void VCLXMultiLineEdit::setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ if ( pMultiLineEdit )
+ pMultiLineEdit->SetMaxTextLen( nLen );
+}
+
+sal_Int16 VCLXMultiLineEdit::getMaxTextLen() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow();
+ return pMultiLineEdit ? (sal_Int16)pMultiLineEdit->GetMaxTextLen() : (sal_Int16)0;
+}
+
+::rtl::OUString VCLXMultiLineEdit::getTextLines() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::rtl::OUString aText;
+ MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow();
+ if ( pEdit )
+ aText = pEdit->GetTextLines( meLineEndType );
+ return aText;
+}
+
+::com::sun::star::awt::Size VCLXMultiLineEdit::getMinimumSize() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz;
+ MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
+ if ( pEdit )
+ aSz = AWTSize(pEdit->CalcMinimumSize());
+ return aSz;
+}
+
+::com::sun::star::awt::Size VCLXMultiLineEdit::getPreferredSize() throw(::com::sun::star::uno::RuntimeException)
+{
+ return getMinimumSize();
+}
+
+::com::sun::star::awt::Size VCLXMultiLineEdit::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz = rNewSize;
+ MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
+ if ( pEdit )
+ aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize )));
+ return aSz;
+}
+
+::com::sun::star::awt::Size VCLXMultiLineEdit::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz;
+ MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
+ if ( pEdit )
+ aSz = AWTSize(pEdit->CalcSize( nCols, nLines ));
+ return aSz;
+}
+
+void VCLXMultiLineEdit::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ nCols = nLines = 0;
+ MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
+ if ( pEdit )
+ {
+ sal_uInt16 nC, nL;
+ pEdit->GetMaxVisColumnsAndLines( nC, nL );
+ nCols = nC;
+ nLines = nL;
+ }
+}
+
+void VCLXMultiLineEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+{
+ switch ( rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_EDIT_MODIFY:
+ {
+ if ( maTextListeners.getLength() )
+ {
+ ::com::sun::star::awt::TextEvent aEvent;
+ aEvent.Source = (::cppu::OWeakObject*)this;
+ maTextListeners.textChanged( aEvent );
+ }
+ }
+ break;
+ default:
+ {
+ VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
+ }
+ break;
+ }
+}
+
+void VCLXMultiLineEdit::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*)GetWindow();
+ if ( pMultiLineEdit )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch ( nPropType )
+ {
+ case BASEPROPERTY_LINE_END_FORMAT:
+ {
+ sal_Int16 nLineEndType = ::com::sun::star::awt::LineEndFormat::LINE_FEED;
+ OSL_VERIFY( Value >>= nLineEndType );
+ switch ( nLineEndType )
+ {
+ case ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN: meLineEndType = LINEEND_CR; break;
+ case ::com::sun::star::awt::LineEndFormat::LINE_FEED: meLineEndType = LINEEND_LF; break;
+ case ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: meLineEndType = LINEEND_CRLF; break;
+ default: DBG_ERROR( "VCLXMultiLineEdit::setProperty: invalid line end value!" ); break;
+ }
+ }
+ break;
+
+ case BASEPROPERTY_READONLY:
+ {
+ sal_Bool b = sal_Bool();
+ if ( Value >>= b )
+ pMultiLineEdit->SetReadOnly( b );
+ }
+ break;
+ case BASEPROPERTY_MAXTEXTLEN:
+ {
+ sal_Int16 n = sal_Int16();
+ if ( Value >>= n )
+ pMultiLineEdit->SetMaxTextLen( n );
+ }
+ break;
+ case BASEPROPERTY_HIDEINACTIVESELECTION:
+ {
+ sal_Bool b = sal_Bool();
+ if ( Value >>= b )
+ {
+ pMultiLineEdit->EnableFocusSelectionHide( b );
+ lcl_setWinBits( pMultiLineEdit, WB_NOHIDESELECTION, !b );
+ }
+ }
+ break;
+ default:
+ {
+ VCLXWindow::setProperty( PropertyName, Value );
+ }
+ }
+ }
+}
+
+::com::sun::star::uno::Any VCLXMultiLineEdit::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::uno::Any aProp;
+ MultiLineEdit* pMultiLineEdit = (MultiLineEdit*)GetWindow();
+ if ( pMultiLineEdit )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch ( nPropType )
+ {
+ case BASEPROPERTY_LINE_END_FORMAT:
+ {
+ sal_Int16 nLineEndType = ::com::sun::star::awt::LineEndFormat::LINE_FEED;
+ switch ( meLineEndType )
+ {
+ case LINEEND_CR: nLineEndType = ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN; break;
+ case LINEEND_LF: nLineEndType = ::com::sun::star::awt::LineEndFormat::LINE_FEED; break;
+ case LINEEND_CRLF: nLineEndType = ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED; break;
+ default: DBG_ERROR( "VCLXMultiLineEdit::getProperty: invalid line end value!" ); break;
+ }
+ aProp <<= nLineEndType;
+ }
+ break;
+
+ case BASEPROPERTY_READONLY:
+ {
+ aProp <<= pMultiLineEdit->IsReadOnly();
+ }
+ break;
+ case BASEPROPERTY_MAXTEXTLEN:
+ {
+ aProp <<= (sal_Int16) pMultiLineEdit->GetMaxTextLen();
+ }
+ break;
+ default:
+ {
+ aProp <<= VCLXWindow::getProperty( PropertyName );
+ }
+ }
+ }
+ return aProp;
+}
+
+void SAL_CALL VCLXMultiLineEdit::setFocus( ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ // don't grab the focus if we already have it. Reason is that the only thing which the edit
+ // does is forwarding the focus to it's text window. This text window then does a "select all".
+ // So if the text window already has the focus, and we give the focus to the multi line
+ // edit, then all which happens is that everything is selected.
+ // #i27072# - 2004-04-25 - fs@openoffice.org
+ if ( GetWindow() && !GetWindow()->HasChildPathFocus() )
+ GetWindow()->GrabFocus();
+}
+
+void VCLXMultiLineEdit::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ // FIXME: elide duplication ?
+ BASEPROPERTY_LINE_END_FORMAT,
+ BASEPROPERTY_READONLY,
+ BASEPROPERTY_MAXTEXTLEN,
+ BASEPROPERTY_HIDEINACTIVESELECTION,
+ 0);
+ VCLXWindow::ImplGetPropertyIds( rIds, true );
+
+}
+// ----------------------------------------------------
+// class VCLXFileControl
+// ----------------------------------------------------
+VCLXFileControl::VCLXFileControl() : maTextListeners( *this )
+{
+}
+
+VCLXFileControl::~VCLXFileControl()
+{
+ FileControl* pControl = (FileControl*) GetWindow();
+ if ( pControl )
+ pControl->GetEdit().SetModifyHdl( Link() );
+}
+
+::com::sun::star::uno::Any VCLXFileControl::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::awt::XTextComponent*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::XTextLayoutConstrains*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
+ return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
+}
+
+// ::com::sun::star::lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( VCLXFileControl )
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent>* ) NULL ),
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains>* ) NULL ),
+ VCLXWindow::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+void SAL_CALL VCLXFileControl::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pControl = (FileControl*)GetWindow();
+ if ( pControl )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch ( nPropType )
+ {
+ case BASEPROPERTY_HIDEINACTIVESELECTION:
+ {
+ sal_Bool bValue( sal_False );
+ OSL_VERIFY( Value >>= bValue );
+
+ lcl_setWinBits( pControl, WB_NOHIDESELECTION, !bValue );
+ lcl_setWinBits( &pControl->GetEdit(), WB_NOHIDESELECTION, !bValue );
+ }
+ break;
+
+ default:
+ VCLXWindow::setProperty( PropertyName, Value );
+ break;
+ }
+ }
+}
+
+void VCLXFileControl::SetWindow( Window* pWindow )
+{
+ FileControl* pPrevFileControl = dynamic_cast<FileControl*>( GetWindow() );
+ if ( pPrevFileControl )
+ pPrevFileControl->GetEdit().SetModifyHdl( Link() );
+
+ FileControl* pNewFileControl = dynamic_cast<FileControl*>( pWindow );
+ if ( pNewFileControl )
+ pNewFileControl->GetEdit().SetModifyHdl( LINK( this, VCLXFileControl, ModifyHdl ) );
+
+ VCLXWindow::SetWindow( pWindow );
+}
+
+void VCLXFileControl::addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException)
+{
+ maTextListeners.addInterface( l );
+}
+
+void VCLXFileControl::removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException)
+{
+ maTextListeners.removeInterface( l );
+}
+
+void VCLXFileControl::setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ Window* pWindow = GetWindow();
+ if ( pWindow )
+ {
+ pWindow->SetText( aText );
+
+ // In JAVA wird auch ein textChanged ausgeloest, in VCL nicht.
+ // ::com::sun::star::awt::Toolkit soll JAVA-komform sein...
+ ModifyHdl( NULL );
+ }
+}
+
+void VCLXFileControl::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ if ( pFileControl )
+ {
+ pFileControl->GetEdit().SetSelection( Selection( rSel.Min, rSel.Max ) );
+ pFileControl->GetEdit().ReplaceSelected( aText );
+ }
+}
+
+::rtl::OUString VCLXFileControl::getText() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::rtl::OUString aText;
+ Window* pWindow = GetWindow();
+ if ( pWindow )
+ aText = pWindow->GetText();
+ return aText;
+}
+
+::rtl::OUString VCLXFileControl::getSelectedText() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::rtl::OUString aText;
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ if ( pFileControl)
+ aText = pFileControl->GetEdit().GetSelected();
+ return aText;
+
+}
+
+void VCLXFileControl::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ if ( pFileControl )
+ pFileControl->GetEdit().SetSelection( Selection( aSelection.Min, aSelection.Max ) );
+}
+
+::com::sun::star::awt::Selection VCLXFileControl::getSelection() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Selection aSel;
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ if ( pFileControl )
+ {
+ aSel.Min = pFileControl->GetEdit().GetSelection().Min();
+ aSel.Max = pFileControl->GetEdit().GetSelection().Max();
+ }
+ return aSel;
+}
+
+sal_Bool VCLXFileControl::isEditable() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ return ( pFileControl && !pFileControl->GetEdit().IsReadOnly() && pFileControl->GetEdit().IsEnabled() ) ? sal_True : sal_False;
+}
+
+void VCLXFileControl::setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ if ( pFileControl )
+ pFileControl->GetEdit().SetReadOnly( !bEditable );
+}
+
+void VCLXFileControl::setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ if ( pFileControl )
+ pFileControl->GetEdit().SetMaxTextLen( nLen );
+}
+
+sal_Int16 VCLXFileControl::getMaxTextLen() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FileControl* pFileControl = (FileControl*) GetWindow();
+ return pFileControl ? pFileControl->GetEdit().GetMaxTextLen() : 0;
+}
+
+
+IMPL_LINK( VCLXFileControl, ModifyHdl, Edit*, EMPTYARG )
+{
+ ::com::sun::star::awt::TextEvent aEvent;
+ aEvent.Source = (::cppu::OWeakObject*)this;
+ maTextListeners.textChanged( aEvent );
+
+ return 1;
+}
+
+::com::sun::star::awt::Size VCLXFileControl::getMinimumSize() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz;
+ FileControl* pControl = (FileControl*) GetWindow();
+ if ( pControl )
+ {
+ Size aTmpSize = pControl->GetEdit().CalcMinimumSize();
+ aTmpSize.Width() += pControl->GetButton().CalcMinimumSize().Width();
+ aSz = AWTSize(pControl->CalcWindowSize( aTmpSize ));
+ }
+ return aSz;
+}
+
+::com::sun::star::awt::Size VCLXFileControl::getPreferredSize() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::awt::Size aSz = getMinimumSize();
+ aSz.Height += 4;
+ return aSz;
+}
+
+::com::sun::star::awt::Size VCLXFileControl::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz =rNewSize;
+ FileControl* pControl = (FileControl*) GetWindow();
+ if ( pControl )
+ {
+ ::com::sun::star::awt::Size aMinSz = getMinimumSize();
+ if ( aSz.Height != aMinSz.Height )
+ aSz.Height = aMinSz.Height;
+ }
+ return aSz;
+}
+
+::com::sun::star::awt::Size VCLXFileControl::getMinimumSize( sal_Int16 nCols, sal_Int16 ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::awt::Size aSz;
+ FileControl* pControl = (FileControl*) GetWindow();
+ if ( pControl )
+ {
+ aSz = AWTSize(pControl->GetEdit().CalcSize( nCols ));
+ aSz.Width += pControl->GetButton().CalcMinimumSize().Width();
+ }
+ return aSz;
+}
+
+void VCLXFileControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ nCols = 0;
+ nLines = 1;
+ FileControl* pControl = (FileControl*) GetWindow();
+ if ( pControl )
+ nCols = (sal_Int16) pControl->GetEdit().GetMaxVisChars();
+}
+
+void VCLXFileControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ // FIXME: elide duplication ?
+ BASEPROPERTY_HIDEINACTIVESELECTION,
+ 0);
+ VCLXWindow::ImplGetPropertyIds( rIds, true );
+}
+
+
+// ----------------------------------------------------
+// class SVTXFormattedField
+// ----------------------------------------------------
+// --------------------------------------------------------------------------------------
+SVTXFormattedField::SVTXFormattedField()
+ :m_pCurrentSupplier(NULL)
+ ,bIsStandardSupplier(sal_True)
+ ,nKeyToSetDelayed(-1)
+{
+}
+
+// --------------------------------------------------------------------------------------
+SVTXFormattedField::~SVTXFormattedField()
+{
+ if (m_pCurrentSupplier)
+ {
+ m_pCurrentSupplier->release();
+ m_pCurrentSupplier = NULL;
+ }
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::SetWindow( Window* _pWindow )
+{
+ VCLXSpinField::SetWindow(_pWindow);
+ if (GetFormattedField())
+ GetFormattedField()->SetAutoColor(TRUE);
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch (nPropType)
+ {
+ case BASEPROPERTY_ENFORCE_FORMAT:
+ {
+ sal_Bool bEnable( sal_True );
+ if ( Value >>= bEnable )
+ pField->EnableNotANumber( !bEnable );
+ }
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_MIN:
+ case BASEPROPERTY_VALUEMIN_DOUBLE:
+ SetMinValue(Value);
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_MAX:
+ case BASEPROPERTY_VALUEMAX_DOUBLE:
+ SetMaxValue(Value);
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_DEFAULT:
+ SetDefaultValue(Value);
+ break;
+
+ case BASEPROPERTY_TREATASNUMBER:
+ {
+ sal_Bool b = sal_Bool();
+ if ( Value >>= b )
+ SetTreatAsNumber(b);
+ }
+ break;
+
+ case BASEPROPERTY_FORMATSSUPPLIER:
+ if (!Value.hasValue())
+ setFormatsSupplier(::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > (NULL));
+ else
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > xNFS;
+ if ( Value >>= xNFS )
+ setFormatsSupplier(xNFS);
+ }
+ break;
+ case BASEPROPERTY_FORMATKEY:
+ if (!Value.hasValue())
+ setFormatKey(0);
+ else
+ {
+ sal_Int32 n = 0;
+ if ( Value >>= n )
+ setFormatKey(n);
+ }
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_VALUE:
+ case BASEPROPERTY_VALUE_DOUBLE:
+ {
+ const ::com::sun::star::uno::TypeClass rTC = Value.getValueType().getTypeClass();
+ if (rTC != ::com::sun::star::uno::TypeClass_STRING)
+ // no string
+ if (rTC != ::com::sun::star::uno::TypeClass_DOUBLE)
+ // no double
+ if (Value.hasValue())
+ { // but a value
+ // try if it is something converitble
+ sal_Int32 nValue = 0;
+ if (!(Value >>= nValue))
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ SetValue(::com::sun::star::uno::makeAny((double)nValue));
+ break;
+ }
+
+ SetValue(Value);
+ }
+ break;
+ case BASEPROPERTY_VALUESTEP_DOUBLE:
+ {
+ double d = 0.0;
+ if ( Value >>= d )
+ pField->SetSpinSize( d );
+ else
+ {
+ sal_Int32 n = 0;
+ if ( Value >>= n )
+ pField->SetSpinSize( n );
+ }
+ }
+ break;
+ case BASEPROPERTY_DECIMALACCURACY:
+ {
+ sal_Int32 n = 0;
+ if ( Value >>= n )
+ pField->SetDecimalDigits( (sal_uInt16)n );
+ }
+ break;
+ case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
+ {
+ sal_Bool b = sal_Bool();
+ if ( Value >>= b )
+ pField->SetThousandsSep( b );
+ }
+ break;
+
+ default:
+ VCLXSpinField::setProperty( PropertyName, Value );
+ }
+
+ if (BASEPROPERTY_TEXTCOLOR == nPropType)
+ { // after setting a new text color, think again about the AutoColor flag of the control
+ // 17.05.2001 - 86859 - frank.schoenheit@germany.sun.com
+ pField->SetAutoColor(!Value.hasValue());
+ }
+ }
+ else
+ VCLXSpinField::setProperty( PropertyName, Value );
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXFormattedField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::uno::Any aReturn;
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch (nPropType)
+ {
+ case BASEPROPERTY_EFFECTIVE_MIN:
+ case BASEPROPERTY_VALUEMIN_DOUBLE:
+ aReturn <<= GetMinValue();
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_MAX:
+ case BASEPROPERTY_VALUEMAX_DOUBLE:
+ aReturn <<= GetMaxValue();
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_DEFAULT:
+ aReturn <<= GetDefaultValue();
+ break;
+
+ case BASEPROPERTY_TREATASNUMBER:
+ aReturn <<= GetTreatAsNumber();
+ break;
+
+ case BASEPROPERTY_EFFECTIVE_VALUE:
+ case BASEPROPERTY_VALUE_DOUBLE:
+ aReturn <<= GetValue();
+ break;
+
+ case BASEPROPERTY_VALUESTEP_DOUBLE:
+ aReturn <<= pField->GetSpinSize();
+ break;
+
+ case BASEPROPERTY_DECIMALACCURACY:
+ aReturn <<= pField->GetDecimalDigits();
+ break;
+
+ case BASEPROPERTY_FORMATSSUPPLIER:
+ {
+ if (!bIsStandardSupplier)
+ { // ansonsten void
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getFormatsSupplier();
+ aReturn <<= xSupplier;
+ }
+ }
+ break;
+
+ case BASEPROPERTY_FORMATKEY:
+ {
+ if (!bIsStandardSupplier)
+ aReturn <<= getFormatKey();
+ }
+ break;
+
+ default:
+ aReturn <<= VCLXSpinField::getProperty(PropertyName);
+ }
+ }
+ return aReturn;
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXFormattedField::convertEffectiveValue(const ::com::sun::star::uno::Any& rValue)
+{
+ ::com::sun::star::uno::Any aReturn;
+
+ FormattedField* pField = GetFormattedField();
+ if (!pField)
+ return aReturn;
+
+ switch (rValue.getValueType().getTypeClass())
+ {
+ case ::com::sun::star::uno::TypeClass_DOUBLE:
+ if (pField->TreatingAsNumber())
+ {
+ double d = 0.0;
+ rValue >>= d;
+ aReturn <<= d;
+ }
+ else
+ {
+ SvNumberFormatter* pFormatter = pField->GetFormatter();
+ if (!pFormatter)
+ pFormatter = pField->StandardFormatter();
+ // should never fail
+
+ Color* pDum;
+ double d = 0.0;
+ rValue >>= d;
+ String sConverted;
+ pFormatter->GetOutputString(d, 0, sConverted, &pDum);
+ aReturn <<= ::rtl::OUString( sConverted );
+ }
+ break;
+ case ::com::sun::star::uno::TypeClass_STRING:
+ {
+ ::rtl::OUString aStr;
+ rValue >>= aStr;
+ String sValue = aStr;
+ if (pField->TreatingAsNumber())
+ {
+ SvNumberFormatter* pFormatter = pField->GetFormatter();
+ if (!pFormatter)
+ pFormatter = pField->StandardFormatter();
+
+ double dVal;
+ sal_uInt32 nTestFormat(0);
+ if (!pFormatter->IsNumberFormat(sValue, nTestFormat, dVal))
+ aReturn.clear();
+ aReturn <<=dVal;
+ }
+ else
+ aReturn <<= aStr;
+ }
+ break;
+ default:
+ aReturn.clear();
+ break;
+ }
+ return aReturn;
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::SetMinValue(const ::com::sun::star::uno::Any& rValue)
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField)
+ return;
+
+ switch (rValue.getValueType().getTypeClass())
+
+ {
+ case ::com::sun::star::uno::TypeClass_DOUBLE:
+ {
+ double d = 0.0;
+ rValue >>= d;
+ pField->SetMinValue(d);
+ }
+ break;
+ default:
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID, "SVTXFormattedField::SetMinValue : invalid argument (an exception will be thrown) !");
+ if ( rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID )
+
+ {
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+ pField->ClearMinValue();
+ break;
+ }
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXFormattedField::GetMinValue()
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField || !pField->HasMinValue())
+ return ::com::sun::star::uno::Any();
+
+ ::com::sun::star::uno::Any aReturn;
+ aReturn <<= pField->GetMinValue();
+ return aReturn;
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::SetMaxValue(const ::com::sun::star::uno::Any& rValue)
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField)
+ return;
+
+ switch (rValue.getValueType().getTypeClass())
+
+ {
+ case ::com::sun::star::uno::TypeClass_DOUBLE:
+ {
+ double d = 0.0;
+ rValue >>= d;
+ pField->SetMaxValue(d);
+ }
+ break;
+ default:
+ if (rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID)
+
+ {
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+ pField->ClearMaxValue();
+ break;
+ }
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXFormattedField::GetMaxValue()
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField || !pField->HasMaxValue())
+ return ::com::sun::star::uno::Any();
+
+ ::com::sun::star::uno::Any aReturn;
+ aReturn <<= pField->GetMaxValue();
+ return aReturn;
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::SetDefaultValue(const ::com::sun::star::uno::Any& rValue)
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField)
+ return;
+
+ ::com::sun::star::uno::Any aConverted = convertEffectiveValue(rValue);
+
+ switch (aConverted.getValueType().getTypeClass())
+
+ {
+ case ::com::sun::star::uno::TypeClass_DOUBLE:
+ {
+ double d = 0.0;
+ aConverted >>= d;
+ pField->SetDefaultValue(d);
+ }
+ break;
+ case ::com::sun::star::uno::TypeClass_STRING:
+ {
+ ::rtl::OUString aStr;
+ aConverted >>= aStr;
+ pField->SetDefaultText( aStr );
+ }
+ break;
+ default:
+ pField->EnableEmptyField(sal_True);
+ // nur noch void erlaubt
+ break;
+ }
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXFormattedField::GetDefaultValue()
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField || pField->IsEmptyFieldEnabled())
+ return ::com::sun::star::uno::Any();
+
+ ::com::sun::star::uno::Any aReturn;
+ if (pField->TreatingAsNumber())
+ aReturn <<= pField->GetDefaultValue();
+ else
+ aReturn <<= ::rtl::OUString( pField->GetDefaultText() );
+ return aReturn;
+}
+
+// --------------------------------------------------------------------------------------
+sal_Bool SVTXFormattedField::GetTreatAsNumber()
+{
+ FormattedField* pField = GetFormattedField();
+ if (pField)
+ return pField->TreatingAsNumber();
+
+ return sal_True;
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::SetTreatAsNumber(sal_Bool bSet)
+{
+ FormattedField* pField = GetFormattedField();
+ if (pField)
+ pField->TreatAsNumber(bSet);
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXFormattedField::GetValue()
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField)
+ return ::com::sun::star::uno::Any();
+
+ ::com::sun::star::uno::Any aReturn;
+ if (!pField->TreatingAsNumber())
+ {
+ ::rtl::OUString sText = pField->GetTextValue();
+ aReturn <<= sText;
+ }
+ else
+ {
+ if (pField->GetText().Len()) // empty wird erst mal standardmaessig als void nach draussen gereicht
+ aReturn <<= pField->GetValue();
+ }
+
+ return aReturn;
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::SetValue(const ::com::sun::star::uno::Any& rValue)
+{
+ FormattedField* pField = GetFormattedField();
+ if (!pField)
+ return;
+
+ if (!rValue.hasValue())
+ {
+ pField->SetText(String());
+ }
+ else
+ {
+ if (rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_DOUBLE )
+ {
+ double d = 0.0;
+ rValue >>= d;
+ pField->SetValue(d);
+ }
+ else
+ {
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_STRING, "SVTXFormattedField::SetValue : invalid argument !");
+
+ ::rtl::OUString sText;
+ rValue >>= sText;
+ String aStr( sText );
+ if (!pField->TreatingAsNumber())
+ pField->SetTextFormatted(aStr);
+ else
+ pField->SetTextValue(aStr);
+ }
+ }
+// NotifyTextListeners();
+}
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > SVTXFormattedField::getFormatsSupplier(void) const
+{
+ return ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > ((::com::sun::star::util::XNumberFormatsSupplier*)m_pCurrentSupplier);
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::setFormatsSupplier(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xSupplier)
+{
+ FormattedField* pField = GetFormattedField();
+
+ SvNumberFormatsSupplierObj* pNew = NULL;
+ if (!xSupplier.is())
+ {
+ if (pField)
+ {
+ pNew = new SvNumberFormatsSupplierObj(pField->StandardFormatter());
+ bIsStandardSupplier = sal_True;
+ }
+ }
+ else
+ {
+ pNew = SvNumberFormatsSupplierObj::getImplementation(xSupplier);
+ bIsStandardSupplier = sal_False;
+ }
+
+ if (!pNew)
+ return; // TODO : wie das behandeln ?
+
+ if (m_pCurrentSupplier)
+ m_pCurrentSupplier->release();
+ m_pCurrentSupplier = pNew;
+ m_pCurrentSupplier->acquire();
+ if (pField)
+ {
+ // den aktuellen Value mit hinueberretten
+ ::com::sun::star::uno::Any aCurrent = GetValue();
+ pField->SetFormatter(m_pCurrentSupplier->GetNumberFormatter(), sal_False);
+ if (nKeyToSetDelayed != -1)
+ {
+ pField->SetFormatKey(nKeyToSetDelayed);
+ nKeyToSetDelayed = -1;
+ }
+ SetValue(aCurrent);
+ NotifyTextListeners();
+ }
+}
+
+// --------------------------------------------------------------------------------------
+sal_Int32 SVTXFormattedField::getFormatKey(void) const
+{
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetFormatKey() : 0;
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::setFormatKey(sal_Int32 nKey)
+{
+ FormattedField* pField = GetFormattedField();
+ if (pField)
+ {
+ if (pField->GetFormatter())
+ pField->SetFormatKey(nKey);
+ else
+ { // Wahrscheinlich bin ich gerade in einem Block, in dem erst der Key und dann der Formatter gesetzt
+ // wird, das passiert initial mit ziemlicher Sicherheit, da die Properties in alphabetischer Reihenfolge
+ // gesetzt werden, und der FormatsSupplier nun mal vor dem FormatKey kommt
+ nKeyToSetDelayed = nKey;
+ }
+ NotifyTextListeners();
+ }
+}
+
+// --------------------------------------------------------------------------------------
+void SVTXFormattedField::NotifyTextListeners()
+{
+ if ( GetTextListeners().getLength() )
+ {
+ ::com::sun::star::awt::TextEvent aEvent;
+ aEvent.Source = (::cppu::OWeakObject*)this;
+ GetTextListeners().textChanged( aEvent );
+ }
+}
+
+void SVTXFormattedField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ // FIXME: elide duplication ?
+ BASEPROPERTY_EFFECTIVE_MIN,
+ BASEPROPERTY_VALUEMIN_DOUBLE,
+ BASEPROPERTY_EFFECTIVE_MAX,
+ BASEPROPERTY_VALUEMAX_DOUBLE,
+ BASEPROPERTY_EFFECTIVE_DEFAULT,
+ BASEPROPERTY_TREATASNUMBER,
+ BASEPROPERTY_EFFECTIVE_VALUE,
+ BASEPROPERTY_VALUE_DOUBLE,
+ BASEPROPERTY_VALUESTEP_DOUBLE,
+ BASEPROPERTY_DECIMALACCURACY,
+ BASEPROPERTY_FORMATSSUPPLIER,
+ BASEPROPERTY_NUMSHOWTHOUSANDSEP,
+ BASEPROPERTY_FORMATKEY,
+ BASEPROPERTY_TREATASNUMBER,
+ BASEPROPERTY_ENFORCE_FORMAT,
+ 0);
+ VCLXWindow::ImplGetPropertyIds( rIds, true );
+ VCLXSpinField::ImplGetPropertyIds( rIds );
+}
+
+
+// ----------------------------------------------------
+// class SVTXRoadmap
+// ----------------------------------------------------
+
+using namespace svt;
+
+// --------------------------------------------------------------------------------------
+SVTXRoadmap::SVTXRoadmap() : maItemListeners( *this )
+{
+}
+
+// --------------------------------------------------------------------------------------
+SVTXRoadmap::~SVTXRoadmap()
+{
+}
+
+void SVTXRoadmap::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+{
+ switch ( rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_ROADMAP_ITEMSELECTED:
+ {
+ ::vos::OGuard aGuard( GetMutex() );
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ sal_Int16 CurItemID = pField->GetCurrentRoadmapItemID();
+ ::com::sun::star::awt::ItemEvent aEvent;
+ aEvent.Selected = CurItemID;
+ aEvent.Highlighted = CurItemID;
+ aEvent.ItemId = CurItemID;
+ maItemListeners.itemStateChanged( aEvent );
+ }
+ }
+ break;
+ default:
+ SVTXRoadmap_Base::ProcessWindowEvent( rVclWindowEvent );
+ break;
+ }
+}
+
+
+void SVTXRoadmap::propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRoadmapItem;
+ xRoadmapItem = evt.Source;
+ sal_Int32 nID = 0;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropertySet( xRoadmapItem, ::com::sun::star::uno::UNO_QUERY );
+ ::com::sun::star::uno::Any aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "ID" ));
+ aValue >>= nID;
+
+ ::com::sun::star::uno::Any rVal = evt.NewValue;
+ evt.NewValue >>= rVal;
+ ::rtl::OUString sPropertyName = evt.PropertyName;
+ if ( sPropertyName.equals(::rtl::OUString::createFromAscii( "Enabled" ) ) )
+ {
+ sal_Bool bEnable = false;
+ evt.NewValue >>= bEnable;
+ pField->EnableRoadmapItem( (RoadmapTypes::ItemId)nID , bEnable );
+ }
+ else if ( sPropertyName.equals(::rtl::OUString::createFromAscii( "Label" ) ) )
+ {
+ ::rtl::OUString sLabel;
+ evt.NewValue >>= sLabel;
+ pField->ChangeRoadmapItemLabel( (RoadmapTypes::ItemId)nID , sLabel );
+ }
+ else if ( sPropertyName.equals(::rtl::OUString::createFromAscii( "ID" ) ) )
+ {
+ sal_Int32 nNewID = 0;
+ evt.NewValue >>= nNewID;
+ evt.OldValue >>= nID;
+ pField->ChangeRoadmapItemID( (RoadmapTypes::ItemId)nID, (RoadmapTypes::ItemId)nNewID );
+ }
+ // else
+ // Todo: handle Interactive appropriately
+ }
+}
+
+
+void SVTXRoadmap::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException)
+{
+ maItemListeners.addInterface( l );
+}
+
+void SVTXRoadmap::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException)
+{
+ maItemListeners.removeInterface( l );
+}
+
+RMItemData SVTXRoadmap::GetRMItemData( const ::com::sun::star::container::ContainerEvent& _rEvent )
+{
+ RMItemData aCurRMItemData;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRoadmapItem;
+ _rEvent.Element >>= xRoadmapItem;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropertySet( xRoadmapItem, ::com::sun::star::uno::UNO_QUERY );
+ if ( xPropertySet.is() )
+ {
+ ::com::sun::star::uno::Any aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "Label" ));
+ aValue >>= aCurRMItemData.Label;
+ aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "ID" ));
+ aValue >>= aCurRMItemData.n_ID;
+ aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "Enabled" ));
+ aValue >>= aCurRMItemData.b_Enabled;
+ }
+ return aCurRMItemData;;
+}
+
+void SVTXRoadmap::elementInserted( const ::com::sun::star::container::ContainerEvent& _rEvent )throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ RMItemData CurItemData = GetRMItemData( _rEvent );
+ sal_Int32 InsertIndex = 0;
+ _rEvent.Accessor >>= InsertIndex;
+ pField->InsertRoadmapItem( InsertIndex, CurItemData.Label, (RoadmapTypes::ItemId)CurItemData.n_ID, CurItemData.b_Enabled );
+ }
+}
+
+void SVTXRoadmap::elementRemoved( const ::com::sun::star::container::ContainerEvent& _rEvent )throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ sal_Int32 DelIndex = 0;
+ _rEvent.Accessor >>= DelIndex;
+ pField->DeleteRoadmapItem(DelIndex);
+// pField->GetCurrentRoadmapItem()
+// setProperty(::rtl::OUString.createFromAscii( "CurrentItem" )aAny,
+ }
+}
+
+void SVTXRoadmap::elementReplaced( const ::com::sun::star::container::ContainerEvent& _rEvent )throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ RMItemData CurItemData = GetRMItemData( _rEvent );
+ sal_Int32 ReplaceIndex = 0;
+ _rEvent.Accessor >>= ReplaceIndex;
+ pField->ReplaceRoadmapItem( ReplaceIndex, CurItemData.Label, (RoadmapTypes::ItemId)CurItemData.n_ID, CurItemData.b_Enabled );
+ }
+}
+
+
+
+// --------------------------------------------------------------------------------------
+void SVTXRoadmap::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch (nPropType)
+ {
+ case BASEPROPERTY_COMPLETE:
+ {
+ sal_Bool b = false;
+ Value >>= b;
+ pField->SetRoadmapComplete( b);
+ }
+ break;
+
+ case BASEPROPERTY_ACTIVATED:
+ {
+ sal_Bool b = false;
+ Value >>= b;
+ pField->SetRoadmapInteractive( b);
+ }
+ break;
+
+ case BASEPROPERTY_CURRENTITEMID:
+ {
+ sal_Int32 nId = 0;
+ Value >>= nId;
+ pField->SelectRoadmapItemByID( (RoadmapTypes::ItemId)nId );
+ }
+ break;
+
+ case BASEPROPERTY_TEXT:
+ {
+ ::rtl::OUString aStr;
+ Value >>= aStr;
+ pField->SetText( aStr );
+ pField->Invalidate();
+ }
+ break;
+
+ default:
+ SVTXRoadmap_Base::setProperty( PropertyName, Value );
+ break;
+ }
+
+ }
+ else
+ SVTXRoadmap_Base::setProperty( PropertyName, Value );
+}
+
+
+// --------------------------------------------------------------------------------------
+::com::sun::star::uno::Any SVTXRoadmap::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::uno::Any aReturn;
+
+ ::svt::ORoadmap* pField = GetRoadmap();
+ if ( pField )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch (nPropType)
+ {
+ case BASEPROPERTY_COMPLETE:
+ aReturn <<= pField->IsRoadmapComplete();
+ break;
+ case BASEPROPERTY_ACTIVATED:
+ aReturn <<= pField->IsRoadmapInteractive();
+ break;
+ case BASEPROPERTY_CURRENTITEMID:
+ aReturn <<= pField->GetCurrentRoadmapItemID();
+ break;
+ default:
+ aReturn = SVTXRoadmap_Base::getProperty(PropertyName);
+ break;
+ }
+ }
+ return aReturn;
+}
+
+void SVTXRoadmap::ImplSetNewImage()
+{
+ OSL_PRECOND( GetWindow(), "SVTXRoadmap::ImplSetNewImage: window is required to be not-NULL!" );
+ ::svt::ORoadmap* pButton = static_cast< ::svt::ORoadmap* >( GetWindow() );
+ pButton->SetRoadmapBitmap( GetBitmap() );
+}
+
+void SVTXRoadmap::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ BASEPROPERTY_COMPLETE,
+ BASEPROPERTY_ACTIVATED,
+ BASEPROPERTY_CURRENTITEMID,
+ BASEPROPERTY_TEXT,
+ 0);
+ VCLXWindow::ImplGetPropertyIds( rIds, true );
+ VCLXGraphicControl::ImplGetPropertyIds( rIds );
+}
+
+// ----------------------------------------------------
+// class SVTXNumericField
+// ----------------------------------------------------
+SVTXNumericField::SVTXNumericField()
+{
+}
+
+SVTXNumericField::~SVTXNumericField()
+{
+}
+
+::com::sun::star::uno::Any SVTXNumericField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::awt::XNumericField*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
+ return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType ));
+}
+
+// ::com::sun::star::lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( SVTXNumericField )
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XNumericField>* ) NULL ),
+ SVTXFormattedField::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+
+void SVTXNumericField::setValue( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetValue( Value );
+}
+
+double SVTXNumericField::getValue() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetValue() : 0;
+}
+
+void SVTXNumericField::setMin( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetMinValue( Value );
+}
+
+double SVTXNumericField::getMin() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetMinValue() : 0;
+}
+
+void SVTXNumericField::setMax( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetMaxValue( Value );
+}
+
+double SVTXNumericField::getMax() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetMaxValue() : 0;
+}
+
+void SVTXNumericField::setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetSpinFirst( Value );
+}
+
+double SVTXNumericField::getFirst() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetSpinFirst() : 0;
+}
+
+void SVTXNumericField::setLast( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetSpinLast( Value );
+}
+
+double SVTXNumericField::getLast() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetSpinLast() : 0;
+}
+
+void SVTXNumericField::setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetSpinSize( Value );
+}
+
+double SVTXNumericField::getSpinSize() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetSpinSize() : 0;
+}
+
+void SVTXNumericField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetDecimalDigits( Value );
+}
+
+sal_Int16 SVTXNumericField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetDecimalDigits() : 0;
+}
+
+void SVTXNumericField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetStrictFormat( bStrict );
+}
+
+sal_Bool SVTXNumericField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->IsStrictFormat() : sal_False;
+}
+
+void SVTXNumericField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ SVTXFormattedField::ImplGetPropertyIds( rIds );
+}
+
+// ----------------------------------------------------
+// class SVTXCurrencyField
+// ----------------------------------------------------
+SVTXCurrencyField::SVTXCurrencyField()
+{
+}
+
+SVTXCurrencyField::~SVTXCurrencyField()
+{
+}
+
+::com::sun::star::uno::Any SVTXCurrencyField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::awt::XCurrencyField*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
+ return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType ));
+}
+
+// ::com::sun::star::lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( SVTXCurrencyField )
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XCurrencyField>* ) NULL ),
+ SVTXFormattedField::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+void SVTXCurrencyField::setValue( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetValue( Value );
+}
+
+double SVTXCurrencyField::getValue() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetValue() : 0;
+}
+
+void SVTXCurrencyField::setMin( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetMinValue( Value );
+}
+
+double SVTXCurrencyField::getMin() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetMinValue() : 0;
+}
+
+void SVTXCurrencyField::setMax( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetMaxValue( Value );
+}
+
+double SVTXCurrencyField::getMax() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetMaxValue() : 0;
+}
+
+void SVTXCurrencyField::setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetSpinFirst( Value );
+}
+
+double SVTXCurrencyField::getFirst() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetSpinFirst() : 0;
+}
+
+void SVTXCurrencyField::setLast( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetSpinLast( Value );
+}
+
+double SVTXCurrencyField::getLast() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetSpinLast() : 0;
+}
+
+void SVTXCurrencyField::setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetSpinSize( Value );
+}
+
+double SVTXCurrencyField::getSpinSize() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetSpinSize() : 0;
+}
+
+void SVTXCurrencyField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetDecimalDigits( Value );
+}
+
+sal_Int16 SVTXCurrencyField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->GetDecimalDigits() : 0;
+}
+
+void SVTXCurrencyField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ if ( pField )
+ pField->SetStrictFormat( bStrict );
+}
+
+sal_Bool SVTXCurrencyField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ FormattedField* pField = GetFormattedField();
+ return pField ? pField->IsStrictFormat() : sal_False;
+}
+
+void SVTXCurrencyField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::uno::Any aReturn;
+
+ DoubleCurrencyField* pField = (DoubleCurrencyField*)GetFormattedField();
+ if ( pField )
+ {
+#ifdef DBG_UTIL
+ String sAssertion( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "SVTXCurrencyField::setProperty(" ) ) );
+ sAssertion += String( PropertyName );
+ sAssertion.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ") : invalid value !" ) );
+#endif
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch (nPropType)
+ {
+ case BASEPROPERTY_CURRENCYSYMBOL:
+ {
+ ::rtl::OUString aStr;
+ Value >>= aStr;
+ pField->setCurrencySymbol( aStr );
+ }
+ break;
+ case BASEPROPERTY_CURSYM_POSITION:
+ {
+ sal_Bool b = false;
+ Value >>= b;
+ pField->setPrependCurrSym(b);
+ }
+ break;
+
+ default:
+ SVTXFormattedField::setProperty(PropertyName, Value);
+ }
+ }
+ else
+ SVTXFormattedField::setProperty(PropertyName, Value);
+}
+
+::com::sun::star::uno::Any SVTXCurrencyField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::uno::Any aReturn;
+
+ DoubleCurrencyField* pField = (DoubleCurrencyField*)GetFormattedField();
+ if ( pField )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch (nPropType)
+ {
+ case BASEPROPERTY_CURRENCYSYMBOL:
+ {
+ aReturn <<= ::rtl::OUString( pField->getCurrencySymbol() );
+ }
+ break;
+ case BASEPROPERTY_CURSYM_POSITION:
+ {
+ aReturn <<= pField->getPrependCurrSym();
+ }
+ break;
+ default:
+ return SVTXFormattedField::getProperty(PropertyName);
+ }
+ }
+ return SVTXFormattedField::getProperty(PropertyName);
+}
+
+void SVTXCurrencyField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ BASEPROPERTY_CURRENCYSYMBOL,
+ BASEPROPERTY_CURSYM_POSITION,
+ 0);
+ SVTXFormattedField::ImplGetPropertyIds( rIds );
+}
+
+
+// ----------------------------------------------------
+// class VCLXProgressBar
+// ----------------------------------------------------
+
+VCLXProgressBar::VCLXProgressBar()
+ :m_nValue(0)
+ ,m_nValueMin(0)
+ ,m_nValueMax(100)
+{
+}
+
+VCLXProgressBar::~VCLXProgressBar()
+{
+}
+
+void VCLXProgressBar::ImplUpdateValue()
+{
+ ProgressBar* pProgressBar = (ProgressBar*) GetWindow();
+ if ( pProgressBar )
+ {
+ sal_Int32 nVal;
+ sal_Int32 nValMin;
+ sal_Int32 nValMax;
+
+ // check min and max
+ if (m_nValueMin < m_nValueMax)
+ {
+ nValMin = m_nValueMin;
+ nValMax = m_nValueMax;
+ }
+ else
+ {
+ nValMin = m_nValueMax;
+ nValMax = m_nValueMin;
+ }
+
+ // check value
+ if (m_nValue < nValMin)
+ {
+ nVal = nValMin;
+ }
+ else if (m_nValue > nValMax)
+ {
+ nVal = nValMax;
+ }
+ else
+ {
+ nVal = m_nValue;
+ }
+
+ // calculate percent
+ sal_Int32 nPercent;
+ if (nValMin != nValMax)
+ {
+ nPercent = 100 * (nVal - nValMin) / (nValMax - nValMin);
+ }
+ else
+ {
+ nPercent = 0;
+ }
+
+ // set progressbar value
+ pProgressBar->SetValue( (USHORT) nPercent );
+ }
+}
+
+// ::com::sun::star::uno::XInterface
+::com::sun::star::uno::Any VCLXProgressBar::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::awt::XProgressBar*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
+ return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
+}
+
+// ::com::sun::star::lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( VCLXProgressBar )
+ getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XProgressBar>* ) NULL ),
+ VCLXWindow::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+// ::com::sun::star::awt::XProgressBar
+void VCLXProgressBar::setForegroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ Window* pWindow = GetWindow();
+ if ( pWindow )
+ {
+ Color aColor( nColor );
+ pWindow->SetControlForeground( aColor );
+ }
+}
+
+void VCLXProgressBar::setBackgroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ Window* pWindow = GetWindow();
+ if ( pWindow )
+ {
+ Color aColor( nColor );
+ pWindow->SetBackground( aColor );
+ pWindow->SetControlBackground( aColor );
+ pWindow->Invalidate();
+ }
+}
+
+void VCLXProgressBar::setValue( sal_Int32 nValue ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ m_nValue = nValue;
+ ImplUpdateValue();
+}
+
+void VCLXProgressBar::setRange( sal_Int32 nMin, sal_Int32 nMax ) throw(::com::sun::star::uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ if ( nMin < nMax )
+ {
+ // take correct min and max
+ m_nValueMin = nMin;
+ m_nValueMax = nMax;
+ }
+ else
+ {
+ // change min and max
+ m_nValueMin = nMax;
+ m_nValueMax = nMin;
+ }
+
+ ImplUpdateValue();
+}
+
+sal_Int32 VCLXProgressBar::getValue() throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ return m_nValue;
+}
+
+// ::com::sun::star::awt::VclWindowPeer
+void VCLXProgressBar::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ProgressBar* pProgressBar = (ProgressBar*)GetWindow();
+ if ( pProgressBar )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch ( nPropType )
+ {
+ case BASEPROPERTY_PROGRESSVALUE:
+ {
+ if ( Value >>= m_nValue )
+ ImplUpdateValue();
+ }
+ break;
+ case BASEPROPERTY_PROGRESSVALUE_MIN:
+ {
+ if ( Value >>= m_nValueMin )
+ ImplUpdateValue();
+ }
+ break;
+ case BASEPROPERTY_PROGRESSVALUE_MAX:
+ {
+ if ( Value >>= m_nValueMax )
+ ImplUpdateValue();
+ }
+ break;
+ case BASEPROPERTY_FILLCOLOR:
+ {
+ Window* pWindow = GetWindow();
+ if ( pWindow )
+ {
+ sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;
+
+ if ( bVoid )
+ {
+ pWindow->SetControlForeground();
+ }
+ else
+ {
+ sal_Int32 nColor = 0;
+ if ( Value >>= nColor )
+ {
+ Color aColor( nColor );
+ pWindow->SetControlForeground( aColor );
+ }
+ }
+ }
+ }
+ break;
+ default:
+ VCLXWindow::setProperty( PropertyName, Value );
+ break;
+ }
+ }
+}
+
+::com::sun::star::uno::Any VCLXProgressBar::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ ::com::sun::star::uno::Any aProp;
+ ProgressBar* pProgressBar = (ProgressBar*)GetWindow();
+ if ( pProgressBar )
+ {
+ sal_uInt16 nPropType = GetPropertyId( PropertyName );
+ switch ( nPropType )
+ {
+ case BASEPROPERTY_PROGRESSVALUE:
+ {
+ aProp <<= m_nValue;
+ }
+ break;
+ case BASEPROPERTY_PROGRESSVALUE_MIN:
+ {
+ aProp <<= m_nValueMin;
+ }
+ break;
+ case BASEPROPERTY_PROGRESSVALUE_MAX:
+ {
+ aProp <<= m_nValueMax;
+ }
+ break;
+ default:
+ aProp <<= VCLXWindow::getProperty( PropertyName );
+ break;
+ }
+ }
+ return aProp;
+}
+
+void VCLXProgressBar::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ BASEPROPERTY_PROGRESSVALUE,
+ BASEPROPERTY_PROGRESSVALUE_MIN,
+ BASEPROPERTY_PROGRESSVALUE_MAX,
+ BASEPROPERTY_FILLCOLOR,
+ 0);
+ VCLXWindow::ImplGetPropertyIds( rIds, true );
+}
+
+
+// ----------------------------------------------------
+// class SVTXDateField
+// ----------------------------------------------------
+SVTXDateField::SVTXDateField()
+ :VCLXDateField()
+{
+}
+
+SVTXDateField::~SVTXDateField()
+{
+}
+
+void SAL_CALL SVTXDateField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException)
+{
+ VCLXDateField::setProperty( PropertyName, Value );
+
+ // some properties need to be forwarded to the sub edit, too
+ Edit* pSubEdit = GetWindow() ? static_cast< Edit* >( GetWindow() )->GetSubEdit() : NULL;
+ if ( !pSubEdit )
+ return;
+
+ switch ( GetPropertyId( PropertyName ) )
+ {
+ case BASEPROPERTY_TEXTLINECOLOR:
+ if ( !Value.hasValue() )
+ pSubEdit->SetTextLineColor();
+ else
+ {
+ sal_Int32 nColor = 0;
+ if ( Value >>= nColor )
+ pSubEdit->SetTextLineColor( Color( nColor ) );
+ }
+ break;
+ }
+}
+
+void SVTXDateField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
+{
+ PushPropertyIds( rIds,
+ BASEPROPERTY_TEXTLINECOLOR,
+ 0);
+ VCLXDateField::ImplGetPropertyIds( rIds );
+}
diff --git a/svtools/source/uno/unoimap.cxx b/svtools/source/uno/unoimap.cxx
new file mode 100644
index 000000000000..88f22f0c8402
--- /dev/null
+++ b/svtools/source/uno/unoimap.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_svtools.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+
+#ifndef _COMPHELPER_SERVICEHELPER_HXX_
+#include <comphelper/servicehelper.hxx>
+#endif
+#include <comphelper/propertysethelper.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <cppuhelper/weakagg.hxx>
+
+#include <cppuhelper/implbase3.hxx>
+
+#include <list>
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include "unoevent.hxx"
+#include "unoimap.hxx"
+#include <svtools/imap.hxx>
+#include <svtools/imapcirc.hxx>
+#include <svtools/imaprect.hxx>
+#include <svtools/imappoly.hxx>
+
+#ifndef SEQTYPE
+ #if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)
+ #define SEQTYPE(x) (new ::com::sun::star::uno::Type( x ))
+ #else
+ #define SEQTYPE(x) &(x)
+ #endif
+#endif
+
+#define MAP_LEN(x) x, sizeof(x)-1
+
+
+using namespace comphelper;
+using namespace cppu;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::document;
+using namespace com::sun::star::drawing;
+
+const sal_Int32 HANDLE_URL = 1;
+const sal_Int32 HANDLE_DESCRIPTION = 2;
+const sal_Int32 HANDLE_TARGET = 3;
+const sal_Int32 HANDLE_NAME = 4;
+const sal_Int32 HANDLE_ISACTIVE = 5;
+const sal_Int32 HANDLE_POLYGON = 6;
+const sal_Int32 HANDLE_CENTER = 7;
+const sal_Int32 HANDLE_RADIUS = 8;
+const sal_Int32 HANDLE_BOUNDARY = 9;
+const sal_Int32 HANDLE_TITLE = 10;
+
+class SvUnoImageMapObject : public OWeakAggObject,
+ public XEventsSupplier,
+ public XServiceInfo,
+ public PropertySetHelper,
+ public XTypeProvider,
+ public XUnoTunnel
+{
+public:
+ SvUnoImageMapObject( UINT16 nType, const SvEventDescription* pSupportedMacroItems );
+ SvUnoImageMapObject( const IMapObject& rMapObject, const SvEventDescription* pSupportedMacroItems );
+ virtual ~SvUnoImageMapObject() throw();
+
+ UNO3_GETIMPLEMENTATION_DECL( SvUnoImageMapObject )
+
+ IMapObject* createIMapObject() const;
+
+ SvMacroTableEventDescriptor* mpEvents;
+
+ // overiden helpers from PropertySetHelper
+ virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException );
+ virtual void _getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValue ) throw(UnknownPropertyException, WrappedTargetException );
+
+ // XInterface
+ virtual Any SAL_CALL queryAggregation( const Type & rType ) throw(RuntimeException);
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw(RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes( ) throw(RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw(RuntimeException);
+
+ // XEventsSupplier
+ virtual Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents( ) throw(RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw( RuntimeException );
+
+private:
+ static PropertySetInfo* createPropertySetInfo( UINT16 nType );
+
+
+ UINT16 mnType;
+
+ ::rtl::OUString maURL;
+ ::rtl::OUString maAltText;
+ ::rtl::OUString maDesc;
+ ::rtl::OUString maTarget;
+ ::rtl::OUString maName;
+ sal_Bool mbIsActive;
+ awt::Rectangle maBoundary;
+ awt::Point maCenter;
+ sal_Int32 mnRadius;
+ PointSequence maPolygon;
+};
+
+UNO3_GETIMPLEMENTATION_IMPL( SvUnoImageMapObject );
+
+PropertySetInfo* SvUnoImageMapObject::createPropertySetInfo( UINT16 nType )
+{
+ switch( nType )
+ {
+ case IMAP_OBJ_POLYGON:
+ {
+ static PropertyMapEntry aPolygonObj_Impl[] =
+ {
+ { MAP_LEN( "URL" ), HANDLE_URL, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Title" ), HANDLE_TITLE, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Target" ), HANDLE_TARGET, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Name" ), HANDLE_NAME, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "IsActive" ), HANDLE_ISACTIVE, &::getBooleanCppuType(), 0, 0 },
+ { MAP_LEN( "Polygon" ), HANDLE_POLYGON, SEQTYPE(::getCppuType((const PointSequence*)0)), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+
+ return new PropertySetInfo( aPolygonObj_Impl );
+ }
+ case IMAP_OBJ_CIRCLE:
+ {
+ static PropertyMapEntry aCircleObj_Impl[] =
+ {
+ { MAP_LEN( "URL" ), HANDLE_URL, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Title" ), HANDLE_TITLE, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Target" ), HANDLE_TARGET, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Name" ), HANDLE_NAME, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "IsActive" ), HANDLE_ISACTIVE, &::getBooleanCppuType(), 0, 0 },
+ { MAP_LEN( "Center" ), HANDLE_CENTER, &::getCppuType((const awt::Point*)0), 0, 0 },
+ { MAP_LEN( "Radius" ), HANDLE_RADIUS, &::getCppuType((const sal_Int32*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+
+ return new PropertySetInfo( aCircleObj_Impl );
+ }
+ case IMAP_OBJ_RECTANGLE:
+ default:
+ {
+ static PropertyMapEntry aRectangleObj_Impl[] =
+ {
+ { MAP_LEN( "URL" ), HANDLE_URL, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Title" ), HANDLE_TITLE, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Target" ), HANDLE_TARGET, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "Name" ), HANDLE_NAME, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ { MAP_LEN( "IsActive" ), HANDLE_ISACTIVE, &::getBooleanCppuType(), 0, 0 },
+ { MAP_LEN( "Boundary" ), HANDLE_BOUNDARY, &::getCppuType((const awt::Rectangle*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+
+ return new PropertySetInfo( aRectangleObj_Impl );
+ }
+ }
+}
+
+SvUnoImageMapObject::SvUnoImageMapObject( UINT16 nType, const SvEventDescription* pSupportedMacroItems )
+: PropertySetHelper( createPropertySetInfo( nType ) ),
+ mnType( nType )
+, mbIsActive( true )
+, mnRadius( 0 )
+{
+ mpEvents = new SvMacroTableEventDescriptor( pSupportedMacroItems );
+ mpEvents->acquire();
+}
+
+SvUnoImageMapObject::SvUnoImageMapObject( const IMapObject& rMapObject, const SvEventDescription* pSupportedMacroItems )
+: PropertySetHelper( createPropertySetInfo( rMapObject.GetType() ) ),
+ mnType( rMapObject.GetType() )
+, mbIsActive( true )
+, mnRadius( 0 )
+{
+ maURL = rMapObject.GetURL();
+ maAltText = rMapObject.GetAltText();
+ maDesc = rMapObject.GetDesc();
+ maTarget = rMapObject.GetTarget();
+ maName = rMapObject.GetName();
+ mbIsActive = rMapObject.IsActive();
+
+ switch( mnType )
+ {
+ case IMAP_OBJ_RECTANGLE:
+ {
+ const Rectangle aRect( ((IMapRectangleObject*)&rMapObject)->GetRectangle(sal_False) );
+ maBoundary.X = aRect.Left();
+ maBoundary.Y = aRect.Top();
+ maBoundary.Width = aRect.GetWidth();
+ maBoundary.Height = aRect.GetHeight();
+ }
+ break;
+ case IMAP_OBJ_CIRCLE:
+ {
+ mnRadius = (sal_Int32)((IMapCircleObject*)&rMapObject)->GetRadius(sal_False);
+ const Point aPoint( ((IMapCircleObject*)&rMapObject)->GetCenter(sal_False) );
+
+ maCenter.X = aPoint.X();
+ maCenter.Y = aPoint.Y();
+ }
+ break;
+ case IMAP_OBJ_POLYGON:
+ default:
+ {
+ const Polygon aPoly( ((IMapPolygonObject*)&rMapObject)->GetPolygon(sal_False) );
+
+ const USHORT nCount = aPoly.GetSize();
+ maPolygon.realloc( nCount );
+ awt::Point* pPoints = maPolygon.getArray();
+
+ for( USHORT nPoint = 0; nPoint < nCount; nPoint++ )
+ {
+ const Point& rPoint = aPoly.GetPoint( nPoint );
+ pPoints->X = rPoint.X();
+ pPoints->Y = rPoint.Y();
+
+ pPoints++;
+ }
+ }
+ }
+
+ mpEvents = new SvMacroTableEventDescriptor( rMapObject.GetMacroTable(), pSupportedMacroItems );
+ mpEvents->acquire();
+}
+
+SvUnoImageMapObject::~SvUnoImageMapObject() throw()
+{
+ mpEvents->release();
+}
+
+IMapObject* SvUnoImageMapObject::createIMapObject() const
+{
+ const String aURL( maURL );
+ const String aAltText( maAltText );
+ const String aDesc( maDesc );
+ const String aTarget( maTarget );
+ const String aName( maName );
+
+ IMapObject* pNewIMapObject;
+
+ switch( mnType )
+ {
+ case IMAP_OBJ_RECTANGLE:
+ {
+ const Rectangle aRect( maBoundary.X, maBoundary.Y, maBoundary.X + maBoundary.Width - 1, maBoundary.Y + maBoundary.Height - 1 );
+ pNewIMapObject = new IMapRectangleObject( aRect, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False );
+ }
+ break;
+
+ case IMAP_OBJ_CIRCLE:
+ {
+ const Point aCenter( maCenter.X, maCenter.Y );
+ pNewIMapObject = new IMapCircleObject( aCenter, mnRadius, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False );
+ }
+ break;
+
+ case IMAP_OBJ_POLYGON:
+ default:
+ {
+ const sal_uInt16 nCount = (sal_uInt16)maPolygon.getLength();
+
+ Polygon aPoly( nCount );
+ for( sal_uInt16 nPoint = 0; nPoint < nCount; nPoint++ )
+ {
+ Point aPoint( maPolygon[nPoint].X, maPolygon[nPoint].Y );
+ aPoly.SetPoint( aPoint, nPoint );
+ }
+
+ aPoly.Optimize( POLY_OPTIMIZE_CLOSE );
+ pNewIMapObject = new IMapPolygonObject( aPoly, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False );
+ }
+ break;
+ }
+
+ SvxMacroTableDtor aMacroTable;
+ mpEvents->copyMacrosIntoTable(aMacroTable);
+ pNewIMapObject->SetMacroTable( aMacroTable );
+
+ return pNewIMapObject;
+}
+
+// XInterface
+
+Any SAL_CALL SvUnoImageMapObject::queryInterface( const Type & rType )
+ throw( RuntimeException )
+{
+ return OWeakAggObject::queryInterface( rType );
+}
+
+Any SAL_CALL SvUnoImageMapObject::queryAggregation( const Type & rType )
+ throw(RuntimeException)
+{
+ Any aAny;
+
+ if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) )
+ aAny <<= Reference< XServiceInfo >(this);
+ else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) )
+ aAny <<= Reference< XTypeProvider >(this);
+ else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) )
+ aAny <<= Reference< XPropertySet >(this);
+ else if( rType == ::getCppuType((const Reference< XEventsSupplier >*)0) )
+ aAny <<= Reference< XEventsSupplier >(this);
+ else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) )
+ aAny <<= Reference< XMultiPropertySet >(this);
+ else if( rType == ::getCppuType((const Reference< XUnoTunnel >*)0) )
+ aAny <<= Reference< XUnoTunnel >(this);
+ else
+ aAny <<= OWeakAggObject::queryAggregation( rType );
+
+ return aAny;
+}
+
+void SAL_CALL SvUnoImageMapObject::acquire() throw()
+{
+ OWeakAggObject::acquire();
+}
+
+void SAL_CALL SvUnoImageMapObject::release() throw()
+{
+ OWeakAggObject::release();
+}
+
+uno::Sequence< uno::Type > SAL_CALL SvUnoImageMapObject::getTypes()
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< uno::Type > aTypes( 7 );
+ uno::Type* pTypes = aTypes.getArray();
+
+ *pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< XEventsSupplier>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0);
+ *pTypes++ = ::getCppuType((const uno::Reference< XUnoTunnel>*)0);
+
+ return aTypes;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvUnoImageMapObject::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XServiceInfo
+
+sal_Bool SAL_CALL SvUnoImageMapObject::supportsService( const ::rtl::OUString& ServiceName ) throw(RuntimeException)
+{
+ const Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
+ const ::rtl::OUString * pArray = aSNL.getConstArray();
+
+ const sal_Int32 nCount = aSNL.getLength();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SvUnoImageMapObject::getSupportedServiceNames()
+ throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapObject" ));
+ switch( mnType )
+ {
+ case IMAP_OBJ_POLYGON:
+ default:
+ aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapPolygonObject" ));
+ break;
+ case IMAP_OBJ_RECTANGLE:
+ aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapRectangleObject" ));
+ break;
+ case IMAP_OBJ_CIRCLE:
+ aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapCircleObject" ));
+ break;
+ }
+ return aSNS;
+}
+
+::rtl::OUString SAL_CALL SvUnoImageMapObject::getImplementationName() throw(RuntimeException)
+{
+ switch( mnType )
+ {
+ case IMAP_OBJ_POLYGON:
+ default:
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapPolygonObject") );
+ case IMAP_OBJ_CIRCLE:
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapCircleObject") );
+ case IMAP_OBJ_RECTANGLE:
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapRectangleObject") );
+ }
+}
+
+// overiden helpers from PropertySetHelper
+void SvUnoImageMapObject::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues )
+ throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException )
+{
+ sal_Bool bOk = sal_False;
+
+ while( *ppEntries )
+ {
+ switch( (*ppEntries)->mnHandle )
+ {
+ case HANDLE_URL:
+ bOk = *pValues >>= maURL;
+ break;
+ case HANDLE_TITLE:
+ bOk = *pValues >>= maAltText;
+ break;
+ case HANDLE_DESCRIPTION:
+ bOk = *pValues >>= maDesc;
+ break;
+ case HANDLE_TARGET:
+ bOk = *pValues >>= maTarget;
+ break;
+ case HANDLE_NAME:
+ bOk = *pValues >>= maName;
+ break;
+ case HANDLE_ISACTIVE:
+ bOk = *pValues >>= mbIsActive;
+ break;
+ case HANDLE_BOUNDARY:
+ bOk = *pValues >>= maBoundary;
+ break;
+ case HANDLE_CENTER:
+ bOk = *pValues >>= maCenter;
+ break;
+ case HANDLE_RADIUS:
+ bOk = *pValues >>= mnRadius;
+ break;
+ case HANDLE_POLYGON:
+ bOk = *pValues >>= maPolygon;
+ break;
+ default:
+ DBG_ERROR( "SvUnoImageMapObject::_setPropertyValues: unexpected property handle" );
+ break;
+ }
+
+ if( !bOk )
+ throw IllegalArgumentException();
+
+ ppEntries++;
+ pValues++;
+ }
+}
+
+void SvUnoImageMapObject::_getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValues )
+ throw(UnknownPropertyException, WrappedTargetException )
+{
+ while( *ppEntries )
+ {
+ switch( (*ppEntries)->mnHandle )
+ {
+ case HANDLE_URL:
+ *pValues <<= maURL;
+ break;
+ case HANDLE_TITLE:
+ *pValues <<= maAltText;
+ break;
+ case HANDLE_DESCRIPTION:
+ *pValues <<= maDesc;
+ break;
+ case HANDLE_TARGET:
+ *pValues <<= maTarget;
+ break;
+ case HANDLE_NAME:
+ *pValues <<= maName;
+ break;
+ case HANDLE_ISACTIVE:
+ *pValues <<= mbIsActive;
+ break;
+ case HANDLE_BOUNDARY:
+ *pValues <<= maBoundary;
+ break;
+ case HANDLE_CENTER:
+ *pValues <<= maCenter;
+ break;
+ case HANDLE_RADIUS:
+ *pValues <<= mnRadius;
+ break;
+ case HANDLE_POLYGON:
+ *pValues <<= maPolygon;
+ break;
+ default:
+ DBG_ERROR( "SvUnoImageMapObject::_getPropertyValues: unexpected property handle" );
+ break;
+ }
+
+ ppEntries++;
+ pValues++;
+ }
+}
+
+
+Reference< XNameReplace > SAL_CALL SvUnoImageMapObject::getEvents()
+ throw( RuntimeException )
+{
+ // try weak reference first
+ Reference< XNameReplace > xEvents( mpEvents );
+ return xEvents;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+class SvUnoImageMap : public WeakImplHelper3< XIndexContainer, XServiceInfo, XUnoTunnel >
+{
+public:
+ SvUnoImageMap( const SvEventDescription* pSupportedMacroItems );
+ SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems );
+ virtual ~SvUnoImageMap();
+
+ sal_Bool fillImageMap( ImageMap& rMap ) const;
+ SvUnoImageMapObject* getObject( const Any& aElement ) const throw( IllegalArgumentException );
+
+ UNO3_GETIMPLEMENTATION_DECL( SvUnoImageMap )
+
+ // XIndexContainer
+ virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element ) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // XIndexReplace
+ virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) throw( RuntimeException );
+ virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType( ) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasElements( ) throw( RuntimeException );
+
+ // XSerivceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw( RuntimeException );
+
+private:
+ ::rtl::OUString maName;
+
+ std::list< SvUnoImageMapObject* > maObjectList;
+};
+
+UNO3_GETIMPLEMENTATION_IMPL( SvUnoImageMap );
+
+SvUnoImageMap::SvUnoImageMap( const SvEventDescription* )
+{
+}
+
+SvUnoImageMap::SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems )
+{
+ maName = rMap.GetName();
+
+ const UINT16 nCount = rMap.GetIMapObjectCount();
+ for( UINT16 nPos = 0; nPos < nCount; nPos++ )
+ {
+ IMapObject* pMapObject = rMap.GetIMapObject( nPos );
+ SvUnoImageMapObject* pUnoObj = new SvUnoImageMapObject( *pMapObject, pSupportedMacroItems );
+ pUnoObj->acquire();
+ maObjectList.push_back( pUnoObj );
+ }
+}
+
+SvUnoImageMap::~SvUnoImageMap()
+{
+ std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
+ const std::list< SvUnoImageMapObject* >::iterator aEnd = maObjectList.end();
+ while( aIter != aEnd )
+ {
+ (*aIter++)->release();
+ }
+}
+
+SvUnoImageMapObject* SvUnoImageMap::getObject( const Any& aElement ) const
+ throw( IllegalArgumentException )
+{
+ Reference< XInterface > xObject;
+ aElement >>= xObject;
+
+ SvUnoImageMapObject* pObject = SvUnoImageMapObject::getImplementation( xObject );
+ if( NULL == pObject )
+ throw IllegalArgumentException();
+
+ return pObject;
+}
+
+// XIndexContainer
+void SAL_CALL SvUnoImageMap::insertByIndex( sal_Int32 Index, const Any& Element )
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ SvUnoImageMapObject* pObject = getObject( Element );
+ const sal_Int32 nCount = maObjectList.size();
+ if( NULL == pObject || Index > nCount )
+ throw IndexOutOfBoundsException();
+
+ pObject->acquire();
+
+ if( Index == nCount )
+ maObjectList.push_back( pObject );
+ else
+ {
+ std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
+ for( sal_Int32 n = 0; n < Index; n++ )
+ aIter++;
+
+ maObjectList.insert( aIter, pObject );
+ }
+}
+
+void SAL_CALL SvUnoImageMap::removeByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ const sal_Int32 nCount = maObjectList.size();
+ if( Index >= nCount )
+ throw IndexOutOfBoundsException();
+
+ if( nCount - 1 == Index )
+ {
+ maObjectList.back()->release();
+ maObjectList.pop_back();
+ }
+ else
+ {
+ std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
+ for( sal_Int32 n = 0; n < Index; n++ )
+ aIter++;
+
+ (*aIter)->release();
+ maObjectList.erase( aIter );
+ }
+}
+
+// XIndexReplace
+void SAL_CALL SvUnoImageMap::replaceByIndex( sal_Int32 Index, const Any& Element ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ SvUnoImageMapObject* pObject = getObject( Element );
+ const sal_Int32 nCount = maObjectList.size();
+ if( NULL == pObject || Index >= nCount )
+ throw IndexOutOfBoundsException();
+
+ std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
+ for( sal_Int32 n = 0; n < Index; n++ )
+ aIter++;
+
+ (*aIter)->release();
+ *aIter = pObject;
+ pObject->acquire();
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL SvUnoImageMap::getCount( ) throw(RuntimeException)
+{
+ return maObjectList.size();
+}
+
+Any SAL_CALL SvUnoImageMap::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ const sal_Int32 nCount = maObjectList.size();
+ if( Index >= nCount )
+ throw IndexOutOfBoundsException();
+
+ std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
+ for( sal_Int32 n = 0; n < Index; n++ )
+ aIter++;
+
+ Reference< XPropertySet > xObj( *aIter );
+ return makeAny( xObj );
+}
+
+// XElementAccess
+Type SAL_CALL SvUnoImageMap::getElementType( ) throw(RuntimeException)
+{
+ return ::getCppuType((const Reference< XPropertySet >*)0);
+}
+
+sal_Bool SAL_CALL SvUnoImageMap::hasElements( ) throw(RuntimeException)
+{
+ return maObjectList.size() != 0;
+}
+
+// XSerivceInfo
+::rtl::OUString SAL_CALL SvUnoImageMap::getImplementationName( )
+ throw(RuntimeException)
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.svt.SvUnoImageMap" ) );
+}
+
+sal_Bool SAL_CALL SvUnoImageMap::supportsService( const ::rtl::OUString& ServiceName )
+ throw(RuntimeException)
+{
+ const Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
+ const ::rtl::OUString * pArray = aSNL.getConstArray();
+
+ const sal_Int32 nCount = aSNL.getLength();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SvUnoImageMap::getSupportedServiceNames( )
+ throw(RuntimeException)
+{
+ const ::rtl::OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.image.ImageMap" ) );
+ return Sequence< ::rtl::OUString >( &aSN, 1 );
+}
+
+sal_Bool SvUnoImageMap::fillImageMap( ImageMap& rMap ) const
+{
+ rMap.ClearImageMap();
+
+ rMap.SetName( maName );
+
+ std::list< SvUnoImageMapObject* >::const_iterator aIter = maObjectList.begin();
+ const std::list< SvUnoImageMapObject* >::const_iterator aEnd = maObjectList.end();
+ while( aIter != aEnd )
+ {
+ IMapObject* pNewMapObject = (*aIter)->createIMapObject();
+ rMap.InsertIMapObject( *pNewMapObject );
+ delete pNewMapObject;
+
+ aIter++;
+ }
+
+ return sal_True;
+}
+
+// -------------------------------------------------------------------
+// factory helper methods
+// -------------------------------------------------------------------
+
+Reference< XInterface > SvUnoImageMapRectangleObject_createInstance( const SvEventDescription* pSupportedMacroItems )
+{
+ return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_RECTANGLE, pSupportedMacroItems );
+}
+
+Reference< XInterface > SvUnoImageMapCircleObject_createInstance( const SvEventDescription* pSupportedMacroItems )
+{
+ return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_CIRCLE, pSupportedMacroItems );
+}
+
+Reference< XInterface > SvUnoImageMapPolygonObject_createInstance( const SvEventDescription* pSupportedMacroItems )
+{
+ return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_POLYGON, pSupportedMacroItems );
+}
+
+Reference< XInterface > SvUnoImageMap_createInstance( const SvEventDescription* pSupportedMacroItems )
+{
+ return (XWeak*)new SvUnoImageMap( pSupportedMacroItems );
+}
+
+Reference< XInterface > SvUnoImageMap_createInstance( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems )
+{
+ return (XWeak*)new SvUnoImageMap( rMap, pSupportedMacroItems );
+}
+
+sal_Bool SvUnoImageMap_fillImageMap( Reference< XInterface > xImageMap, ImageMap& rMap )
+{
+ SvUnoImageMap* pUnoImageMap = SvUnoImageMap::getImplementation( xImageMap );
+ if( NULL == pUnoImageMap )
+ return sal_False;
+
+ return pUnoImageMap->fillImageMap( rMap );
+}
diff --git a/svtools/source/uno/unowizard.hxx b/svtools/source/uno/unowizard.hxx
new file mode 100644
index 000000000000..ceb8fac14eb6
--- /dev/null
+++ b/svtools/source/uno/unowizard.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 SVT_UNO_WIZARD_HXX
+#define SVT_UNO_WIZARD_HXX
+
+#include "svtools/genericunodialog.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/dialogs/XWizard.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ui/dialogs/XWizardController.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/componentcontext.hxx>
+
+//......................................................................................................................
+namespace svt { namespace uno
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= Wizard - declaration
+ //==================================================================================================================
+ typedef ::cppu::ImplInheritanceHelper1 < ::svt::OGenericUnoDialog
+ , ::com::sun::star::ui::dialogs::XWizard
+ > Wizard_Base;
+ class Wizard;
+ typedef ::comphelper::OPropertyArrayUsageHelper< Wizard > Wizard_PBase;
+ class Wizard : public Wizard_Base
+ , public Wizard_PBase
+ {
+ public:
+ Wizard( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& i_rContext );
+
+ // ::com::sun::star::lang::XServiceInfo - static version
+ static ::rtl::OUString SAL_CALL getImplementationName_static() throw(::com::sun::star::uno::RuntimeException);
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static() throw(::com::sun::star::uno::RuntimeException);
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& i_rContext );
+
+ protected:
+ // ::com::sun::star::lang::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);
+
+ // ::com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // ::com::sun::star::ui::dialogs::XWizard
+ virtual ::rtl::OUString SAL_CALL getHelpURL() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setHelpURL( const ::rtl::OUString& _helpurl ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL getDialogWindow() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage > SAL_CALL getCurrentPage( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL enableButton( ::sal_Int16 WizardButton, ::sal_Bool Enable ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDefaultButton( ::sal_Int16 WizardButton ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL travelNext( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL travelPrevious( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL enablePage( ::sal_Int16 PageID, ::sal_Bool Enable ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::util::InvalidStateException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTravelUI( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL advanceTo( ::sal_Int16 PageId ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL goBackTo( ::sal_Int16 PageId ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL activatePath( ::sal_Int16 PathIndex, ::sal_Bool Final ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::util::InvalidStateException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::ui::dialogs::XExecutableDialog
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL execute( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::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);
+
+ protected:
+ ~Wizard();
+
+ protected:
+ virtual Dialog* createDialog( Window* _pParent );
+ virtual void destroyDialog();
+
+ private:
+ ::comphelper::ComponentContext m_aContext;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int16 > > m_aWizardSteps;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController > m_xController;
+ ::rtl::OUString m_sHelpURL;
+ };
+
+//......................................................................................................................
+} } // namespace svt::uno
+//......................................................................................................................
+
+#endif // SVT_UNO_WIZARD_HXX
diff --git a/svtools/source/uno/wizard/makefile.mk b/svtools/source/uno/wizard/makefile.mk
new file mode 100644
index 000000000000..521496fc5d48
--- /dev/null
+++ b/svtools/source/uno/wizard/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=svtools
+TARGET=unowiz
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/unowizard.obj \
+ $(SLO)$/wizardshell.obj \
+ $(SLO)$/wizardpagecontroller.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/uno/wizard/unowizard.cxx b/svtools/source/uno/wizard/unowizard.cxx
new file mode 100644
index 000000000000..9440c0e69f26
--- /dev/null
+++ b/svtools/source/uno/wizard/unowizard.cxx
@@ -0,0 +1,452 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "../unowizard.hxx"
+#include "wizardshell.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
+#include <com/sun/star/ui/dialogs/XWizardController.hpp>
+#include <com/sun/star/ui/dialogs/WizardButton.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+#include <rtl/strbuf.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+//......................................................................................................................
+namespace svt { namespace uno
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ 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::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::lang::XServiceInfo;
+ using ::com::sun::star::ui::dialogs::XWizard;
+ using ::com::sun::star::lang::XInitialization;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::uno::XComponentContext;
+ using ::com::sun::star::beans::Property;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::ucb::AlreadyInitializedException;
+ using ::com::sun::star::ui::dialogs::XWizardController;
+ using ::com::sun::star::ui::dialogs::XWizardPage;
+ using ::com::sun::star::container::NoSuchElementException;
+ using ::com::sun::star::util::InvalidStateException;
+ using ::com::sun::star::awt::XWindow;
+ /** === end UNO using === **/
+ namespace WizardButton = ::com::sun::star::ui::dialogs::WizardButton;
+
+ //------------------------------------------------------------------------------------------------------------------
+ namespace
+ {
+ sal_uInt32 lcl_convertWizardButtonToWZB( const sal_Int16 i_nWizardButton )
+ {
+ switch ( i_nWizardButton )
+ {
+ case WizardButton::NONE: return WZB_NONE;
+ case WizardButton::NEXT: return WZB_NEXT;
+ case WizardButton::PREVIOUS: return WZB_PREVIOUS;
+ case WizardButton::FINISH: return WZB_FINISH;
+ case WizardButton::CANCEL: return WZB_CANCEL;
+ case WizardButton::HELP: return WZB_HELP;
+ }
+ OSL_ENSURE( false, "lcl_convertWizardButtonToWZB: invalid WizardButton constant!" );
+ return WZB_NONE;
+ }
+ }
+
+ //==================================================================================================================
+ //= Wizard - implementation
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ Wizard::Wizard( const Reference< XComponentContext >& _rxContext )
+ :Wizard_Base( _rxContext )
+ ,m_aContext( _rxContext )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ Wizard::~Wizard()
+ {
+ // we do this here cause the base class' call to destroyDialog won't reach us anymore : we're within an dtor,
+ // so this virtual-method-call the base class does does not work, we're already dead then ...
+ if ( m_pDialog )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pDialog )
+ destroyDialog();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL Wizard::Create( const Reference< XComponentContext >& _rxContext )
+ {
+ return *(new Wizard( _rxContext ) );
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ static void lcl_checkPaths( const Sequence< Sequence< sal_Int16 > >& i_rPaths, const Reference< XInterface >& i_rContext )
+ {
+ // need at least one path
+ if ( i_rPaths.getLength() == 0 )
+ throw IllegalArgumentException( ::rtl::OUString(), i_rContext, 2 );
+
+ // each path must be of length 1, at least
+ for ( sal_Int32 i = 0; i < i_rPaths.getLength(); ++i )
+ {
+ if ( i_rPaths[i].getLength() == 0 )
+ throw IllegalArgumentException( ::rtl::OUString(), i_rContext, 2 );
+
+ // page IDs must be in ascending order
+ sal_Int16 nPreviousPageID = i_rPaths[i][0];
+ for ( sal_Int32 j=1; j<i_rPaths[i].getLength(); ++j )
+ {
+ if ( i_rPaths[i][j] <= nPreviousPageID )
+ {
+ ::rtl::OStringBuffer message;
+ message.append( "Path " );
+ message.append( i );
+ message.append( ": invalid page ID sequence - each page ID must be greater than the previous one." );
+ throw IllegalArgumentException(
+ ::rtl::OStringToOUString( message.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ),
+ i_rContext, 2 );
+ }
+ nPreviousPageID = i_rPaths[i][j];
+ }
+ }
+
+ // if we have one path, that's okay
+ if ( i_rPaths.getLength() == 1 )
+ return;
+
+ // if we have multiple paths, they must start with the same page id
+ const sal_Int16 nFirstPageId = i_rPaths[0][0];
+ for ( sal_Int32 i = 0; i < i_rPaths.getLength(); ++i )
+ {
+ if ( i_rPaths[i][0] != nFirstPageId )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "All paths must start with the same page id." ) ),
+ i_rContext, 2 );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL Wizard::initialize( const Sequence< Any >& i_Arguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bInitialized )
+ throw AlreadyInitializedException( ::rtl::OUString(), *this );
+
+ if ( i_Arguments.getLength() != 2 )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, -1 );
+
+ // the second argument must be a XWizardController, for each constructor
+ m_xController.set( i_Arguments[1], UNO_QUERY );
+ if ( !m_xController.is() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 2 );
+
+ // the first arg is either a single path (short[]), or multiple paths (short[][])
+ Sequence< sal_Int16 > aSinglePath;
+ i_Arguments[0] >>= aSinglePath;
+ Sequence< Sequence< sal_Int16 > > aMultiplePaths;
+ i_Arguments[0] >>= aMultiplePaths;
+
+ if ( !aMultiplePaths.getLength() )
+ {
+ aMultiplePaths.realloc(1);
+ aMultiplePaths[0] = aSinglePath;
+ }
+ lcl_checkPaths( aMultiplePaths, *this );
+ // if we survived this, the paths are valid, and we're done here ...
+ m_aWizardSteps = aMultiplePaths;
+
+ m_bInitialized = true;
+ }
+
+ //--------------------------------------------------------------------
+ Dialog* Wizard::createDialog( Window* i_pParent )
+ {
+ WizardShell* pDialog( new WizardShell( i_pParent, this, m_xController, m_aWizardSteps ) );
+ pDialog->SetSmartHelpId( SmartId( m_sHelpURL ) );
+ pDialog->setTitleBase( m_sTitle );
+ return pDialog;
+ }
+
+ //--------------------------------------------------------------------
+ void Wizard::destroyDialog()
+ {
+ if ( m_pDialog )
+ m_sHelpURL = m_pDialog->GetSmartHelpId().GetStr();
+
+ Wizard_Base::destroyDialog();
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL Wizard::getImplementationName_static() throw(RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.uno.Wizard" ) );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL Wizard::getSupportedServiceNames_static() throw(RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aServices(1);
+ aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.Wizard" ) );
+ return aServices;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL Wizard::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_static();
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL Wizard::getSupportedServiceNames() throw(RuntimeException)
+ {
+ return getSupportedServiceNames_static();
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XPropertySetInfo > SAL_CALL Wizard::getPropertySetInfo() throw(RuntimeException)
+ {
+ return createPropertySetInfo( getInfoHelper() );
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper& SAL_CALL Wizard::getInfoHelper()
+ {
+ return *const_cast< Wizard* >( this )->getArrayHelper();
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper* Wizard::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL Wizard::getHelpURL() throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pDialog )
+ return m_sHelpURL;
+
+ const SmartId aSmartId( m_pDialog->GetSmartHelpId() );
+ return aSmartId.GetStr();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::setHelpURL( const ::rtl::OUString& i_HelpURL ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pDialog )
+ m_sHelpURL = i_HelpURL;
+ else
+ m_pDialog->SetSmartHelpId( SmartId( i_HelpURL ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWindow > SAL_CALL Wizard::getDialogWindow() throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ENSURE_OR_RETURN( m_pDialog, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", NULL );
+ return Reference< XWindow >( m_pDialog->GetComponentInterface(), UNO_QUERY );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::enableButton( ::sal_Int16 i_WizardButton, ::sal_Bool i_Enable ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enableButtons: invalid dialog implementation!" );
+
+ pWizardImpl->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton ), i_Enable );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::setDefaultButton( ::sal_Int16 i_WizardButton ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::setDefaultButton: invalid dialog implementation!" );
+
+ pWizardImpl->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool SAL_CALL Wizard::travelNext( ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelNext: invalid dialog implementation!" );
+
+ return pWizardImpl->travelNext();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool SAL_CALL Wizard::travelPrevious( ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelPrevious: invalid dialog implementation!" );
+
+ return pWizardImpl->travelPrevious();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::enablePage( ::sal_Int16 i_PageID, ::sal_Bool i_Enable ) throw (NoSuchElementException, InvalidStateException, RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enablePage: invalid dialog implementation!" );
+
+ if ( !pWizardImpl->knowsPage( i_PageID ) )
+ throw NoSuchElementException( ::rtl::OUString(), *this );
+
+ if ( i_PageID == pWizardImpl->getCurrentPage() )
+ throw InvalidStateException( ::rtl::OUString(), *this );
+
+ pWizardImpl->enablePage( i_PageID, i_Enable );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::updateTravelUI( ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::updateTravelUI: invalid dialog implementation!" );
+
+ pWizardImpl->updateTravelUI();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Bool SAL_CALL Wizard::advanceTo( ::sal_Int16 i_PageId ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::advanceTo: invalid dialog implementation!" );
+
+ return pWizardImpl->advanceTo( i_PageId );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Bool SAL_CALL Wizard::goBackTo( ::sal_Int16 i_PageId ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::goBackTo: invalid dialog implementation!" );
+
+ return pWizardImpl->goBackTo( i_PageId );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWizardPage > SAL_CALL Wizard::getCurrentPage( ) throw (RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::getCurrentPage: invalid dialog implementation!" );
+
+ return pWizardImpl->getCurrentWizardPage();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::activatePath( ::sal_Int16 i_PathIndex, ::sal_Bool i_Final ) throw (NoSuchElementException, InvalidStateException, RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ( i_PathIndex < 0 ) || ( i_PathIndex >= m_aWizardSteps.getLength() ) )
+ throw NoSuchElementException( ::rtl::OUString(), *this );
+
+ WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog );
+ ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::activatePath: invalid dialog implementation!" );
+
+ pWizardImpl->activatePath( i_PathIndex, i_Final );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL Wizard::setTitle( const ::rtl::OUString& i_Title ) throw (RuntimeException)
+ {
+ // simply disambiguate
+ Wizard_Base::OGenericUnoDialog::setTitle( i_Title );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int16 SAL_CALL Wizard::execute( ) throw (RuntimeException)
+ {
+ return Wizard_Base::OGenericUnoDialog::execute();
+ }
+
+//......................................................................................................................
+} } // namespace svt::uno
+//......................................................................................................................
diff --git a/svtools/source/uno/wizard/wizardpagecontroller.cxx b/svtools/source/uno/wizard/wizardpagecontroller.cxx
new file mode 100644
index 000000000000..d6f7029b477c
--- /dev/null
+++ b/svtools/source/uno/wizard/wizardpagecontroller.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.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "wizardpagecontroller.hxx"
+#include "wizardshell.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+/** === end UNO includes === **/
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace svt { namespace uno
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ 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::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::ui::dialogs::XWizardController;
+ using ::com::sun::star::awt::XWindow;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::awt::XControl;
+ /** === end UNO using === **/
+ using namespace ::com::sun::star;
+
+ //==================================================================================================================
+ //= WizardPageController
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ WizardPageController::WizardPageController( WizardShell& i_rParent, const Reference< XWizardController >& i_rController,
+ const sal_Int16 i_nPageId )
+ :m_xController( i_rController )
+ ,m_xWizardPage()
+ ,m_nPageId( i_nPageId )
+ {
+ ENSURE_OR_THROW( m_xController.is(), "no controller" );
+ try
+ {
+ m_xWizardPage.set( m_xController->createPage(
+ Reference< XWindow >( i_rParent.GetComponentInterface( TRUE ), UNO_QUERY_THROW ),
+ m_nPageId
+ ), UNO_SET_THROW );
+
+ Reference< XWindow > xPageWindow( m_xWizardPage->getWindow(), UNO_SET_THROW );
+ xPageWindow->setVisible( sal_True );
+
+ TabPage* pTabPage( getTabPage() );
+ if ( pTabPage )
+ pTabPage->SetStyle( pTabPage->GetStyle() | WB_CHILDDLGCTRL | WB_DIALOGCONTROL );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ WizardPageController::~WizardPageController()
+ {
+ try
+ {
+ if ( m_xWizardPage.is() )
+ m_xWizardPage->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ TabPage* WizardPageController::getTabPage() const
+ {
+ ENSURE_OR_RETURN( m_xWizardPage.is(), "WizardPageController::getTabPage: no external wizard page!", NULL );
+ try
+ {
+ Reference< XWindow > xPageWindow( m_xWizardPage->getWindow(), UNO_SET_THROW );
+ Window* pPageWindow = VCLUnoHelper::GetWindow( xPageWindow );
+ if ( pPageWindow == NULL )
+ {
+ // windows created via the XContainerWindowProvider might be controls, not real windows, so resolve
+ // that one indirection
+ const Reference< XControl > xPageControl( m_xWizardPage->getWindow(), UNO_QUERY_THROW );
+ xPageWindow.set( xPageControl->getPeer(), UNO_QUERY_THROW );
+ pPageWindow = VCLUnoHelper::GetWindow( xPageWindow );
+ }
+
+ OSL_ENSURE( pPageWindow != NULL, "WizardPageController::getTabPage: unable to find the Window implementation for the page's window!" );
+ return dynamic_cast< TabPage* >( pPageWindow );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return NULL;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void WizardPageController::initializePage()
+ {
+ if ( !m_xWizardPage.is() )
+ return;
+
+ try
+ {
+ m_xWizardPage->activatePage();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool WizardPageController::commitPage( WizardTypes::CommitPageReason i_eReason )
+ {
+ if ( !m_xWizardPage.is() )
+ return sal_True;
+
+ try
+ {
+ return m_xWizardPage->commitPage( WizardShell::convertCommitReasonToTravelType( i_eReason ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ bool WizardPageController::canAdvance() const
+ {
+ if ( !m_xWizardPage.is() )
+ return true;
+
+ try
+ {
+ return m_xWizardPage->canAdvance();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return true;
+ }
+
+//......................................................................................................................
+} } // namespace svt::uno
+//......................................................................................................................
diff --git a/svtools/source/uno/wizard/wizardpagecontroller.hxx b/svtools/source/uno/wizard/wizardpagecontroller.hxx
new file mode 100644
index 000000000000..9de04d2f0dd4
--- /dev/null
+++ b/svtools/source/uno/wizard/wizardpagecontroller.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 SVT_UNOWIZ_WIZARDPAGECONTROLLER_HXX
+#define SVT_UNOWIZ_WIZARDPAGECONTROLLER_HXX
+
+#include "svtools/wizardmachine.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/dialogs/XWizardController.hpp>
+/** === end UNO includes === **/
+
+//......................................................................................................................
+namespace svt { namespace uno
+{
+//......................................................................................................................
+
+ class WizardShell;
+
+ //==================================================================================================================
+ //= WizardPageController
+ //==================================================================================================================
+ class WizardPageController : public IWizardPageController
+ {
+ public:
+ WizardPageController(
+ WizardShell& i_rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController >& i_rController,
+ const sal_Int16 i_nPageId
+ );
+ ~WizardPageController();
+
+ // IWizardPageController overridables
+ virtual void initializePage();
+ virtual sal_Bool commitPage( WizardTypes::CommitPageReason _eReason );
+ virtual bool canAdvance() const;
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage >&
+ getWizardPage() const { return m_xWizardPage; }
+ TabPage* getTabPage() const;
+
+ private:
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController > m_xController;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage > m_xWizardPage;
+ const sal_Int16 m_nPageId;
+ };
+
+//......................................................................................................................
+} } // namespace svt::uno
+//......................................................................................................................
+
+#endif // SVT_UNOWIZ_WIZARDPAGECONTROLLER_HXX
diff --git a/svtools/source/uno/wizard/wizardshell.cxx b/svtools/source/uno/wizard/wizardshell.cxx
new file mode 100644
index 000000000000..7737b214ac1f
--- /dev/null
+++ b/svtools/source/uno/wizard/wizardshell.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "wizardshell.hxx"
+#include "wizardpagecontroller.hxx"
+
+#include <tools/diagnose_ex.h>
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/dialogs/WizardTravelType.hpp>
+/** === end UNO includes === **/
+
+#include <vcl/msgbox.hxx>
+
+//......................................................................................................................
+namespace svt { namespace uno
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ 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::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::ui::dialogs::XWizardController;
+ using ::com::sun::star::ui::dialogs::XWizard;
+ using ::com::sun::star::ui::dialogs::XWizardPage;
+ /** === end UNO using === **/
+ namespace WizardTravelType = ::com::sun::star::ui::dialogs::WizardTravelType;
+
+ //==================================================================================================================
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ sal_Int16 lcl_determineFirstPageID( const Sequence< Sequence< sal_Int16 > >& i_rPaths )
+ {
+ ENSURE_OR_THROW( ( i_rPaths.getLength() > 0 ) && ( i_rPaths[0].getLength() > 0 ), "illegal paths" );
+ return i_rPaths[0][0];
+ }
+ }
+
+ //==================================================================================================================
+ //= WizardShell
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ WizardShell::WizardShell( Window* i_pParent, const Reference< XWizard >& i_rWizard, const Reference< XWizardController >& i_rController,
+ const Sequence< Sequence< sal_Int16 > >& i_rPaths )
+ :WizardShell_Base( i_pParent, WB_MOVEABLE | WB_CLOSEABLE )
+ ,m_xWizard( i_rWizard )
+ ,m_xController( i_rController )
+ ,m_nFirstPageID( lcl_determineFirstPageID( i_rPaths ) )
+ {
+ ENSURE_OR_THROW( m_xWizard.is() && m_xController.is(), "invalid wizard/controller" );
+
+ // declare the paths
+ for ( sal_Int32 i=0; i<i_rPaths.getLength(); ++i )
+ {
+ const Sequence< sal_Int16 >& rPath( i_rPaths[i] );
+ WizardPath aPath( rPath.getLength() );
+ for ( sal_Int32 j=0; j<rPath.getLength(); ++j )
+ aPath[j] = impl_pageIdToState( rPath[j] );
+ declarePath( i, aPath );
+ }
+
+ // create the first page, to know the page size
+ TabPage* pStartPage = GetOrCreatePage( impl_pageIdToState( i_rPaths[0][0] ) );
+ SetPageSizePixel( pStartPage->GetSizePixel() );
+
+ // some defaults
+ ShowButtonFixedLine( true );
+ SetRoadmapInteractive( true );
+ enableAutomaticNextButtonState();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ WizardShell::~WizardShell()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ short WizardShell::Execute()
+ {
+ ActivatePage();
+ return WizardShell_Base::Execute();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Int16 WizardShell::convertCommitReasonToTravelType( const CommitPageReason i_eReason )
+ {
+ switch ( i_eReason )
+ {
+ case WizardTypes::eTravelForward:
+ return WizardTravelType::FORWARD;
+
+ case WizardTypes::eTravelBackward:
+ return WizardTravelType::BACKWARD;
+
+ case WizardTypes::eFinish:
+ return WizardTravelType::FINISH;
+
+ default:
+ break;
+ }
+ OSL_ENSURE( false, "WizardShell::convertCommitReasonToTravelType: unsupported CommitPageReason!" );
+ return WizardTravelType::FINISH;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void WizardShell::enterState( WizardState i_nState )
+ {
+ WizardShell_Base::enterState( i_nState );
+
+ if ( !m_xController.is() )
+ return;
+
+ try
+ {
+ m_xController->onActivatePage( impl_stateToPageId( i_nState ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool WizardShell::leaveState( WizardState i_nState )
+ {
+ if ( !WizardShell_Base::leaveState( i_nState ) )
+ return sal_False;
+
+ if ( !m_xController.is() )
+ return sal_True;
+
+ try
+ {
+ m_xController->onDeactivatePage( impl_stateToPageId( i_nState ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ PWizardPageController WizardShell::impl_getController( TabPage* i_pPage ) const
+ {
+ Page2ControllerMap::const_iterator pos = m_aPageControllers.find( i_pPage );
+ ENSURE_OR_RETURN( pos != m_aPageControllers.end(), "WizardShell::impl_getController: no controller for this page!", PWizardPageController() );
+ return pos->second;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWizardPage > WizardShell::getCurrentWizardPage() const
+ {
+ const WizardState eState = getCurrentState();
+
+ PWizardPageController pController( impl_getController( GetPage( eState ) ) );
+ ENSURE_OR_RETURN( pController, "WizardShell::getCurrentWizardPage: invalid page/controller!", NULL );
+
+ return pController->getWizardPage();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void WizardShell::enablePage( const sal_Int16 i_nPageID, const sal_Bool i_bEnable )
+ {
+ enableState( impl_pageIdToState( i_nPageID ), i_bEnable );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ TabPage* WizardShell::createPage( WizardState i_nState )
+ {
+ ENSURE_OR_RETURN( m_xController.is(), "WizardShell::createPage: no WizardController!", NULL );
+
+ ::boost::shared_ptr< WizardPageController > pController( new WizardPageController( *this, m_xController, impl_stateToPageId( i_nState ) ) );
+ TabPage* pPage = pController->getTabPage();
+ OSL_ENSURE( pPage != NULL, "WizardShell::createPage: illegal tab page!" );
+ if ( pPage == NULL )
+ {
+ // fallback for ill-behaved clients: empty page
+ pPage = new TabPage( this, 0 );
+ pPage->SetSizePixel( LogicToPixel( Size( 280, 185 ), MAP_APPFONT ) );
+ }
+
+ m_aPageControllers[ pPage ] = pController;
+ return pPage;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IWizardPageController* WizardShell::getPageController( TabPage* i_pCurrentPage ) const
+ {
+ return impl_getController( i_pCurrentPage ).get();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ String WizardShell::getStateDisplayName( WizardState i_nState ) const
+ {
+ try
+ {
+ if ( m_xController.is() )
+ return m_xController->getPageTitle( impl_stateToPageId( i_nState ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ // fallback for ill-behaved clients: the numeric state
+ return String::CreateFromInt32( i_nState );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ bool WizardShell::canAdvance() const
+ {
+ try
+ {
+ if ( m_xController.is() && !m_xController->canAdvance() )
+ return false;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return WizardShell_Base::canAdvance();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool WizardShell::onFinish()
+ {
+ try
+ {
+ if ( m_xController.is() && !m_xController->confirmFinish() )
+ return sal_False;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return WizardShell_Base::onFinish();
+ }
+
+//......................................................................................................................
+} } // namespace svt::uno
+//......................................................................................................................
diff --git a/svtools/source/uno/wizard/wizardshell.hxx b/svtools/source/uno/wizard/wizardshell.hxx
new file mode 100644
index 000000000000..338b4f38dc4a
--- /dev/null
+++ b/svtools/source/uno/wizard/wizardshell.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 SVT_UNO_WIZARD_SHELL
+#define SVT_UNO_WIZARD_SHELL
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/dialogs/XWizardController.hpp>
+#include <com/sun/star/ui/dialogs/XWizard.hpp>
+/** === end UNO includes === **/
+
+#include <svtools/roadmapwizard.hxx>
+
+#include <boost/shared_ptr.hpp>
+#include <map>
+
+//......................................................................................................................
+namespace svt { namespace uno
+{
+//......................................................................................................................
+
+ class WizardPageController;
+ typedef ::boost::shared_ptr< WizardPageController > PWizardPageController;
+
+ //==================================================================================================================
+ //= WizardShell
+ //==================================================================================================================
+ typedef ::svt::RoadmapWizard WizardShell_Base;
+ class WizardShell : public WizardShell_Base
+ {
+ public:
+ WizardShell(
+ Window* _pParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizard >& i_rWizard,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController >& i_rController,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int16 > >& i_rPaths
+ );
+ virtual ~WizardShell();
+
+ // Dialog overridables
+ virtual short Execute();
+
+ // OWizardMachine overridables
+ virtual TabPage* createPage( WizardState i_nState );
+ virtual void enterState( WizardState i_nState );
+ virtual sal_Bool leaveState( WizardState i_nState );
+ virtual String getStateDisplayName( WizardState i_nState ) const;
+ virtual bool canAdvance() const;
+ virtual sal_Bool onFinish();
+ virtual IWizardPageController*
+ getPageController( TabPage* _pCurrentPage ) const;
+
+ // attribute access
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizard >&
+ getWizard() const { return m_xWizard; }
+
+ static sal_Int16 convertCommitReasonToTravelType( const CommitPageReason i_eReason );
+
+ // operations
+ sal_Bool advanceTo( const sal_Int16 i_nPageId )
+ {
+ return skipUntil( impl_pageIdToState( i_nPageId ) );
+ }
+ sal_Bool goBackTo( const sal_Int16 i_nPageId )
+ {
+ return skipBackwardUntil( impl_pageIdToState( i_nPageId ) );
+ }
+ sal_Bool travelNext() { return WizardShell_Base::travelNext(); }
+ sal_Bool travelPrevious() { return WizardShell_Base::travelPrevious(); }
+
+ void activatePath( const sal_Int16 i_nPathID, const sal_Bool i_bFinal )
+ {
+ WizardShell_Base::activatePath( PathId( i_nPathID ), i_bFinal );
+ }
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage >
+ getCurrentWizardPage() const;
+
+ sal_Int16 getCurrentPage() const
+ {
+ return impl_stateToPageId( getCurrentState() );
+ }
+
+ void enablePage( const sal_Int16 i_PageID, const sal_Bool i_Enable );
+
+ bool knowsPage( const sal_Int16 i_nPageID ) const
+ {
+ return knowsState( impl_pageIdToState( i_nPageID ) );
+ }
+
+ private:
+ sal_Int16 impl_stateToPageId( const WizardTypes::WizardState i_nState ) const
+ {
+ return static_cast< sal_Int16 >( i_nState + m_nFirstPageID );
+ }
+
+ WizardState impl_pageIdToState( const sal_Int16 i_nPageId ) const
+ {
+ return static_cast< WizardState >( i_nPageId - m_nFirstPageID );
+ }
+
+ PWizardPageController impl_getController( TabPage* i_pPage ) const;
+
+ // prevent outside access to some base class members
+ using WizardShell_Base::skip;
+ using WizardShell_Base::skipUntil;
+ using WizardShell_Base::skipBackwardUntil;
+ using WizardShell_Base::getCurrentState;
+ using WizardShell_Base::activatePath;
+
+ private:
+ typedef ::std::map< TabPage*, PWizardPageController > Page2ControllerMap;
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizard > m_xWizard;
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController > m_xController;
+ const sal_Int16 m_nFirstPageID;
+ Page2ControllerMap m_aPageControllers;
+ };
+
+//......................................................................................................................
+} } // namespace svt::uno
+//......................................................................................................................
+
+#endif // SVT_UNO_WIZARD_SHELL
diff --git a/svtools/source/urlobj/inetimg.cxx b/svtools/source/urlobj/inetimg.cxx
new file mode 100644
index 000000000000..7e81f17209f2
--- /dev/null
+++ b/svtools/source/urlobj/inetimg.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_svtools.hxx"
+#include <tools/debug.hxx>
+#include <sot/formats.hxx>
+#include <tools/stream.hxx>
+
+#ifndef GCC
+#endif
+
+#include "inetimg.hxx"
+
+#define TOKEN_SEPARATOR '\001'
+
+sal_Bool INetImage::Write( SvStream& rOStm, ULONG nFormat ) const
+{
+ sal_Bool bRet = sal_False;
+ switch( nFormat )
+ {
+ case SOT_FORMATSTR_ID_INET_IMAGE:
+ {
+ String sString;
+ (sString += aImageURL ) += TOKEN_SEPARATOR;
+ (sString += aTargetURL ) += TOKEN_SEPARATOR;
+ (sString += aTargetFrame ) += TOKEN_SEPARATOR;
+ (sString += aAlternateText ) += TOKEN_SEPARATOR;
+ sString += String::CreateFromInt32( aSizePixel.Width() );
+ sString += TOKEN_SEPARATOR;
+ sString += String::CreateFromInt32( aSizePixel.Height() );
+ ByteString sOut( sString, RTL_TEXTENCODING_UTF8 );
+
+ rOStm.Write( sOut.GetBuffer(), sOut.Len() );
+ static const sal_Char aEndChar[2] = { 0 };
+ rOStm.Write( aEndChar, sizeof( aEndChar ));
+ bRet = 0 == rOStm.GetError();
+ }
+ break;
+
+ case SOT_FORMATSTR_ID_NETSCAPE_IMAGE:
+ break;
+ }
+ return bRet;
+}
+
+sal_Bool INetImage::Read( SvStream& rIStm, ULONG nFormat )
+{
+ sal_Bool bRet = sal_False;
+ switch( nFormat )
+ {
+ case SOT_FORMATSTR_ID_INET_IMAGE:
+ {
+ String sINetImg;
+ rIStm.ReadCString( sINetImg, RTL_TEXTENCODING_UTF8 );
+ xub_StrLen nStart = 0;
+ aImageURL = sINetImg.GetToken( 0, TOKEN_SEPARATOR, nStart );
+ aTargetURL = sINetImg.GetToken( 0, TOKEN_SEPARATOR, nStart );
+ aTargetFrame = sINetImg.GetToken( 0, TOKEN_SEPARATOR, nStart );
+ aAlternateText = sINetImg.GetToken( 0, TOKEN_SEPARATOR, nStart );
+ aSizePixel.Width() = sINetImg.GetToken( 0, TOKEN_SEPARATOR,
+ nStart ).ToInt32();
+ aSizePixel.Height() = sINetImg.GetToken( 0, TOKEN_SEPARATOR,
+ nStart ).ToInt32();
+ bRet = 0 != sINetImg.Len();
+ }
+ break;
+
+ case SOT_FORMATSTR_ID_NETSCAPE_IMAGE:
+ {
+/*
+ --> structure size MUST - alignment of 4!
+ int iSize; // size of all data, including variable length strings
+ BOOL bIsMap; // For server side maps
+ INT32 iWidth; // Fixed size data correspond to fields in LO_ImageDataStruct
+ INT32 iHeight; // and EDT_ImageData
+ INT32 iHSpace;
+ INT32 iVSpace;
+ INT32 iBorder;
+ int iLowResOffset; // Offsets into string_data. If 0, string is NULL (not used)
+ int iAltOffset; // (alternate text?)
+ int iAnchorOffset; // HREF in image
+ int iExtraHTML_Offset; // Extra HTML (stored in CImageElement)
+ sal_Char pImageURL[1]; // Append all variable-length strings starting here
+*/
+ rtl_TextEncoding eSysCSet = gsl_getSystemTextEncoding();
+ sal_Int32 nVal, nAnchorOffset, nAltOffset, nFilePos;
+ ByteString sData;
+
+ nFilePos = rIStm.Tell();
+ // skip over iSize (int), bIsMao ( BOOL ) alignment of 4 !!!!
+ rIStm.SeekRel( 8 );
+ rIStm >> nVal; aSizePixel.Width() = nVal;
+ rIStm >> nVal; aSizePixel.Height() = nVal;
+ // skip over iHSpace, iVSpace, iBorder, iLowResOffset
+ rIStm.SeekRel( 3 * sizeof( INT32 ) + sizeof( int ) );
+ rIStm >> nAltOffset;
+ rIStm >> nAnchorOffset;
+ // skip over iExtraHTML_Offset
+ rIStm.SeekRel( sizeof( int ) );
+
+ rIStm.ReadCString( aImageURL, eSysCSet );
+ if( nAltOffset )
+ {
+ rIStm.Seek( nFilePos + nAltOffset );
+ rIStm.ReadCString( aAlternateText, eSysCSet );
+ }
+ else if( aAlternateText.Len() )
+ aAlternateText.Erase();
+
+ if( nAnchorOffset )
+ {
+ rIStm.Seek( nFilePos + nAnchorOffset );
+ rIStm.ReadCString( aTargetURL, eSysCSet );
+ }
+ else if( aTargetURL.Len() )
+ aTargetURL.Erase();
+
+ bRet = 0 == rIStm.GetError();
+ }
+ break;
+ }
+ return bRet;
+}
+
diff --git a/svtools/source/urlobj/makefile.mk b/svtools/source/urlobj/makefile.mk
new file mode 100644
index 000000000000..c75e592ea10b
--- /dev/null
+++ b/svtools/source/urlobj/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svtools
+TARGET=urlobj
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/svt.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/inetimg.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+